Java 类型

类型描述

Java中有两大类型,原生类型和对象类型
不管哪种,都可以用.class的方式获取类型对象,比如Object.class,int.class
类型是用Class泛型类表示,泛型参数就是实际的类

类型间关系


Class类提供两个方法判断类型关系

Class.java
1
2
public native boolean isInstance(Object obj);
public native boolean isAssignableFrom(Class<?> cls);
  • 类型和实例之间
    有关键字instanceof等同于类方法
Sample
1
2
Integer.valueOf(1) instanceof Number;  //true
Number.class.isInstance(Integer.valueOf(1)); //true

尽管null可以认为是任何类型,但是不会通过instanceof判定
因此通过判定后可以放心的后续使用,不必担心是null

1
null instanceof String  //false
  • 类型之间
    判断一个类型是不是一个类的(子)类型,使用isAssignableFrom,检测能否接受赋值
1
2
Class<?> clazz = Integer.class;
boolean isSubType = Number.class.isAssignableFrom(clazz); //true

对象类型


对象类型的实例还可以调用方法获取

Object.java
1
public final native Class<?> getClass();

判断一个对象是不是一个(子)类的实例,使用关键字instanceof

Sample
1
2
Object obj = Integer.valueOf(1);
boolean isNumber = obj instanceof Number; //true

或者使用方法

Sample
1
Number.class.isInstance(obj);

枚举是一种特殊的对象,判断是否枚举可以用isEnum

Sample
1
2
Class<?> clazz = Month.class;
boolean isEnum = clazz.isEnum(); //true

原生类型


原生可以通过isPrimitive区分
原生类型包含9种,boolean,char,byte,short,int,long,float,double,void

Sample
1
2
Class<?> clazz = int.class;
boolean isPrimitive = clazz.isPrimitive(); //true

数值原生类型的Class类型还可以从包装类的TYPE获得

Sample
1
System.out.println(Integer.TYPE == int.class); //true

原生类型是不能直接使用instanceof的,但是可以直接赋给Object对象,利用自动装箱机制

Sample
1
2
Object obj = 1;
boolean isNumber = obj instanceof Number; //true

类型层面并不包含拆装箱机制,原生类型和包装类在类型层面是互不相容的

Sample
1
2
boolean canPrimitiveToObject = Integer.class.isAssignableFrom(int.class); //false
boolean canObjectToPrimitive = int.class.isAssignableFrom(Integer.class); //false

类型名称


Class类提供三种方法获得类名表示

  • getName: JVM内部类型名
  • getCanonicalName: 包含包名的全限定名
  • getSimpleName: 不包含包名
Sample
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package test;

public class Test {
class Inner {
}

public static void main(String[] args) throws InterruptedException {
System.out.println(Test.class.getName()); // test.Test
System.out.println(Test.class.getCanonicalName()); // test.Test
System.out.println(Test.class.getSimpleName()); // Test

System.out.println(Test[].class.getName()); // [Ltest.Test;
System.out.println(Test[].class.getCanonicalName()); // test.Test[]
System.out.println(Test[].class.getSimpleName()); // Test[]

System.out.println(Test.Inner.class.getName()); // test.Test$Inner
System.out.println(Test.Inner.class.getCanonicalName()); // test.Test.Inner
System.out.println(Test.Inner.class.getSimpleName()); // Inner
}
}