Java中对象的类型判断
2015-12-12 11:12
134 查看
instanceof
判断一个对象是否是一个类的实例,用Java中自带的关键字instanceof似乎可以做到(仅从关键字名称上可以猜测出),如下面的代码:
[code]public static void main(String args[]) { Object i = new Integer(7); if (i instanceof Number) { System.out.println("Integer i is a Number"); } else { System.out.println("Integer i isn't a Number"); } if (i instanceof Serializable) { System.out.println("Integer i is a Serializable"); } else { System.out.println("Integer i isn't a Serializable"); } if (i instanceof Integer) { System.out.println("Integer i is an Integer"); } else { System.out.println("Integer i isn't an Integer"); } if (i instanceof Float) { System.out.println("Integer i is a Float"); } else { System.out.println("Integer i isn't a Float"); } }
类定义部分为:
[code]public abstract class Number implements java.io.Serializable {} public final class Integer extends Number implements Comparable<Integer> {}
运行结果:
Console Output :
Integer i is a Number
Integer i is a Serializable
Integer i is an Integer
Integer i isn’t a Float
然而好像和预期的不太一样,能看出,使用该关键字不仅可以判断对象是否是某个类的实例,甚至连该类继承的基类和实现的接口也都能够被识别为true,虽然这样在逻辑上没有任何问题,是可以把Integer当做一个Number来看来用,也当做一个
Serializable来看来用,但是这样返回的结果就没有针对性了,太过于模糊,我们如果仅仅需要
i instanceof Integer为true该怎么做呢?
Class.equals
还好在Java有一个叫做Class的类,这是一个用来描述类信息的类,我们如果要精确判断一个对象是否是具体的一个类的实例,可以这么做:
[code]public static void main(String args[]) { Object i = new Integer(7); if (i.getClass().equals(Number.class)) { System.out.println("Integer i is a Number"); } else { System.out.println("Integer i isn't a Number"); } if (i.getClass().equals(Serializable.class)) { System.out.println("Integer i is a Serializable"); } else { System.out.println("Integer i isn't a Serializable"); } if (i.getClass().equals(Integer.class)) { System.out.println("Integer i is an Integer"); } else { System.out.println("Integer i isn't an Integer"); } if (i.getClass().equals(Float.class)) { System.out.println("Integer i is a Float"); } else { System.out.println("Integer i isn't a Float"); } }
运行结果:
Console Output :
Integer i isn’t a Number
Integer i isn’t a Serializable
Integer i is an Integer
Integer i isn’t a Float
这样就能达到我们的目的了,从
equals函数上就可以看出,上述代码是比较两个类的类信息是否一致,全相等,这其中不考虑继承实现的关系,当且仅当该对象是要比较的那个类的实例才返回true。
但是我们查看源代码的时候可以发现,其equals函数用的就是Object中的方法,没有重写:
[code]public boolean equals(Object obj) { return (this == obj); }
这就很奇怪了,如果是只有比较两个Class实例化对象的引用是否是指向同一个对象的话,这样返回的是true,也就是说,
i.getClass()和
Integer.class获取到的是同一个对象?!
可是这就是事实:
无论我们用Integer实例化多少个对象,当我们调用
getClass()方法时返回的总是同一个对象,还有
Integer.class返回的也是它。
所以上面的
i.getClass().equals(Number.class)改写为
i.getClass == Number.class也是成立的。
事实上每个类都会有且只有一个对应Class的对象,我们正是用这个Class对象来实例化该类的所有对象的,也就是Class中的
newInstance()方法。
其实也可以理解,既然是同一个类的信息,无论有多少个对象,他们的类信息也都是一样的,所以也就没有必要实例化那么多Class对象来存放
PS:
a instanceof b的结果和
b.class.isInstance(a)的结果是一致的,可以实现相同的功能,完全等价。
更加全面的类型信息
这样看起来就好很多了,可是我们如果想获取更多有关于对象i的类型信息呢?比如获取它的基类呢?
同样还是使用
Class的对象,它里面提供了很多方法如:
获取父类的类型信息:getSuperclass()
获取实现的接口的类型信息:getInterfaces()
获取类型名称:getName()、getSimpleName()、getCanonicalName()
相关文章推荐
- java中的this与super的区别
- springmvc 接收json对象的两种方式
- K-Means 算法(Java)
- mac eclipse快捷键整理
- 二叉树非递归遍历实现-java版本
- 教你如何精通Struts:Tiles框架
- Java自增问题:x=x++
- Java中byte与16进制字符串的互相转换
- eclipse自动生成类图
- java中的类总结
- eclipse常用设置(字体设置、jdk版本更改、编码更改)
- java初始化技巧
- JDK错误
- JDK错误
- TCL脚本在Eclipse开发的环境搭建(图解)。
- 【菜鸟学Java】5:“徒手”创建一个Web应用
- java语言基础概述
- 枚举类型的单例模式(java)五种
- SpringMVC+Spring+Mybatis+Maven整合
- [java]2、校验手机号纯数字8-13位