我又不是你的谁--java instanceof操做符用法揭秘

背景故事html

《曾经最美》是朱铭捷演唱的一首歌曲,由陈佳明填词,叶良俊谱曲,是电视剧《水晶之恋》的主题曲。歌曲时长4分28秒。 歌曲歌词:java

  • 看不穿你的眼睛
  • 藏有多少悲和喜
  • 像冰雪细腻又如此透明
  • 仿佛片刻就要老去
  • 整个城市的孤寂
  • 不止一个你
  • 只能远远的
  • 想像慰藉咱们之间的距离
  • 我又不是你的谁
  • 不能带给你安慰
  • 忍心你枯萎凋零的玫瑰
  • 仿佛但愿化成灰
  • 要不是痛彻心扉
  • 谁又记得谁
  • 只是云和月
  • 相互觉得是彼此的盈缺
  • 不能哭喊已破碎
  • 曾经的最美
  • 独自一我的熟悉的街
  • 别问你在想谁
  • 不去追悔已憔悴
  • 爱过的机会
  • 真实已粉碎人事已非
  • 还有什么最难得
  • 我又不是你的谁
  • 不能带给你安慰
  • 忍心你枯萎凋零的玫瑰
  • 仿佛但愿化成灰
  • 要不是痛彻心扉
  • 谁又记得谁
  • 只是云和月
  • 相互觉得是彼此的盈缺
  • 不能哭喊已破碎
  • 曾经的最美
  • 独自一我的熟悉的街
  • 别问你在想谁
  • 不去追悔已粉碎
  • 爱过的机会
  • 真实已粉碎人事已非
  • 还有什么最难得
  • 不能哭喊已破碎
  • 曾经的最美
  • 独自一我的熟悉的街
  • 别问你在想谁
  • 不去追悔已憔悴
  • 爱过的机会
  • 真实已粉碎人事已非
  • 还有什么最难得

牵线之牛刀小试express

如何判断是否是谁的谁?java有一个instanceof操做符(关系操做符)能够作这件事。oracle

    public static void main(String[] args) {
        String s = "Hello World!";
        System.out.println(s instanceof String);
    }

打印出结果truethis

但是若是你的哪一个谁不存在呢?请看代码:atom

    public static void main(String[] args) {
        String s = null;
        System.out.println(s instanceof String);
    }

不少人都会异口同声的说spa

falsecode

我又不是你的谁--java instanceof操做符用法揭秘

 

你答对了。htm

JSL-15.20.2规定blog

At run time, the result of the instanceof operator is true if the value of the RelationalExpression is not null and the reference could be cast to the ReferenceType without raising a ClassCastException. Otherwise the result is false.

牵线之乱点鸳鸯谱

若是没有任何关系的两个类使用instanceof会如何?

class Point { int x, y; }
class Element { int atomicNumber; }

public class InstanceofTest {
    public static void main(String[] args) {
 Point p = new Point();
 Element e = new Element();
 if (e instanceof Point) { 
 System.out.println("匹配成功!");
 }else {
     System.out.println("匹配不成功");
 }
    }
}

很多人会说:“匹配不成功”

我又不是你的谁--java instanceof操做符用法揭秘

 

抱歉,你又掉进坑里了,这个会报编译错误

我又不是你的谁--java instanceof操做符用法揭秘

 

JSL-15.20.2规定

The type of the RelationalExpression operand of the instanceof operator must be a reference type or the null type, or a compile-time error occurs.

It is a compile-time error if the ReferenceType mentioned after the instanceof operator does not denote a reference type that is reifiable (§4.7).

If a cast of the RelationalExpression to the ReferenceType would be rejected as a compile-time error (§15.16), then the instanceof relational expression likewise produces a compile-time error. In such a situation, the result of the instanceof expression could never be true.

固然,cast也会是编译错误

class Point { int x, y; }
class Element { int atomicNumber; }
public class InstanceofTest {
    public static void main(String[] args) {
 Point p = new Point();
 Element e = new Element();
 p = (Point)e; // compile-time error
    }
}

牵线之暗藏玄机

编译器并非万能的,并不能检测出全部问题,看下面:

class Point { int x, y; }
class Element { int atomicNumber; }
public class InstanceofTest {
    public static void main(String[] args) {
 Point p = new Point();
 //Element e = new Element();
 p = (Point) new Object();
 System.out.println(p instanceof Point);
    }
}

猛一看,没事问题,编译也没有问题,但是运行时报错

Exception in thread "main" java.lang.ClassCastException: java.lang.Object cannot be cast to Point

上面的程序展现了当要被转型的表达式的静态类型是转型类型的超类时,转型操做符的行为。与instanceof 操做相同,若是在一个转型操做中的两种类型都是类,那么其中一个必须是另外一个的子类型。尽管对咱们来讲,这个转

型很显然会失败,可是类型系统尚未强大到可以洞悉表达式new Object()的运行期类型不多是Point的一个子类型。所以,该程序将在运行期抛出ClassCastException 异常。

牵线之竞争激烈

关系操做符instanceof可不是市场上惟一的选择,另一个背靠大山的家伙要注意了

Class 的方法

booleanisInstance(Object obj)

Determines if the specified Object is assignment-compatible with the object represented by this Class.

那么何时该用instanceof 何时该用isInstance呢

个人理解是

instanceof偏向于比较class之间

isInstance偏向于比较instance和class之间

stackoverflow也有此问题的解答:

I take that to mean that isInstance() is primarily intended for use in code dealing with type reflection at runtime. In particular, I would say that it exists to handle cases where you might not know in advance the type(s) of class(es) that you want to check for membership of in advance (rare though those cases probably are).

For instance, you can use it to write a method that checks to see if two arbitrarily typed objects are assignment-compatible, like:

public boolean areObjectsAssignable(Object left, Object right) {
 return left.getClass().isInstance(right);
} 

In general, I'd say that using instanceof should be preferred whenever you know the kind of class you want to check against in advance. In those very rare cases where you do not, use isInstance() instead.

 

参考资料

【1】https://docs.oracle.com/javase/specs/jls/se12/html/jls-15.html#jls-15.20.2

【2】java解惑

【3】https://stackoverflow.com/questions/8692214/when-to-use-class-isinstance-when-to-use-instanceof-operator

相关文章
相关标签/搜索