这很好用:
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
}
}
然而,我的问题在于理解当我尝试做同样的事情时会发生什么
Enums
代替
Foo
此处的示例是有一个接口定义,定义为接受接口参数,实际上,接口参数由实现接口的枚举实现:
我有两个界面:
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);
}
两位妈妈如下:
public enum MyEnum implements MyEnumInterface{
VALUE_ONE,
VALUE_TWO,
VALUE_THREE;
}
public enum MyEnum2 implements MyEnumInterface{
VALUE_A,
}
测试java类:
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();
}
}
我正在努力解决enumTestOne(..)的返回类型被编码为List但接口指定List的问题。当它是Enum'MyEnum'的单个实例时它工作正常但是当它是一个值列表时它似乎失败了:
“错误:MyClass类中的方法列表不能应用于给定的类型; 必需:列表 发现:列表 原因:实际参数List无法通过方法调用转换“
转换为List
我不知道如何解决这个问题 - 我已经尝试添加您在上面看到的声明,以便它可以读取
public <MyEnumInterface> List<MyEnumInterface> testingList();
但是那时候给我“警告”关于未经检查的演员阵容,同时继续失败
这一切都源于我对Generics缺乏更深入的理解以及它们与Enums的关系。
我见过一些有趣的声明
<? extends Enum<E> & SecondInterface>
但这延伸了我的理解。请帮忙!
顺便说一句,我认为返回类之前的生命声明用于指定类型侵蚀目的的“T”是否正确?
感谢无知的进步,
的Al。
答案 0 :(得分:4)
泛型本质上是invariant
。因此List<String>
不是List<Object>
您必须更改方法以包含MyEnumInterface
的列表,而不是单独的枚举类。
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;
}
答案 1 :(得分:2)
如果要允许实现类定义要使用的MyEnumInterface
实现,可以将接口方法的返回类型指定为任何List
的{{1}}。< / p>
MyEnumInterface
然后,这些方法的实现可以定义具体的返回类型。
public List<? extends MyEnumInterface> enumTestOne(String anotherString);
public List<? extends MyEnumInterface> enumTestTwo(String anotherString);
顺便说一句,您可以使用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;
}
“反向”执行相同操作。这指定可以使用任何类型为给定类型的超类型。
super
Why is SomeClass not equivalent to SomeClass in Java generic types?