【问题标题】:Is there syntactic sugar when declaring generic types?声明泛型类型时是否有语法糖?
【发布时间】:2016-01-26 18:38:47
【问题描述】:

假设我有这门课

class Generic<T extends List<? extends Integer>, E extends List<? extends Integer>>

或菱形括号内的任何长泛型类型。在使用此类时,为了保持类型安全,我需要不断提及泛型类型。因此,例如,如果我想遍历上述类的Set 或对其进行操作,我需要执行以下操作:

class SomeClass {

    <T extends List<? extends Integer>, E extends List<? extends Integer>> void add(Set<Generic<T, E>> mySet, Generic<T, E> toAdd) {

        mySet.add(toAdd);
    }

    <T extends List<? extends Integer>, E extends List<? extends Integer>> void iterate(Set<Generic<T, E>> mySet) {

        for (Generic<T, E> myGeneric : mySet)
        {
                // do something with myGeneric
        }
    }
}

但是,这很快就会变得非常麻烦。我搜索并找不到某种正确处理此问题的方法。我知道可以写Generic&lt;?, ?&gt;,但据我所知,这会阻碍类型安全检查。

有没有办法妥善处理这个问题?以某种方式命名T extends List&lt;? extends Integer&gt;, E extends List&lt;? extends Integer 并将该名称用作语法快捷方式?

快速说明:我不是在谈论 Java 7 中引入的 initialization 语法糖,其中右侧可以使用来自 声明

【问题讨论】:

    标签: java generics syntactic-sugar


    【解决方案1】:

    并非如此,但我认为您的类型参数工作不正常。

    如果您的方法是通用的,那么您可以轻松地引用方法的类型参数,而不必每次都重写它们的边界:

    <T extends List<? extends Integer>, E extends List<? extends Integer>> 
    void iterate(Set<Generic<T, E>> mySet) {
        for (Generic<T, E> myGeneric : mySet) {
            // do something with myGeneric
        }
    }
    

    如果你的类是通用的,这也是有效的,例如:

    class SomeClass<T extends List<? extends Integer>, E extends List<? extends Integer>> {
       void iterate(Set<Generic<T, E>> mySet) {
            for (Generic<T, E> myGeneric : mySet) {
                // do something with myGeneric
            }
        }
    }
    

    【讨论】:

    • 是的,在方法或类中声明泛型类型是我已经知道的事情(无论如何+1),但仍然很烦人。我在想如果有办法“命名”&lt;...&gt; 的所有内容并在其他任何地方重用该“名称”。另外,为什么您认为我无法正确使用类型参数?
    • 糟糕!当我简化问题时,我丢失了正确的代码。请查看我编辑的问题。
    【解决方案2】:

    在 Java 8 中你可以使用

    mySet.forEach(myGeneric -> {
        ...
    });
    

    所以你根本不需要指定myGeneric 类型,它会被推断出来。但是这种方法有一些已知的限制(例如无法修改外部方法的局部变量或无法抛出检查的异常)。

    【讨论】:

    • 是的,很好,但这只能解决迭代混乱的例子,对吧?
    • @user1803551,是的,在正常的方法声明中,您仍然需要指定完整的签名。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 2015-12-14
    • 2018-12-14
    • 1970-01-01
    • 2019-04-02
    • 1970-01-01
    • 2010-10-23
    相关资源
    最近更新 更多