Suppose I have the following structure:
public interface A {
}
public interface B {
}
public interface B1 extends B {
}
public interface B2 extends B {
}
public class C implements A, B1 {
private final String s;
public C(final String s) {
this.s = s;
}
}
public class D implements A, B2 {
private final Exception e;
public D(final Exception e) {
this.e = e;
}
}
public class SomeClass<T> {
private final T t;
private final Exception e;
public SomeClass(final T t, final Exception e) {
this.t = t;
this.e = e;
}
public <U extends B> U transform(final java.util.function.Function<T, ? extends U> mapper1, final java.util.function.Function<Exception, ? extends U> mapper2) {
return t == null ? mapper2.apply(e) : mapper1.apply(t);
}
}
When now we do the following in another class:
public class AnotherClass {
public static void main(final String[] args) {
SomeClass<String> someClass = new SomeClass<>("Hello World!", null);
// this line is what is bothering me
A mappedResult = someClass.transform(C::new, D::new);
}
}
The code compiles without any problems. Why does the code compile? How is it possible that the type of 'mappedResult' can be A, even though the generic U in the method is declared to be a subtype of B?
U
is inferred to beB
&A
both, so you can assign the result to anA
– Attainture.<A & B>transform(...)
. – Olvanvar obj = new Object() { int x() {return 0;} }; System.out.println(obj.x());
and it should work because the compiler infers that the type ofobj
is not justObject
, it also contains that method – Attainture