Generics and varargs java

Below is my setup

public interface Test<T extends MyInterface> 
{
    someMethod(T... a)
}

public class TestImpl implements Test<MyInterfaceImpl> 
{
    someMethod(MyInterfaceImpl... a)
}

public class MyInterfaceImpl implements MyInterface {}

public someClass { @Autowired TestFactory testfactory 

......

// getting an error --  Type mismatch Can't assign non-array value to an array 
testfactory.getTest(Type type).someMethod(new MyInterfaceImpl()) 

}

public class TestFactoryImpl implements TestFactory { Test getTest(Type type) { return registry.get(type)}}

      

which in turn results in java.lang.ClassCastException: [Lcom.test.MyInterface; cannot be applied to [Lcom.test.Impl.MyInterfaceImpl;

but below works

testfactory.getTest(Type type).someMethod(new MyInterfaceImpl[]{new MyInterfaceImpl()}) 

      

Not sure what's going on. help me please

+3


source to share


2 answers


Good. The problem is in the development of your pre-existing code (which you cannot change). Availability public interface Test<T extends MyInterface>

and then public class TestImpl implements Test<MyInterfaceImpl>

incorrect.

TestImpl

implements Test

with MyInterfaceImpl

, whereas the original interface Test

only expects an object extends

MyInterface

and does not implement it.

There will be confusion when the code is executed at runtime. Not only the next line throwsClassCastException

test.someMethod(new MyInterfaceImpl()); 

      

but test.someMethod();

by itself raises an exception. So, let's say if you called this method a factory without passing any argument, you still get an exception, since the original as designed is wrong. Normally, test.someMethod();

you shouldn't start with an exception. You will need to speak with the relevant party to correct this serious issue.



Below is a sample solution:

The method someMethod(MyInterface...)

is of the raw type Test

. Generic type references Test<T>

must be parameterized.

This means that you have to Test<MyInterfaceImpl> test

avoid this error with just the operator new

.

Test<MyInterfaceImpl> test
...
test.someMethod(new MyInterfaceImpl()); 

      

The above code will work without issue.

+5


source


The best solution in your class is TestImpl

doing the following

public class TestImpl implements Test<MyInterface>{...}

      

instead

public class TestImpl implements Test<MyInterfaceImpl>{...}

      



This way you don't have to explicitly parameterize the object instance (i.e. you could just do

Test test
...
test.someMethod(new MyInterfaceImpl());

      

)

0


source







All Articles