Java:检查泛型是否为 int
public class Hashing<Key, Elem>
我想检查 Key 是否是一个 int,所以我将这一行放在构造函数中:
Key key = null;
if (!(key instanceof Integer)) {
throw new TypeOfKeyStillNotSupportedException();
}
但是,我以这种方式创建一个:
tHash = new Hashing<Integer, Movie>(max);
然后弹出了该死的 TypeOfKeyStillNotSupportedException() 。为什么会发生这种情况以及我该如何正确地做到这一点?
提前致谢。
编辑:已经发现问题在于密钥被分配为空。现在的问题是:如何进行检查?
public class Hashing<Key, Elem>
I want to check if Key is an int, so I place this lines in the constructor:
Key key = null;
if (!(key instanceof Integer)) {
throw new TypeOfKeyStillNotSupportedException();
}
However, I create one this way:
tHash = new Hashing<Integer, Movie>(max);
And the damn TypeOfKeyStillNotSupportedException() pops. Why is this happening and how can I do it properly?
Thanks in advance.
Edit: Already found that the problem is with key being assigned null. The question is now: How to do the check?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
null
不是任何东西的instanceof
。由于类型擦除,无法在运行时直接检查Key
的类型。一种选择是让用户将Class
传递给构造函数,以便您可以检查:为了避免重复类型参数,您可以创建一个静态工厂方法:
null
is not aninstanceof
anything. Due to type erasure, there's no way to check the type ofKey
directly at runtime. One option is to make the user pass inClass<Key>
to the constructor so that you can check that:To save yourself from having to repeat the type arguments, you can create a static factory method:
Java泛型是使用类型擦除实现的:泛型信息被丢弃在用于类型检查后由编译器执行,因此在运行时您的类实际上只是
Hashing
。这就是为什么你不能基于泛型类型进行运行时检查。您可以将
Class
类型的参数添加到构造函数,调用者必须传递用作键的类型的正确类对象。例如,在Hashing
中,只有Integer.class
会被接受作为该参数的值,并且您可以将其用于运行时类型检查。不过,将密钥的类对象作为参数传递的要求使得构造函数调用看起来有点尴尬。Java generics are implemented using type erasure: the generic information is discarded by the compiler after being used for type checking, so at runtime your class is effectively just
Hashing<Object, Object>
. That's why you can't do runtime checks based on a generic type.You can add an argument of type
Class<Key>
to the constructor, and the caller will have to pass the correct class object for the type being used as the key. For example, in aHashing<Integer, String>
, onlyInteger.class
will be accepted as the value of that argument, and you can use that for runtime type checking. The requirement to pass a the key's class object as a parameter makes the constructor call look a little awkward, though.如果您的代码有“key = null;”在instanceof测试之前,必然会抛出异常。
原因是 instancof 运算符检查所指向对象类型的引用,而不是它的声明方式。
您可以尝试使用这个简单的示例并相应地删除注释以查看差异:
此外,您可以在此处找到更多详细信息:
http://download.oracle.com/javase/tutorial/java/nutsandbolts/op2.html
希望它有帮助:)
Java 泛型的完整示例:
另请注意通过使用“Key extends Integer”,如果您传递的不是 Integer 的子类,则会在运行时抛出异常。此外,如果您正在使用检查它的 IDE,它将被标记为 GenTest 类的“类型不在范围内”。
Floats 和 Integer 都继承自 Number。因此,您可以“扩展 Number”,然后检查“instanceof Integer”或“instanceof Float”,具体取决于您希望如何在代码中使用它。
希望它有帮助:) 干杯!
If your code has "key = null;" right before the test of instanceof, then the Exception will necessarily be thrown.
The reason being that the instancof operator checks the reference of the type of object being pointed to and not how it is declared to be.
You can try with this simple example and remove the comments accordingly to see the difference:
Also, you can find out more details here:
http://download.oracle.com/javase/tutorial/java/nutsandbolts/op2.html
Hope it helps :)
Full blown example of Java Generics:
Also note that by having 'Key extends Integer', an exception will be thrown during Runtime if you pass that does not subclass Integer. Furthermore, if you're using and IDE that checks for it, it'll be flag as 'Type not within bound' of the GenTest Class.
Floats and Integer all inherit from Number. Thus you can 'extend Number' and then check for 'instanceof Integer' or 'instanceof Float' depending on how you want to use it in your code.
Hope it helps :) Cheers!
鉴于您的示例中的以下内容:
这没有任何意义:因为
K
是一个Type
,当该类专门化时可以将其设置为任何内容。我将名称从Key
更改为K
,以消除您可能认为Key
不代表Type
的困惑>。Type
名称的一般标准是大多数时候使用单个字符。如果您将其更改为,
这将是一个更通用的解决方案,但这也没有意义,因为
key
将始终是一种类型K
key
不能为null
,因为null
不属于任何Type
没有对
instanceof
检查周围的内容有更多上下文我不知道您的意图是什么。使用
instanceof
检查Generic
的Type
是一种代码味道,而且可能是错误的方法。看看这里
java.util.HashMap
实现解决了这个问题。只有两个地方使用
instanceof
,并且这些都是仅接受Object
且不类型安全的遗留方法。Given the following from your example:
This makes no sense: because
K
is aType
that can be set to anything when the class is specialized. I changed the name fromKey
toK
to remove confusion that you might have thatKey
isn't representing aType
. The general standard forType
names is to use single characters most of the time.if you change it to
that would be a more
Generic
solution, but that doesn't make sense either becausekey
will always be a type ofK
key
can't benull
becausenull
is not of anyType
Without having more context to what surrounds the
instanceof
check I don't know what your intention is.Checking the
Type
of aGeneric
withinstanceof
is a code smell, and probably the wrong approach regardless.Look here at how the
java.util.HashMap
implementation handles this problem.There is only two places where they use
instanceof
and those are both legacy methods that accept onlyObject
and are not typesafe.处理这个问题的方法是显式测试 null;例如
,郑重声明,那些回答说这与类型擦除有关的人是错误的。如果
Key
是一个明确的类或接口,您将得到完全相同的行为。(另一方面,如果代码表示
someObj instanceof Key
...,由于类型擦除问题,这将是一个编译错误。)The way to deal with this is to explicitly test for null; e.g.
For the record, those people who responded that this was something to do with type erasure are off base. You would get exactly the same behaviour if
Key
was a definite class or interface.(On the other hand, if the code had said
someObj instanceof Key
... that would be a compilation error because of the type erasure issue.)您需要一个 isInstance 方法,该方法是动态相当于
instanceof
运算符。例如,
编辑:
如果您想针对不同的类类型进行测试,请编写如下实用方法:
例如,
You need an isInstance method which is the dynamic equivalent of
instanceof
operator.For example,
Edit:
If you want to test against different class type, write a utility method like this:
For example,