Не знаю, понятно ли название, но у меня есть вот такое:

    public class Product {
        public Integer getId() {...}
        public String getName() {...}
    }

    public <T,V> static void method(Function<T, V> f, V value) {...}

И я хочу стать ошибкой компиляции, когда:

    method(Product::getId, "some String"); // id is not String
    method(Product::getName, 123);         // name is not Integer

Но компилятор интерпретирует V как:

java Serializable & Comparable<? extends Serializable & Comparable<?>>

Он компилируется, но в зависимости от того, как реализован «метод», вы получаете исключение во время выполнения, или он просто работает неправильно.

Как я могу указать компилятору соответствовать желаемому типу данных? и я не хочу писать «метод» для каждого возможного типа V.

Благодарность!

1
César Mora 26 Фев 2021 в 12:22

1 ответ

Лучший ответ

Вы можете принудительно применить дженерики, разделив их на два вызова методов, для этого вам понадобится новый класс:

public class Value<T, V> {
    private final Function<T, V> f;
    
    public Value(Function<T, V> f) {
        this.f= f;
    }

    public void with(V value) {
        // move your code from method() into here
    }
}

А затем измените method() на что-то вроде этого:

public static <T, V> Value<T, V> method(Function<T, V> f) {
    return new Value<>(f);
}

Тогда вы можете использовать это так:

method(Product::getId).with("123");   // compiler error
method(Product::getName).with(123);   // compiler error
method(Product::getId).with(123);     // no error
method(Product::getName).with("123"); // no error
1
Lino 26 Фев 2021 в 09:49