This question already has answers here:
What is PECS (Producer Extends Consumer Super)?
(16 answers)
Closed 1 year ago.
I am trying to assign a method reference to the following generic interface.
interface Interface1<R> {
public R doIt();
}
interface Interface2<P, R> {
public R doIt(P x);
}
public class Test {
public static Long foo(Long x) {
return x;
}
public static Long bar() {
Long x = 1L;
return x;
}
public static void main(String[] args) {
Interface1<? extends Number> fun1 = Test::bar; //works
Interface2<? extends Number, ? extends Number> fun2 = Test::foo; // does not work
}
}
The second assignment gives me
incompatible types: Number cannot be converted to Long
What am I missing here!
You cant do this because then you can do fun2.doIt((Number)0.5);
The idea is that you need something like
Interface2<? super Number, ? extends Number>
Related
This question already has answers here:
How do I make the method return type generic?
(19 answers)
Closed 2 years ago.
I need a non-generic class containing a method with two generic parameters . In this method my goal is to compare two generic parameters and return the greater value. How can I do it?
public class generic <T extends Comparable<T>>{
public T Max( T pv, T sv){
if(pv.compareTo(sv)>=0){
return pv;
}else {
return sv;
}
}
public static void main(String[]args){
generic g = new generic();
System.out.println(g.Max( 2, 7));
}
}
Just move it to the method declaration
public class Generic {
public <T extends Comparable<T>> T max( T pv, T sv){
if (pv.compareTo(sv) >= 0) {
return pv;
} else {
return sv;
}
}
public static void main(String[]args){
Generic g = new Generic();
System.out.println(g.max(2, 7));
}
}
Also the method could be static, because it does not rely on any state. It would make calling it easier
System.out.println(max(2, 7));
This question already has answers here:
String gets assigned to a List without a compilation error [duplicate]
(1 answer)
Why can this generic method with a bound return any type?
(1 answer)
Generic return type upper bound - interface vs. class - surprisingly valid code
(2 answers)
Closed 5 years ago.
Why does the below snippet compile ? OtherInterface does not extends Concrete so I would have bet a kidney that this wouldn't compile. But it does.
public class Test {
public static interface SomeInterface {}
public static interface OtherInterface{}
public static class Concrete implements SomeInterface {
public <T extends Concrete> T getConcrete() {
return null;
}
}
public static void doStuff() {
Concrete c = new Concrete();
OtherInterface iCompile = c.getConcrete();
}
}
On the other hand, the next snippet does not compile, which is what I expect.
public class Test {
public static interface SomeInterface {}
public static class UnrelatedClass{}
public static class Concrete implements SomeInterface {
public <T extends Concrete> T getConcrete() {
return null;
}
}
public static void doStuff() {
Concrete c = new Concrete();
UnrelatedClass iCompile = c.getConcrete();
}
}
The difference is here:
public static interface OtherInterface{} ...
OtherInterface iCompile = c.getConcrete();
vs.
public static class UnrelatedClass{} ...
UnrelatedClass iCompile = c.getConcrete();
Meaning: in the first case, you call the method to return an instance of some interface. Interfaces can be any class.
In the second example, you instruct that returned type is of be a specific class! A class which is known, and that does not implement that other interface!
And the error message:
reason: no unique maximal instance exists for type variable T with upper bounds UnrelatedClass,Concrete
is pretty specific here.
In other words: the compiler factors in the left hand side of that assignment - to determine the valid types. And UnrelatedClass can never be a Concrete - because the class UnrelatedClass does not extend Concrete!
Whereas something that is SomeInterface can as well implement OtherInterface.
This question already has answers here:
What is a raw type and why shouldn't we use it?
(16 answers)
Closed 7 years ago.
I have an interface defining the following method:
public <C extends RTSpan<V>, V extends Object> void onEffectSelected(Effect<V, C> effect, V value);
I'm calling this like this:
mListener.onEffectSelected(Effects.BOLD, true);
with Effects.BOLD being an Effect<Boolean,RTSpan<Boolean>> object.
I was under the impression that the compiler should make sure that the two Vs in the onEffectSelected are of the same type?
However if I write:
mListener.onEffectSelected(Effects.BOLD, 1);
It compiles without issues and of course throws a runtime exception.
What's wrong here? How can I make sure that the second parameter has an identical type to the one used in the first parameter?
EDIT
public class GenericsTest {
interface RTSpan<V> {}
static class BoldSpan implements RTSpan<Boolean> {}
static class Effect<V extends Object, C extends RTSpan<V>> {}
static class BoldEffect extends Effect<Boolean, BoldSpan> {}
interface TheListener {
public <C extends RTSpan<V>, V extends Object> void onEffectSelected(Effect<V, C> effect, V value);
}
static class Effects {
public static final Effect BOLD = new BoldEffect();
}
public static void main(String[] args) {
TheListener listener = new TheListener() {
#Override
public <C extends RTSpan<V>, V> void onEffectSelected(Effect<V, C> effect, V value) {}
};
listener.onEffectSelected(Effects.BOLD, Boolean.TRUE);
listener.onEffectSelected(Effects.BOLD, 1); // this compiles
listener.onEffectSelected(new BoldEffect(), 1); // this doesn't compile
}
}
The issue seems to be Effects.BOLD. If I replace it with a new BoldEffect() the compiler complains. Does anyone know why the static instantiation throws off the compiler?
public static final Effect BOLD = new BoldEffect();
This use of raw types essentially turns off type checking entirely anywhere BOLD is used. Turn it into Effect<Boolean, BoldSpan> and type checking will work properly.
This question already has answers here:
Java Generics - How do I call a generic map with a successor object
(3 answers)
Closed 8 years ago.
Is there a way to send a list/map of a concrete type to a method that recieves a list/map of interfaces?
e.g.
(Toyota extends Car and Car implements ICar)
I want to call
private static void doSomething(Map<String, ICar> cars) {}
Using
Map<String, Toyota> toyotas = new HashMap<>();
doSomething0(toyotas);
You can use type bounds :
private static void doSomething(Map<String, ? extends ICar> cars) {}
Example :
public static void doSomething (Map<String,? extends Number> numMap)
{
for (Number n : numMap.values ())
System.out.println (n);
}
public static void main (String[] args)
{
Map<String,Integer> intMap = new HashMap<String, Integer> ();
intMap.put("two",2);
intMap.put("three",3);
doSomething (intMap);
}
Change your declaration to:
private static void doSomething(Map<String, ? extends ICar> cars) {}
This means acept everything that extends ICar.
This question already has answers here:
What is a raw type and why shouldn't we use it?
(16 answers)
Closed 8 years ago.
Is there any differences between those two class declarations
1:
class MyClass <T extends Number & Comparable>
2:
class MyClass <T extends Number & Comparable<T>>
I think that there are differences. But I cannot find an example which would show differences because I don't understand it exact.
Can you show me this example?
There is a difference. The first one is using raw types, and thus, is less type-safe. For example:
This works, but should not work
class MyClass<T extends Number & Comparable>
{
void use(T t)
{
String s = null;
t.compareTo(s); // Works, but will cause a runtime error
}
}
Whereas this does not work (because it should not work)
class MyClass<T extends Number & Comparable<T>>
{
void use(T t)
{
String s = null;
t.compareTo(s); // Compile-time error
}
}
EDIT: Full code, as requested:
class MyClass<T extends Number & Comparable>
{
void use(T t)
{
String s = "Laziness";
t.compareTo(s); // Works, but will cause a runtime error
}
}
public class MyClassTest
{
public static void main(String[] args)
{
MyClass<Integer> m = new MyClass<Integer>();
Integer integer = new Integer(42);
m.use(integer);
}
}