簡體   English   中英

實現接口的枚舉的 Java 參數和返回類型

[英]Java Parameter and return types for enum that implements interface

經過大量搜索,我發現了許多與普通課程相關的問題,但沒有一個與枚舉真正相關。

這工作正常:

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 中的方法列表不能應用於給定類型;要求:找到列表:列表原因:無法通過方法調用轉換將實際參數列表轉換為列表”

我不確定解決這個問題的方法 - 我已經嘗試添加您在上面看到的聲明,以便它讀取public <MyEnumInterface> List<MyEnumInterface> testingList(); 但這給了我關於未經檢查的強制轉換的“警告”,同時繼續失敗

這一切都源於我對泛型及其與枚舉的關系缺乏更深入的了解。

我看到了一些關於<? extends Enum<E> & SecondInterface> <? extends Enum<E> & SecondInterface>但這擴展了我的理解。 請幫忙!

順便說一句,我認為返回類之前的泛型聲明用於為類型腐蝕目的指定“T”是否正確?

泛型本質上是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;
}

如果要允許實現類定義要使用的MyEnumInterface實現, MyEnumInterface可以將接口方法的返回類型指定為任何MyEnumInterfaceList

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?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM