我想实现一个同时使用泛型和varargs的函数。
public class Question {
public static <A> void doNastyThingsToClasses(Class<A> parent, Class<? extends A>... classes) {
/*** something here ***/
}
public static class NotQuestion {
}
public static class SomeQuestion extends Question {
}
public static void main(String[] args) {
doNastyThingsToClasses(Object.class, Question.class, SomeQuestion.class); // OK
doNastyThingsToClasses(Question.class, SomeQuestion.class); // OK
doNastyThingsToClasses(Question.class, Object.class, SomeQuestion.class); // compilation failure
}
}
这里的意图是Assert传递给该函数的所有参数都是Class对象,扩展了作为第一个参数给定的Class,因此main方法的前两行将编译,而第三行生成错误。My question is:
为什么我得到"类型安全:为varargs参数"前两行的消息"创建Class的泛型数组。
我错过什么了吗?**Additional question:**
如何重新设计它来防止这个警告出现在调用"doNastyThingsToClasses"函数的每一行?我可以将它改为"doNastyThingsToClasses(Class parent,Class〈?〉... classes)"并去掉警告,但这也去掉了编译时的类型检查---如果我想确保正确使用这个函数的话就不太好了。有更好的解决方案吗? parent, Class<?>... classes)" and get rid of the warnings but this also removes the compilation-time type checking --- not so good if I wanted to assure the right use of this function. Any better solution?
6条答案
按热度按时间w80xi6nr1#
Angelika Langer的Java泛型FAQ几乎总是对此进行了详细的解释(滚动到“为什么当我调用“varargs”方法时,编译器有时会发出未经检查的警告?”-ID工作得不好)。
基本上,您最终会以比正常情况更糟糕的方式丢失信息。Java泛型中的另一个小痛点是:(
zazmityj2#
乔恩·斯基特的答案(当然)是正确的;我将对此进行一些扩展,指出您可以使用一个很大的“if”来消除此警告。如果您愿意使用Java7构建项目,则可以避免此警告。
Bob Lee编写了a proposal,作为Project Coin的一部分,让这个警告在方法声明位置而不是使用位置被抑制。
JDK 7接受了这个建议(尽管语法稍有变化,变为
@SuppressWarnings("varargs")
);如果你好奇的话,可以看看the commit that added this support to the JDK。这对您未必有帮助,但我想我会把它作为一个单独的答案,这样它就可以为未来的读者所用,他们可能足够幸运地生活在后Java-7的世界里。
fcwjkofz3#
附带说明一下,可以使用Java 7中引入的@SafeVarargs注解来抑制警告。
ej83mcc04#
我解决这个问题的方法是
1.创建一个类Nastier
1.删除...从doNastyThingsToClasses中删除
1.使doNastyThingsToClasses成为非静态方法
1.把名字缩短,像do
1.把这个退了
1.将重复参数移动到类属性
我相信代码看起来很干净,我很高兴...:)
bmp9r5qi5#
好吧,最后我还是把varargs扔掉了:
唯一的缺陷是填充用于携带函数参数的集合的代码很长。
smdncfj36#
The second argument
Class<? extends A>
... that must extend the class that the first argument is (ex. argument one is aQuestion
so the second argument be something that extendsQuestion
.The Breakdown:
NastyThingsToClasses(Object.class, Question.class, SomeQuestion.class); // OK
Everything extends
Object
so the second argument is correct.NastyThingsToClasses(Question.class, SomeQuestion.class); // OK
SomeQuestion
extendsQuestion
so thats fair game.NastyThingsToClasses(Question.class, Object.class, SomeQuestion.class);
Object
does not extendQuestion
hence error.hopefully that cleared things up.
-Brett