Programmer Trond
Programmer Trond

Reputation: 313

Code compiles while breaking generics constraint on return type

String does not implement AutoCloseable, so how can we assign the result of my method "get" to a String? Does anyone know why this compiles under Java 8 and 11? If I swap AutoCloseable with a non-interface class like Integer, I get the compiler error I expected.

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

public class FooTest {

    @Test
    public void myTest() {
        final String result = new Foo().get(0);
    }
}

class Foo {

    List<AutoCloseable> list = new ArrayList<>();

    public <A extends AutoCloseable> A get(int name) {
        return (A) list.get(name);
    }
}

Upvotes: 4

Views: 50

Answers (1)

Andrew
Andrew

Reputation: 49646

Since you don't provide the type argument explicitly, it's being inferred (see Type Inference) allowing String to be one of the valid return types.

I assume it gets resolved to a more permissive type (see AdditionalBound) taking into account the type of the variable it's going to be assigned to and the bounds you declared.

Something like

String & AutoCloseable
Integer & AutoCloseable
<Anything Really> & AutoCloseable

It changes if you set the type argument explicitly

String autoCloseable = new Foo().<AutoCloseable>get(0);

resulting in a compilation error.

Upvotes: 2

Related Questions