michael nesterenko
michael nesterenko

Reputation: 14439

incorrect type inferring

I have following code:

SomeInterface self = sessionContext.getBusinessObject(sessionContext.getInvokedBusinessInterface());

And following method signature (from eclipse tooltip (not real code)):

<Object> Object javax.ejb.SessionContext.getBusinessObject(Class<Object> arg0) throws IllegalStateException

For some reason return type is resolved as Object. And that is weird as eclipse does not mark this line as erroneous, however ant and maven builders fails on this line saying that Object can not be converted to SomeInterface.

I have several questions:

I have following example which is correctly compiled under eclipse, but fails in maven:

public class TestClass implements SomeInterface {
    private Resolver resolver;

    /**
     * 
     */
    @SuppressWarnings("unchecked")
    public TestClass() {
        SomeInterface c = resolver.some(resolver.someClass());
    }

    @Override
    public void something() {
    }
}

class Resolver {
    public <T> T some(final Class<T> c) {
        return null;
    }

    public Class someClass() {
        return null;
    }
}

interface SomeInterface {
    void something();
}

Here type is inferred correctly (from eclipse tooltip (not real code)):

 <SomeInterface> SomeInterface Resolver.some(Class<SomeInterface> c)

But this class still can not be compiled with maven compiler.

I am using eclipse juno.

UPD

Maven failure:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.3.2:compile (default-compile) on project jpharm-server: Compilation failure
[ERROR] TestClass.java:[21,39] incompatible types
[ERROR] found   : java.lang.Object
[ERROR] required: SomeInterface

Upvotes: 0

Views: 715

Answers (2)

Mattias Buelens
Mattias Buelens

Reputation: 20159

The problem is this line:

public Class someClass() {

This returns a raw type Class object, which is practically equivalent with a Class<? extends Object>. You should make this method generic as well:

public Class<? extends T> someClass() {

and call it with:

resolver.<SomeInterface>someClass();

Ideally, you'd fill an actual type in the signature of your getInvokedBusinessInterface() so that it returns a Class<? extends SomeInterface>.

Upvotes: 1

assylias
assylias

Reputation: 328608

You can write:

SomeInterface c = resolver.<SomeInterface> some(resolver.someClass());

to help the compiler.

The specific example you give should not compile. The compiler, when applying type inference, tries to find the most specific type that suits all the operands of the statement. Here, resolver.someClass() returns a Class which could be any class, i.e. it really is a Class<? extends Object> and there is no way to infer that ? extends Object is a SomeInterface.

For example, someClass could well be:

public Class someClass() {
    return Object.class;
}

Upvotes: 4

Related Questions