Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java bounded parameters in generic methods

I have tested some things with bounded parameters in generic methods and I discovered some strange behavior.
It would be great If anybody could explain the two errors in the following code snippet.

Imagine there are two classes Class1 and Class2 both extend from a BaseClass. Class2 implements an Interface.

In Class1, I have a method which returns an instance of Class2 in the following way:

public class Class2 extends BaseClass implements Interface {

    @Override
    public void method() {
        System.out.println("test"); //$NON-NLS-1$
    }
}

public class Class1 extends BaseClass {

    public <T extends BaseClass & Interface> T getTwo() {
        return new Class2();
        // Error: Type mismatch: cannot convert from Class2 to T
    }

    public static void main(String[] args) {
        Interface two = new Class1().getTwo();
        // Error: Bound mismatch: The generic method getTwo() of type Class1 is
        // not applicable for the arguments (). The inferred type Interface is
        // not a valid substitute for the bounded parameter <T extends BaseClass
        // & Interface>
        System.out.println(two);
    }
}
like image 572
Marco Avatar asked Dec 18 '11 20:12

Marco


People also ask

What are bounded type parameters in generic?

Whenever you want to restrict the type parameter to subtypes of a particular class you can use the bounded type parameter. If you just specify a type (class) as bounded parameter, only sub types of that particular class are accepted by the current generic class. These are known as bounded-types in generics in Java.

What is bounded and unbounded wildcards in generics Java?

Bounded and unbounded wildcards in Generics are two types of wildcards available on Java. Any Type can be bounded either upper or lower of the class hierarchy in Generics by using bounded wildcards.

Can a generic class have multiple parameters?

A Generic class can have muliple type parameters.

Can a parameterized type have several bounds?

A type parameter can have multiple bounds.


2 Answers

The first compilation error occurs because type parameters declared by methods are specified by the caller, not the method implementation. That is, given

class Class3 extends BaseClass implements Interface { ... }

a caller may write

Class3 c3 = new Class1().<Class3>getTwo();

, but the method implementation returns a Class2, which isn't a subtype of T = Class3.

The second compilation error occurs because type parameters that aren't explicitly specified by the caller are inferred from method arguments and the type of the variable the method return value is assigned to. This inference fails here. The usual workaround, recommended by the Java Language Specification, is to specify the type parameters explicitly in such cases (type inference is intended as a convenience for simple cases; it doesn't aim to cover all cases).

As for how to properly declare this type parameter, I'd need to know what you are trying to accomplish with these declarations.

like image 68
meriton Avatar answered Oct 19 '22 15:10

meriton


Why use generics for the method getTwo, when you know it's a Class2? Simply do this:

public Class2 getTwo() {
    return new Class2();
}

If you're overriding a method public <T extends BaseClass & Interface> T getTwo(), the compiler will allow you to declare your impl as public Class2 getTwo() when your T for your impl is Class2

like image 45
Bohemian Avatar answered Oct 19 '22 16:10

Bohemian