首先,梳理一一下类型系统的基础概念:问:什么是强 / 弱类型语言?:
答:强 / 弱类型语言的区分,关键在于变量是否**(倾向于)**类型兼容。例如,Java 是强类型语言,变量有固定的类型,以下代码在 Java 中是非法的:
public class MyRunnable {
public abstract void run();
}
// 编译错误:Incompatible types
java.lang.Runnable runnable = new MyRunnable() {
@Override
public void run() {
}
}
runnable.run(); // X
相对地,JavaScript 是弱类型语言,一个变量没有固定的类型,允许接收不同类型的值:
function MyRunnable(){
this.run = function(){
}
}
function Runnable(){
this.run = function(){
}
}
var ss = new MyRunnable();
ss.run(); // 只要对象有相同方法签名的方法即可
ss = new Runnable();
ss.run();
更具体地描述,Java的强类型特性体现为:**变量仅允许接收相同类型或子类型的值**。嗯(黑人问号脸)?和你的理解一致吗?请看下面代码,哪一行是有问题的:
注意,请读者假设 1 ~ 4 号代码是单独运行的
long numL = 1L;
int numI = 0;
numL = numI; // 1
numI = (int)numL; // 2
Integer integer = new Integer(0);
Object obj = new Object();
integer = (Integer) obj; // 3 ClassCastException
obj = integer; // 4
在这里,第 3 句代码会发生运行时异常,结论:1:调用字节码指令 i2l 将 int 值转换为 long 值(此时,numL 变量接收的是相同类型的值,命题正确)
2:调用字节码指令 l2i,将 long 值转换为 int 值(此时,numI 变量接收的是相同类型的值,命题正确)
3:调用字节码指令 checkcast ,发现 obj 变量的值不是 Integer 类型,抛出 ClassCastException(此时,Integer 变量不允许接收 Object 对象,命题正确)
4:integer 变量的值是 obj 变量的子类型,可以接收(此时,Object 变量允许接收 Integer 对象,命题正确)
用一张图概括一下:Java | 反射:在运行时访问类型信息(含 Kotlin)www.jianshu.com