为什么instanceof有时似乎在静态泛型函数中工作?
问候。这是我在这个网站上的第一篇文章。
我认为由于类型擦除,人们无法指望以下代码能够编译,事实上,它无法在早期版本的 Eclipse 上编译。我的理解是 instanceof 是一个运行时运算符,无法知道将在运行时编译掉的泛型类型:
public static <E extends Comparable<? super E>>
void SampleForQuestion(E e)
{
if ( !(e instanceof String) )
System.out.println("I am not a String");
else
System.out.println("I am a String");
}
但是,我很惊讶地发现您的线程之一实际上在答案中包含了一些这样的代码,我最新的 Eclipse(Windows 上的 Galileo,带有 JVM 1.6 rev 20)对此非常满意 - 而且它也有效。 (我确实注意到有人说它在 Eclipse 上有效,但在该线程中的另一个 IDE/JDK 上无效,但不记得具体细节。)
有人可以解释为什么它有效,更重要的是,因为我必须指导我的学生,它是否应该在未来发挥作用。
谢谢。 (我希望代码格式正确 - 从我的角度来看,它看起来缩进正确,并且没有制表符。)
Greetings. This is my first post in this site.
I thought that because of type erasure, one could not expect the following code to compile, and indeed, it did not compile on an earlier version of Eclipse. My understanding was that instanceof was a run-time operator and could not know about the generic type which would be, by run-time, compiled away:
public static <E extends Comparable<? super E>>
void SampleForQuestion(E e)
{
if ( !(e instanceof String) )
System.out.println("I am not a String");
else
System.out.println("I am a String");
}
However, I was surprised to see that one of your threads actually included some code like this in an answer, and my latest Eclipse (Galileo on Windows with JVM 1.6 rev 20) is perfectly happy with it -- and it works, too. (I did notice that someone said it worked on Eclipse but not in another IDE/JDK in that thread, but don't remember the specifics.)
Can someone explain why it works, and more importantly, because I have to guide my students, whether it should be expected to work in the future.
Thank you. (I hope the code formatting comes through correctly - it looks indented correctly from my perspective and there are no tabs.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
被删除的是
E
。事实上,您不能执行if (e instanceof E)
,因为类型参数E
已被删除。但是,String
不是参数化类型,并且e
确实有运行时类型,因此if (e instanceof String)
工作得很好。JLS 15.20.2 类型比较
instanceof
运算符String
是一种可具体化的类型。E
不是。JLS 4.7 可具体化类型
另请参阅
instanceof
和.class
文字是可以在新代码中使用原始类型的两个例外What is erased is
E
. You can't, in fact, doif (e instanceof E)
, because the type parameterE
is erased. However,String
is not a parameterized type, ande
does have a run-time type, soif (e instanceof String)
works just fine.JLS 15.20.2 Type comparison
instanceof
operatorString
is a reifiable type.E
is not.JLS 4.7 Reifiable Types
See also
instanceof
and.class
literal are the two exceptions where raw type in new code can be used效果很好。采用没有。因此,人们使用诸如检查列表的第一个元素之类的技巧。
E e
的方法被编译为Comparable e
,但这并不会阻止对运行时存在的类型(您的String
)进行检查。例子)。您不能做的是检查类似ArrayList
(或您自己的类的通用专业化)的内容,因为ArrayList
类型在运行时存在,但是 < code>ArrayListThat works fine. The method that takes
E e
is compiled asComparable e
, but that doesn't prevent checks against types that exist at runtime (String
in your example). What you can't do is check for something likeArrayList<String>
(or a generic specialization of your own class), because theArrayList
type exists at runtime, butArrayList<String>
does not. Thus, people use hacks like checking the first element of the list.小写的 e 是一个对象,每个对象都有它的类型。您可以检查任何对象的instanceof。用不同的名称阅读你的代码,会更容易得到:
The lower case e is an object and every object has it's type. You can check instanceof on any object. Read your code with different names and it'll be easier to get: