Java里面的类型是一个引用或者一个基本类型,类、枚举、或者数组都是继承于java.lang.Object,它们和接口一样都是引用类型,对于这些类型,JVM提供了方式可以在运行中获取对象对应类型,也就是它属于哪个Class。java.lang.class也提供了创建Class和Class对应的对象的方式。
本文讲一下目前有哪儿些方式可以获取到一个类(Class)。
所有的反射操作的切入点都是java.lang.Class,这也印证了Java是面向对象编程语言,在包java.lang.reflect中,除了 java.lang.reflect.ReflectPermission之外都没有public的构造方法,为了得到这些类,需要在java.lang.Class上调用对应的方法。
Object.getClass()
引用对象可以调用getClass()方法获取到它的类。
Class c = "foo".getClass();
System.out.println(c);//class java.lang.String
Class c = System.out.getClass();
System.out.println(c);//class java.io.PrintStream
byte[] bytes = new byte[1024];
Class c = bytes.getClass();
System.out.println(c);//class [B
Set<String> s = new HashSet<String>();
Class c = s.getClass();
System.out.println(c);//class java.util.HashSet
这里要注意是的通过接口的引用调用其getClass()方法是返回引用对象的真正类,而不是接口的名称。
数组对象的Class会以“[”开头。
.class
.class的方式是使用Class本身调用.class获取。
比如:
boolean b;
Class c = b.getClass(); // compile-time error
Class c = boolean.class; // boolean
Class c = java.io.PrintStream.class;//class java.io.PrintStream
Class c = int[][][].class;//class [[[I
Class.forName()
forName()是声明异常类方法,如果找不到这个类会抛出java.lang.ClassNotFoundException异常。
比如:
Class c = Class.forName("com.duke.MyLocaleServiceProvider");
Exception in thread "main" java.lang.ClassNotFoundException: com.duke.MyLocaleServiceProvider
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at reflect.Main.main(Main.java:8)
如果能找到类:
Class cDoubleArray = Class.forName("[D");
Class cStringArray = Class.forName("[[Ljava.lang.String;");
基础类型包装类的TYPE属性
基础类型的包装类都有一个TYPE属性,和包装类的Class是一样的。
Class c = Double.TYPE;
Class c = Void.TYPE;
其他方式
Class.getSuperclass()
获得当前类的父类。
Class.getClasses()
返回当前类的内部定义的类、接口、枚举类型。
Class.getDeclaredClasses()
返回当前类中显式声明的接口、枚举类型。
引申
Class.getDeclaringClass()方法可以引申出另外几个方法:
java.lang.reflect.Field.getDeclaringClass()
java.lang.reflect.Method.getDeclaringClass()
java.lang.reflect.Constructor.getDeclaringClass()
作用和Class.getDeclaredClasses()一样,只是作用于的类型不一样,分别是Field、Method、Constructor。
Class.getEnclosingClass()
返回当前类的封闭类,也就是包含这个类的类,比如:
Class c = Thread.State.class.getEnclosingClass();
System.out.println(c);//class java.lang.Thread