Java parameters and return types for an enumeration that implements an interface

After searching many times, I found a lot of relevant questions for regular classes, but not so much what really relates to enumerations.

This works great:

package list; public interface Testing { //treat as a tag interface. } 
 package list; public class Foo implements Testing { } 
 package list; import java.util.ArrayList; import java.util.List; public class Bar { public Bar(){ List<Foo> myList = new ArrayList<Foo>(); myList.add(new Foo()); testList(myList); testMethod(new Foo()); } public void testMethod(Testing myInstance){ //do nothing } public <Testing> void testList(List<Testing> myList){ //do nothing } } 

However, my problem is understanding what happens when I try to do the same with Enums instead of Foo

In this example, there is an interface definition that is defined as the adoption of an interface parameter, which is actually implemented by an enumeration that implements the interface:

I have two interfaces:

 public interface MyEnumInterface { //implemented by Enums } 
 import java.util.List; public interface SecondInterface { public MyEnumInterface testMe(String myString); public <MyEnumInterface> List<MyEnumInterface> testingList(); public List <MyEnumInterface> enumTestOne(String anotherString); public List <MyEnumInterface> enumTestTwo(String anotherString); } 

Two emum as follows:

 public enum MyEnum implements MyEnumInterface{ VALUE_ONE, VALUE_TWO, VALUE_THREE; } 
 public enum MyEnum2 implements MyEnumInterface{ VALUE_A, } 

And the java test class:

 import java.util.ArrayList; import java.util.List; class MyClass implements SecondInterface{ public MyClass(){ single(testMe("")); enumTestOne(""); enumTestTwo(""); } public MyEnum testMe(String someParam){ return MyEnum.VALUE_ONE; } public List<MyEnumInterface> enumTestOne(String anotherString) { List<MyEnum> returnL = new ArrayList<MyEnum>(); returnL.add(MyEnum.VALUE_ONE); returnL.add(MyEnum.VALUE_THREE); return returnL; } public List<MyEnumInterface> enumTestTwo(String anotherString) { List<MyEnum2> returnL = new ArrayList<MyEnum2>(); returnL.add(MyEnum2.VALUE_A); return returnL; } public List<MyEnum> testingList(){ List<MyEnum> returnL = new ArrayList<MyEnum>(); returnL.add(MyEnum.VALUE_ONE); returnL.add(MyEnum.VALUE_THREE); return returnL; } public void single(MyEnumInterface val){ System.out.println("Value is " + val); } public static void main(String[] args){ MyClass clazz = new MyClass(); } } 

I am struggling with the problem that the return type enumTestOne (..) is encoded as List, but the interface indicates the list. It works fine when it is a standalone instance of Enum 'MyEnum', but when it presents a list of values ​​that seem to fail with:

": the list of methods in the MyClass class cannot be applied to the specified types; required: List found: List reason: the actual argument List cannot be converted to a method call conversion"

I am not sure about that. I tried adding the declaration you see above so that it public <MyEnumInterface> List<MyEnumInterface> testingList(); but then gives me β€œwarnings” about uncontrolled refuse, continuing to fail

All this stems from my lack of a deeper understanding around Generics and how they relate to Enums.

I saw some interesting statements regarding <? extends Enum<E> & SecondInterface> <? extends Enum<E> & SecondInterface> but this explains my understanding. Please, help!

As I said, do I correctly think that the gerneic declarations before the return class are used to indicate "T" for type erosion purposes?

Thanks in ignorant progress,

Al

+4
source share
2 answers

If you want to allow the implementation class to determine which implementation of MyEnumInterface use, you can specify the return type of the interface methods as List any MyEnumInterface .

 public List<? extends MyEnumInterface> enumTestOne(String anotherString); public List<? extends MyEnumInterface> enumTestTwo(String anotherString); 

As a result of the implementation of these methods, a specific return type can be determined.

 public List<MyEnum> enumTestOne(String anotherString) { List<MyEnum> returnL = new ArrayList<MyEnum>(); returnL.add(MyEnum.VALUE_ONE); returnL.add(MyEnum.VALUE_THREE); return returnL; } public List<MyEnum2> enumTestTwo(String anotherString) { List<MyEnum2> returnL = new ArrayList<MyEnum2>(); returnL.add(MyEnum2.VALUE_A); return returnL; } 

By the way, you can do the same in reverse with super . This indicates that any type that is a supertype of that type can be used.

 public void addToList(List<? super MyEnum> list) { list.add(MyEnum.VALUE_ONE); } addToList(new ArrayList<MyEnum>()); addToList(new ArrayList<MyEnumInterface>()); 

see also

Java Generics (wildcards)

Why is SomeClass not equivalent to SomeClass in typical Java types?

+2
source

General invariant features. Thus, List<String> not a subtype of List<Object>

You will need to change your method to include the List of MyEnumInterface , not the individual enum classes.

 public List<MyEnumInterface> enumTestOne(String anotherString) { List<MyEnumInterface> returnL = new ArrayList<MyEnumInterface>();//Change returnL.add(MyEnum.VALUE_ONE); returnL.add(MyEnum.VALUE_THREE); return returnL; } public List<MyEnumInterface> enumTestTwo(String anotherString) { List<MyEnumInterface> returnL = new ArrayList<MyEnumInterface>();//Change returnL.add(MyEnum2.VALUE_A); return returnL; } 
+4
source

Source: https://habr.com/ru/post/1432793/


All Articles