简体   繁体   中英

Composing generic types in Java

I get a type-mismatch error in a situation I wouldn't expect.

public interface I {}

public abstract class C {}

public class A extends C implements I {}

public class B extends C implements I {}

public class Foo {

    public <T extends C & I> T getComposition(String selector) {
        switch (selector) {
            case "a": return new A(); // type-mismatch!
            case "b": return new B(); // type-mismatch!
        }
    }

}

Why A , which is both C and I , couldn't return as T ?

The notation <T extends C & I> means that T is a type-parameter . This means that when someone calls the function, they have to specify this type. The only restriction is that the type extends C and I . A is one such type, but I could create a new class that also extends C and I . Like this example:

class B extends C implements I {}

Foo foo = new Foo();
B b = foo.<B>getComposition();

If your example had compiled, this would result in an exception because A is not the same type as B .

If you really want to just return an A , you need to remove the generic parameter and make the return type A directly. Like this:

public class Foo {
    public A getComposition() {
        return new A();
    }
}

You are correct but just a part. A or B are T, that is absolutely correct. But T itself is not A or B at all. Eg I have another class called D and D extends A. So, D is T also. If you say T is A, you also mean D is A. That is not correct at all since D is a subtype of A.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM