4

经过大量搜索,我发现了很多与普通课程相关的问题,但没有一个与枚举真正相关。

这工作正常:

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);
}

两个emum如下:

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 中的方法列表不能应用于给定类型;必需:找到列表:列表原因:实际参数列表无法通过方法调用转换转换为列表”

我不确定解决这个问题的方法 - 我已经尝试添加您在上面看到的声明,以便它读取 public <MyEnumInterface> List<MyEnumInterface> testingList(); 但是然后给我关于未经检查的演员的“警告”,同时继续失败

这一切都源于我对泛型以及它们与枚举的关系缺乏更深入的了解。

我已经看到了一些有趣的声明, <? extends Enum<E> & SecondInterface> 但这扩展了我的理解。请帮忙!

顺便说一句,我认为返回类之前的泛型声明用于指定“T”用于类型侵蚀目的是否正确?

4

2 回答 2

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;
}
于 2012-09-06T19:03:32.233 回答
2

如果要允许实现类定义MyEnumInterface使用哪个实现,可以将接口方法的返回类型指定为 a Listof any 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. 这指定可以使用作为给定类型的超类型的任何类型。

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

addToList(new ArrayList<MyEnum>());
addToList(new ArrayList<MyEnumInterface>());

也可以看看

Java 泛型(通配符)

为什么 SomeClass 不等同于 Java 泛型类型中的 SomeClass?

于 2012-09-06T19:48:56.090 回答