ну тут T
может быть что угодно. Это синоним типа, но может быть в основном любым типом.
Таким образом, когда у вас есть compareValues(Supplier<T> supplier, T value)
, это означает, что поставщик может дать мне любой тип и значение, которое может быть любого типа. Так что это не дает ошибки компиляции и даже работает. В вашем методе вы можете сделать:
private <T> void compareValues(Supplier<T> supplier, T value) {
value=supplier.get(); //It is still valid even if you give different types
System.out.println((supplier.get() == value) +" - "+ value);
}
Что касается другого метода, он отличается, потому что вы говорите «Дайте мне потребителя, который принимает любой тип», но вы даете ему потребителя, который принимает только String.
Так вот
private void setString(String s) {
}
не будет работать, но
private <T> void setString(T s) {
}
будет работать просто отлично.
Это похоже на то, что если у вас есть переменная типа Object, вы можете назначить ей String, но не наоборот, в более странной ситуации. Поставщик String - это <T>
поставщик, но потребитель String не является <T>
.
См. Эти два метода:
private <T> void setString(T a) {
T var=a;
T var2="Asdf"; //This doesn't compile! cannot convert String to T
}
private <String> void setString2(String a) {
String var=a;
String var2="asd";
}
Вы хотите потребителя типа T, который является первым методом. Но вместо этого вы пытаетесь дать потребителю тип String, который не может работать, потому что он потребляет только строки, и вам нужен метод, который может потреблять все