Java, plain interfaces for generic types - bad design?

I have a regular interface (which I don’t want to make common) using the generic Get method and the generic class that implements it.

@Override does not give me a warning, and the code works as intended, but I have a warning in Foo # Get (): Type safety: The return type T for Get() from the type Test.Foo<T> needs unchecked conversion to conform to TT from the type Test.Attribute

Should I make Attribute common interface? I try to avoid manually messing with Object and casts and store all types of various attributes in a list.

(using static only to compile a test sample in one file - it does not change anything)

 import java.util.ArrayList; import java.util.List; public class Test { static interface Attribute { <TT> TT Get(); } static class Foo<T> implements Attribute { T val; public Foo(T val) { this.val = val; } @Override public T Get() { System.out.println("it is me"); return val; } } public static void main(String[] args) { List<Attribute> list = new ArrayList<Attribute>(); list.add(new Foo<String>("test")); String s = list.get(0).Get(); System.out.println(s); } } 
+4
source share
3 answers

You can create a generic Attribute interface and then use wildcard to allow any type of Attribute to be placed in a List :

 List<Attribute<?>> list = new ArrayList<Attribute<?>>(); 

If you need to make sure that only one Attribute each type can be placed in the container, just use Set :

 Set<Attribute<?>> set = new HashSet<Attribute<?>>(); 
+1
source

To use the interface without casting, you will need to make a common interface.

 import java.util.ArrayList; import java.util.List; public class Test { static interface Attribute<E> //Added Generic Param { <E> E Get(); } static class Foo<T> implements Attribute<T> //Added Generic Param { T val; public Foo(T val) { this.val = val; } @Override public T Get() { System.out.println("it is me"); return val; } } public static void main(String[] args) { //Specify Type of generic List<Attribute<String>> list = new ArrayList<Attribute<String>>(); list.add(new Foo<String>("test")); String s = list.get(0).Get(); System.out.println(s); } } 
+1
source

The problem with the general method in the base class is that someone can call it with an explicit type parameter. Which obviously does not make sense here, so the compiler complains.

It seems the best solution is to create a common base class. If you want to store attributes of different types in a list, then you have another problem; how are you going to revert to the original types (regardless of whether you use shared files)?

+1
source

All Articles