instanceof java list_Java:Instanceof和泛型
在查看通用数据结构中的值索引之前,我想看看它是否甚至已被参数化为类型this的实例。
但是当我这样做时,Eclipse会抱怨:
@Override
public int indexOf(Object arg0) {
if (!(arg0 instanceof E)) {
return -1;
}
这是错误消息:
Cannot perform instanceof check against type parameter E. Use instead its erasure Object since generic type information will be erased at runtime
有什么更好的方法呢?
错误消息说明了一切。在运行时,该类型已消失,无法对其进行检查。
您可以通过为对象创建工厂来捕获它,如下所示:
public static < T > MyObject< T > createMyObject(Class< T > type) {
return new MyObject< T >(type);
}
然后在对象的构造函数中存储该类型,变量,以便您的方法如下所示:
if (arg0 != null && !(this.type.isAssignableFrom(arg0.getClass()))
{
return -1;
}
我不认为您想要Class.isAssignableFrom。
@Tom,我昨晚是从记忆中写这本书的,我将其固定为实际上通过了课程(duh!),但否则,我不明白您为什么不想要它(也许今天早上我需要更多咖啡,我只在我的第一杯咖啡上)。
我和汤姆在一起。你能澄清一下吗?使用isAssignableFrom()将是我的工作选择。也许我错过了什么?
@ luis,Toms评论可能意味着我应该使用isInstance()并传递实际的arg0参数。它具有避免空检查的优点。
我有类似的情况,但我无法完全理解答案。你能为像我这样的假人澄清一下吗?
@RubensMariuzzo可能有帮助:ralfebert.de/blog/java/isassignablefrom的重要部分是:isAssignableFrom告诉您泛型T是否是实例arg0的超类。
@ Emerald214,您不需要扩展该类,但是该类具有静态方法(这是静态工厂模式javaworld.com/javaworld/jw-06-2001/j1-01-sintes2.html)
使用泛型进行运行时类型检查的两个选项:
选项1-破坏您的构造函数
假设您要覆盖indexOf(...),并且只想检查类型以提高性能,以免自己遍历整个集合。
创建一个肮脏的构造函数,如下所示:
public MyCollection< T >(Class< T > t) {
this.t = t;
}
然后,您可以使用isAssignableFrom检查类型。
public int indexOf(Object o) {
if (
o != null &&
!t.isAssignableFrom(o.getClass())
) return -1;
//...
每次实例化对象时,都必须重复一次:
new MyCollection(Apples.class);
您可能会认为这不值得。在ArrayList.indexOf(...)的实现中,它们不检查类型是否匹配。
选项2-让它失败
如果您需要使用需要未知类型的抽象方法,那么您真正想要的只是让编译器停止对instanceof的抱怨。如果您有这样的方法:
protected abstract void abstractMethod(T element);
您可以像这样使用它:
public int indexOf(Object o) {
try {
abstractMethod((T) o);
} catch (ClassCastException e) {
//...
您正在将对象强制转换为T(您的泛型类型),只是为了欺骗编译器。您的强制转换在运行时不执行任何操作,但是当您尝试将错误类型的对象传递给抽象方法时,您仍然会收到ClassCastException。
注意1:如果您在抽象方法中执行其他未经检查的强制转换,则ClassCastExceptions将在此处被捕获。那可能是好事也可能是坏事,因此请仔细考虑。
注意2:使用instanceof时,您将获得免费的空检查。由于您无法使用它,因此您可能需要裸手检查null。
旧帖子,但是做普通instanceOf检查的一种简单方法。
public static < T > boolean isInstanceOf(Class< T > clazz, Class< T > targetClass) {
return clazz.isInstance(targetClass);
}
目前尚不清楚您在这里实际做出了什么贡献。
如果您的类扩展了具有通用参数的类,则您还可以在运行时通过反射来获取它,然后将其用于比较,即
class YourClass extends SomeOtherClass
{
private Class< ? > clazz;
public Class< ? > getParameterizedClass()
{
if(clazz == null)
{
ParameterizedType pt = (ParameterizedType)this.getClass().getGenericSuperclass();
clazz = (Class< ? >)pt.getActualTypeArguments()[0];
}
return clazz;
}
}
在上述情况下,在运行时将从getParameterizedClass()中获取String.class并进行缓存,因此在进行多次检查时不会有任何反射开销。请注意,您可以从ParameterizedType.getActualTypeArguments()方法中通过索引获取其他参数化类型。
我遇到了同样的问题,这是我的解决方案(非常谦虚,@ george:这一次编译并正在工作……)。
我的探针位于实现Observer的抽象类内部。
Observable可以通过Object类触发update(...)方法,该方法可以是任何种类的Object。
我只想处理T类型的对象
解决方案是将类传递给构造函数,以便能够在运行时比较类型。
public abstract class AbstractOne< T > implements Observer {
private Class< T > tClass;
public AbstractOne(Class< T > clazz) {
tClass = clazz;
}
@Override
public void update(Observable o, Object arg) {
if (tClass.isInstance(arg)) {
// Here I am, arg has the type T
foo((T) arg);
}
}
public abstract foo(T t);
}
对于实现,我们只需要将Class传递给构造函数
public class OneImpl extends AbstractOne {
public OneImpl() {
super(Rule.class);
}
@Override
public void foo(Rule t){
}
}
否则您可能会尝试将E转换为E失败,例如
public int indexOf(Object arg0){
try{
E test=(E)arg0;
return doStuff(test);
}catch(ClassCastException e){
return -1;
}
}
+1实用的非工程化解决方案,可轻松进行检查!我希望我能投票更多
这不会工作。 E在运行时被擦除,因此强制类型转换不会失败,您只会收到编译器警告。
对象的运行时类型是要过滤的相对任意的条件。我建议远离您的收藏夹。只需将您的集合委托给构造中传递的过滤器即可实现。
public interface FilterObject {
boolean isAllowed(Object obj);
}
public class FilterOptimizedList implements List {
private final FilterObject filter;
...
public FilterOptimizedList(FilterObject filter) {
if (filter == null) {
throw NullPointerException();
}
this.filter = filter;
}
...
public int indexOf(Object obj) {
if (!filter.isAllows(obj)) {
return -1;
}
...
}
...
}
final List longStrs = new FilterOptimizedList(
new FilterObject() { public boolean isAllowed(Object obj) {
if (obj == null) {
return true;
} else if (obj instanceof String) {
String str = (String)str;
return str.length() > = 4;
} else {
return false;
}
}}
);
(尽管如果您使用的是Comparator或类似版本,则可能要检查实例类型。)
从技术上讲,您不必这样做,这就是泛型的重点,因此您可以进行编译类型检查:
public int indexOf(E arg0) {
...
}
但是如果您有一个类层次结构,那么@Override可能是一个问题。否则,请参见Yishai的答案。
是的,List接口要求该函数采用对象参数。
您实施清单?为什么不实施List ?
(例如,参见ArrayList的声明:java.sun.com/j2se/1.5.0/docs/api/java/util/ArrayList.html)
@Rosarch:List接口的indexOf()方法不需要给定的参数与您要查找的对象具有相同的类型。它只是必须等于.equals(),并且不同类型的对象可以彼此等于.equals()。这与remove()方法的问题相同,请参见:stackoverflow.com/questions/104799/
[[[sheepishly]]]没关系,我认为indexOf()要求E作为参数而不是Object。 (他们为什么这样做?!?!)
@Jason基本上是因为它会破坏不需要有效类型转换的完全有效的代码。另外,由于泛型不是协变的,因此即使使用indexOf()实际上返回一个实数索引(对象),您也会陷入一些带有类型参数的极端情况(例如,列表本身具有类型参数的列表)在列表中,但编译器无法让您看到它)。
instanceof java list_Java:Instanceof和泛型相关推荐
- java中instanceof的用法和实战
https://blog.csdn.net/qq_37192800/article/details/78861387 https://www.cnblogs.com/zjxynq/p/5882756. ...
- Java关键字——instanceof
instanceof 严格来说是Java中的一个双目运算符,用来测试一个对象是否为一个类的实例,用法为: 1 boolean result = obj instanceof Class 其中 obj ...
- 深入Java关键字instanceof
深入Java关键字instanceof instanceof关键字用于判断一个引用类型变量所指向的对象是否是一个类(或接口.抽象类.父类)的实例. 举个例子: public interface ...
- java is instance of_详谈Java中instanceof和isInstance的区别
一次性搞定instanceof和isInstance,instanceof和isInstance长的非常像,用法也很类似,先看看这两个的用法: obj.instanceof(class) 也就是说这个 ...
- instanceof java 报错_java中instanceof怎么理解?java中instanc 爱问知识人
1.用法表达式 result = object instanceof class result:布尔类型. object:必选项.任意对象表达式. class:必选项.任 ...
- 详解Java操作符 instanceof
1.简述 "instanceof" (1)instanceof 是什么? instanceof 是 Java 运算符中的一个二元操作符,类似于 ==,>,< 等. 同时 ...
- 12 java中instanceof运算符的意义和用法
java中instanceof运算符的意义和用法 instanceof运算符是用来在运行时指出对象是否是特定类的一个实例.instanceof通过返回一个布尔值来标识该对象是否为特定类或者它的子类的一 ...
- java中 instanceof 的用法
引言 instanceof 概念在多态中引出,因为在多态发生时,子类只能调用父类中的方法(编译时类型的方法),而子类自己独有的方法(运行时类型的方法)无法调用,如果强制调用的话就需要向下转型,语法和基 ...
- Java中instanceof与getClass的区别
在比较一个类和另一个类是否属于同一个类实例的时候,通常可以采用instanceof和getClass两种方法比较两者是否相等来判断,但是两者在判断上面是有差别的,下面通过代码说明: public cl ...
最新文章
- ArcObject开发时,axtoolbarcontrol中一些添加的按钮是灰色的问题
- 视觉SLAM总结——LSD SLAM中关键知识点总结
- DeepLearning.AI第一部分第三周、 浅层神经网络(Shallow neural networks)
- javaWEB学习之filter
- 玩转oracle 11g(5):表空间的作用
- 查看计算机上隐藏用户,隐藏或显示 InetOrgPerson 对象类 - Windows Server | Microsoft Docs...
- 求多个数的最小公倍数
- double operator[](int i)_请谨慎使用float和double
- 建筑系学生怎么系统地学 Photoshop、CAD 之类软件?
- 使用rsync+inotify配置触发式(实时)远程同步
- JAVA项目-学生成绩管理系统
- 基于Java的OA系统的设计与实现
- PHP+MYSQL+SCWS 做自己的站内搜索引擎
- android 那个桌面好,Hola桌面 可能是最好用的安卓手机桌面
- 解决Ubuntu 22.04 LTS作为nfs server时根文件系统挂载失败的问题
- 洗衣机程序c语言代码大全,全自动洗衣机控制器设计的单片机代码
- JS(JavaScript)详解
- 我的星座图 php,星座图映射
- 竖流式沉淀池集水槽设计计算_各类沉淀池的设计要点都在这了!(建议收藏)...
- 地图下面的标尺是什么意思_机油标尺怎么看图解,汽车机油标尺正常位置示意图...
热门文章
- pythonsocket数据对接_python socket通信 网站之间数据交流
- php cgi路径解析,php.ini中的cgi.fix_pathinfo选项
- linux2.6添加新硬盘,Linux_TurboLinux11添加新硬盘方法,一.Linux的硬盘识别2.6 kernel - phpStudy...
- android java 延时函数,如何在Android中设置文本之间的延迟
- python快速入门课堂笔记_Python 快速入门笔记(10):文件及目录操作
- mongodb 时间戳 java_Java将日期类型Date时间戳转换为MongoDB的时间类型数据
- 机器学习系列(一)感知器分类算法
- 超全!Python获取某一日期是“星期几”的6种方法!
- Leetcode惊现马化腾每天刷题?为啥大佬都这么努力?代码你打算写到几岁?
- 程序员,你喜欢抽哪种香烟?(python数据分析)