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
source to share
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.
source to share
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());
)
source to share