Vic*_*yew 5 java generics wildcard
在Java教程中,有时会这样写:
Set<?> unknownSet = new HashSet<String>();
Run Code Online (Sandbox Code Playgroud)
虽然我了解在类定义和方法中使用类型参数和通配符的好处,但我想知道以下问题:
通配符仅在方法参数声明中真正有用,因为它们增加了可接受的参数类型的范围,例如:
\n\nvoid original(List<Number> list) { /* ... */ }\nvoid withUpperWildcard(List<? extends Number> list) { /* ... */ }\nvoid withLowerWildcard(List<? super Number> list) { /* ... */ }\n\noriginal(new ArrayList<Number>()); // OK.\noriginal(new ArrayList<Integer>()); // Compiler-error.\noriginal(new ArrayList<Object>()); // Compiler-error.\n\nwithUpperWildcard(new ArrayList<Number>()); // OK.\nwithUpperWildcard(new ArrayList<Integer>()); // OK.\n\nwithLowerWildcard(new ArrayList<Number>()); // OK.\nwithLowerWildcard(new ArrayList<Object>()); // OK.\nRun Code Online (Sandbox Code Playgroud)\n\n返回类型中的通配符使您的类的用户的生活变得困难(或者更确切地说,混乱),因为您必须传播它们,或者执行显式工作以使它们消失,例如:
\n\nList<? extends Number> method() { /* ... */ }\n\n// Compiler error.\nList<Number> list1 = method();\n// OK, but yuk!\nList<? extends Number> list2 = method(); \n// OK, but the list gets copied.\nList<Number> list3 = new ArrayList<Number>(method()); \nRun Code Online (Sandbox Code Playgroud)\n\n局部变量中的通配符不是必需的(除非接受通配符返回方法的结果)。
\n\n引用《Effective Java》第二版:
\n\n\n\n如果类的用户必须考虑通配符类型,则 class\xe2\x80\x99s API 可能有问题。
\n