【问题标题】:Confused to Cast List in generics method?对泛型方法中的 Cast List 感到困惑?
【发布时间】:2020-06-13 09:32:48
【问题描述】:
    class A {
        private int a;
    }

    public static <T> List<T> listStrToListT(String str) {
        String[] idStrs = str.replace(" ", "").split(",");
        List<T> uids = new ArrayList<>();
        for (String idStr : idStrs) {
            uids.add((T) idStr);
        }
        return uids;
    }

    public static void main(String[] args) {
        List<A> lst = listStrToListT("1,2,3");
        System.err.println(lst);
    }

这个程序没有任何错误。但是当我调试时(在下图中):lstList&lt;String&gt;。为什么我直接将List&lt;String&gt;(右侧)分配给List&lt;A&gt;(左侧) ?

【问题讨论】:

    标签: java debugging generics collections casting


    【解决方案1】:

    请记住,Java 中的泛型只是编译时的事情。在运行时,所有泛型参数都被擦除为非泛型类型。

    从编译器的角度来看,listStrToListT 可以返回调用者想要的任何类型的List,而不仅仅是List&lt;String&gt;。您通过 (1) 使 listStrToListT 泛型和 (2) 将 idStr 转换为 T,使编译器相信了这个非事实。你是在说“我相信这个演员在运行时会起作用。别担心,编译器!”这个演员表肯定闻起来很腥,不是吗?如果TA...

    无论如何,现在List&lt;A&gt; lst = listStrToListT("1,2,3"); 编译,因为listStrToListT“可以返回任何类型的List”,如前所述。你会想象T 被推断为A,而你在listStrToListT 中的转换会在运行时失败,但事实并非如此。

    现在是运行时,所有泛型类型都被删除,使您的代码看起来像这样:

    public static List listStrToListT(String str) {
        String[] idStrs = str.replace(" ", "").split(",");
        List uids = new ArrayList();
        for (String idStr : idStrs) {
            uids.add((Object)idStr);
        }
        return uids;
    }
    
    // main method:
    List lst = listStrToListT("1,2,3");
    System.out.println(lst);
    

    请注意,T 的转换变成了Object 的转换,这在这里真的是多余的。

    打印出列表只需要在每个Objects 上调用toString,因此不会在那里进行转换。

    请注意,在编译时“闻起来很腥”的东西在编译时是完全有效的。鱼腥味的演员表成为Object 的完全有效(和冗余)演员表!演员去哪儿了?

    只会在必要时插入演员表。这就是泛型在 Java 中的工作方式。所以让我们创造这样的情况。假设在A 中,您有一个用于字段a 的getter,而不是打印整个列表,而是打印第一个元素的a

    // main method:
    List<A> lst = listStrToListT("1,2,3");
    System.out.println(lst.get(0).getA());
    

    好吧,为了能够访问getA,需要插入演员表:

    List lst = listStrToListT("1,2,3");
    System.out.println(((A)lst.get(0)).getA());
    

    否则lst.get(0) 将是Object 类型,而Objects 没有getA 方法。

    此时你的程序会崩溃。

    【讨论】:

    • 非常感谢您的详细解释。我对 java 中的泛型方法感到困惑。
    猜你喜欢
    • 1970-01-01
    • 2013-07-27
    • 1970-01-01
    • 2017-03-20
    • 2013-07-19
    • 1970-01-01
    • 1970-01-01
    • 2021-03-30
    • 1970-01-01
    相关资源
    最近更新 更多