在声明泛型类型时是否存在语法糖?

时间:2015-10-27 11:14:26

标签: java generics syntactic-sugar

假设我有这个课程

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<?, ?>,但这会阻碍我所知道的类型安全检查。

有没有办法正确处理这个问题?命名T extends List<? extends Integer>, E extends List<? extends Integer并将该名称用作语法快捷方式的某种方式可能是?

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

2 个答案:

答案 0 :(得分:2)

不是,但我认为您的类型参数无法正常工作。

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

<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,这也是有效的,例如:

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 :(得分:1)

在Java 8中,您可以使用

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

因此,您根本不需要指定myGeneric类型,它将被推断。但是这种方法存在一些已知的局限性(如无法修改外部方法的局部变量或无法抛出已检查的异常)。