背景故事

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

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

牵线之牛刀小试

如何判断是不是谁的谁?java有一个instanceof操作符(关系操作符)可以做这件事。

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

打印出结果true

可是如果你的哪个谁不存在呢?请看代码:

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

很多人都会异口同声的说

false

你答对了。

JSL-15.20.2规定

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("匹配不成功");
}
}
}

不少人会说:“匹配不成功”

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

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

我又不是你的谁--java instanceof操作符用法揭秘的更多相关文章

  1. Java-Runoob-高级教程-实例-方法:07. Java 实例 – instanceOf 关键字用法

    ylbtech-Java-Runoob-高级教程-实例-方法:07. Java 实例 – instanceOf 关键字用法 1.返回顶部 1. Java 实例 - instanceof 关键字用法   ...

  2. Java 实例 - instanceof 关键字用法

    Java 实例 - instanceof 关键字用法 instanceof 是 Java 的一个二元操作符,类似于 ==,>,< 等操作符. instanceof 是 Java 的保留关键 ...

  3. C++ 'dynamic_cast' and Java 'instanceof' 使用对比

    在Java中,如果A是基类,B是A的派生类,那么instanceof可以用来判断一个实例对象是A还是B,相当于一个二元操作符,但与==, >, < 不同的是,它是由字母组成,是Java的保 ...

  4. Java Instanceof

    Java Instanceof Instanceof是一个非常简单的运算符,前一个操作通常是一个引用类型的变量,后一个操作数通常是一个类(也可以是接口,可以把接口理解成一种特殊的类),它用于判断前面的 ...

  5. [Java学习] Java instanceof 运算符

    多态性带来了一个问题,就是如何判断一个变量所实际引用的对象的类型 . C++使用runtime-type information(RTTI),Java 使用 instanceof 操作符. insta ...

  6. java基础-操作符

    浏览以下内容前,请点击并阅读 声明 定义:操作符是一种能够对一个,两个或三个操作对象执行特定的操作,并返回一个结果的特定符号. java中操作符的种类和优先级如下表所示,除了赋值运算,所有二元操作符运 ...

  7. 设计模式 - 观察者模式(Observer Pattern) Java内置 用法

    观察者模式(Observer Pattern) Java内置 用法 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26601659 ...

  8. 使用instanceof操作符判断对象类型及方法的重载

    学习内容: 一.使用instanceof操作符判断对象类型 1.instanceof操作符可以判断一个实例对象是否属于一个类. 语法:对象名 instanceof 类名 2.使用instanceof表 ...

  9. JAVA的continue用法

    JAVA的continue用法: public class test{ public static void main(String [] args){  for(int i=0;i<=10;i ...

随机推荐

  1. 计蒜客 ACM训练联盟周赛 第一场 从零开始的神棍之路 暴力dfs

    题目描述 ggwdwsbs最近被Zeratul和Kyurem拉入了日本麻将的坑.现在,ggwdwsbs有13张牌,Kyurem又打了一张,加起来有14张牌.ggwdwsbs想拜托你帮他判断一下,这14 ...

  2. go Server示例

    示例1: package main import ( "fmt" "log" "net/http" "time" ) f ...

  3. Python爬虫之小试牛刀——使用Python抓取百度街景图像

    之前用.Net做过一些自动化爬虫程序,听大牛们说使用python来写爬虫更便捷,按捺不住抽空试了一把,使用Python抓取百度街景影像. 这两天,武汉迎来了一个德国总理默克尔这位大人物,又刷了一把武汉 ...

  4. 【LeetCode】334#递增的三元子序列

    题目描述 给定一个未排序的数组,判断这个数组中是否存在长度为 3 的递增子序列. 数学表达式如下: 如果存在这样的 i, j, k, 且满足 0 ≤ i < j < k ≤ n-1, 使得 ...

  5. Kafka服务端之网络连接源码分析

    #### 简介 上次我们通过分析KafkaProducer的源码了解了生产端的主要流程,今天学习下服务端的网络层主要做了什么,先看下 KafkaServer的整体架构图 ![file](https:/ ...

  6. 用button 属性来保存字符串地址

    我用到for循环创建button  通过点击不同的按钮拿到每个button对应的链接地址,因为button的个数也是通过后台数据返回.上代码: //保存到数组 _array = [Article mj ...

  7. 第四周课程总结&试验报告(二)

    实验二 Java简单类与对象 实验目的 掌握类的定义,熟悉属性.构造函数.方法的作用,掌握用类作为类型声明变量和方法返回值: 理解类和对象的区别,掌握构造函数的使用,熟悉通过对象名引用实例的方法和属性 ...

  8. Linux 笔记 - 第六章 Linux 磁盘管理

    博客地址:http://www.moonxy.com 一.前言 1.1 硬盘 硬盘一般分为 IDE 硬盘.SCSI 硬盘和 SATA 硬盘.在 Linux 中,IDE 接口的设备被称为 hd,SCSI ...

  9. CentOS7 安装 Pure-ftpd

    博客地址:http://www.moonxy.com 一.摘要 FTP 是 File Transfer Protocol(文件传输协议)的英文简称,而中文简称为"文传协议”.用于Intern ...

  10. 你好,C语言

    对于我来说,C语言就和陌生人一样,对他完全不了解,更不要提什么C++了,这就要我主动和他打招呼,深入认识了解它了哈.目前对于C语言的理解,只知道他的的功强大,能操作硬件,编写各类驱动,强悍的LINUX ...