2013-02-28 89 views
8

我需要在java中使用反射。我知道Class clazz会创建一个代表Class对象的变量。但是,我试图使用forName("aClassName")方法引用String中的Class对象。我的IDE(Eclipse)似乎更喜欢使用Class<?> clazz来声明变量。我在其他地方多次看到过这种符号。这是什么意思?Class clazz和Class <?> clazz在java中有什么区别?

编辑:删除对三元运算符的引用,因为它与此问题无关。

+2

这与三元运算符有什么关系?这里没有运营商。 – 2013-02-28 20:06:24

+0

在这种情况下,它不是一个三元运算符,它是一个未绑定的通配符。 – Perception 2013-02-28 20:06:30

回答

22

Class是一个原始类型 - 它基本上是一种泛型类型,你对待就好像你根本不知道泛型一样。

Class<?>是使用未绑定通配符泛型类型 - 这基本上意味着“Class<Foo>某种类型Foo,但我不知道是什么。”

同样可以有通配符界限:

  • Class<? extends InputStream>的意思是“Class<Foo>某种类型Foo,但我不知道是什么,只要它是InputStream或子类”

  • Class<? super InputStream>的意思是“Class<Foo>某种型号Foo,但我不知道什么,只要它是InputStream或超级”

又见Java Generics FAQ很多更多信息:

和Java语言规范:

特别是,从原始类型的部分:

原始类型密切相关的通配符。两者都基于存在类型。原始类型可以被认为是通配符,其类型规则故意不适用,以适应与旧代码的交互。历史上,原始类型在通配符之前;它们首先在GJ中介绍过,并在文章中描述了过去对于未来的安全性:Gilad Bracha,Martin Odersky,David Stoutamire和Philip Wadler在Java编程语言中增加Genericity在ACM Conference on Object-面向对象编程,系统,语言和应用程序(OOPSLA 98),1998年10月。

+0

但是,从技术上讲,原始类型和未绑定通配符之间没有任何区别,是吗?我的意思是,除了避免编译器警告和可能增加代码可读性。 – Gothmog 2013-02-28 20:13:37

+1

@Gothmog:由于原始类型的处理方式(IIRC),有些情况会影响覆盖和重载。 – 2013-02-28 20:14:55

+0

非常感谢Jon,非常感谢! – 2013-02-28 20:21:54

0

在一般类型通配符?表示“任何类”(因此Class<?>相同只是Class而是作为原始类型参数化正确)。

2

首先要认识到的是,在这种情况下,“?”不是三元运算符,但它是Java的泛型实现的一部分,并指出类的类型未指定,因为其他一些答案已经解释过。

为了阐明关于三元运算符的问题,它其实很简单。

想象一下,你已经if语句如下:

boolean correct = true; 
String message; 

if (correct) { 
    message = "You are correct."; 
} else { 
    message = "You are wrong."; 
} 

您可以重写与三元运算符(认为它作为if-else语句的快捷操作):

message = (correct) ? "You are correct." : "You are wrong."; 

然而,为了提高代码的可读性,除了最简单的语句之外,最好避免使用三元运算符。

+0

我看到,我的印象是“?”总是被称为三元运算符。我现在看到这是不正确的。三元运算符是常用的,还是这是过去更受欢迎的功能? – 2013-02-28 20:25:13

+0

我会说,它仍在使用,但通常可以避免。我仍然看到它现在随时出现在代码中,所以知道如何阅读它是很好的。在极少数情况下,使用更简洁的陈述可以更清楚地了解正在发生的事情。这是我唯一考虑使用if/else的时间。 – yogaphil 2013-02-28 21:19:18

相关问题