正常方式:引入需要的“包类”名称-->通过new实例化-->取得实例化对象
反射方式:实例化对象-->getClass()方法-->得到完整的“包类”名称
对象照镜子后可以得到信息:某个类的属性、方法和构造器、某个类到底实现了哪些接口。对于每个类而言,JRE都为其保留了一个不变的Class对象。一个Class对象包含了特定某个结构(class/interface/enum/annotation/primitive type/void/[])的有关信息。
方法名 | 功能说明 |
---|---|
static ClassforName(String name) | 返回指定类名name的Class对象 |
Object newInstance() | 调用缺省构造函数,返回Class对象的一个实例 |
getName() | 返回此Class对象所表示的实体(类,接口,数组类或void)的名称。 |
Class getSuperClass() | 返回当前Class对象的父类的Class对象 |
Class[] getinterfaces() | 获取当前Class对象的接口 |
ClassLoader getClassLoader() | 返回该类的类加载器 |
Constructor[] getConstructors() | 返回一个包含某些Constructor对象的数组 |
Method getMothed(String name,Class.. T) | 返回一个Method对象,此对象的形参类型为paramType |
Field[] getDeclaredFields() | 返回Field对象的一个数组 |
若已知具体的类,通过类的class属性获取,该方法最为安全可靠,程序性能最高。
Class clazz = Person.class;
已知某个类的实例,调用该实例的getClass()方法获取Class对象
Class clazz = person.getClass();
已知一个类的全类名,且该类再类路径下,可通过Class类的静态方法forName()获取,可能抛出ClassNotFoundException
Class clazz = Class.forName("demo01.Student");
内置基本数据类型可以直接用包装类类名.Type;
可以利用ClassLoader
package com.cnblogs.reflection; /* 本类用作测试Class类的获取 */ public class TestReflection1 { public static void main(String[] args) throws ClassNotFoundException { Person per = new Student(); System.out.println("这人是个" + per.name);//这是一个学生 //方法一 Class c1 = per.getClass(); System.out.println(c1.hashCode());//1956725890 //方法二 Class c2 = Class.forName("com.cnblogs.reflection.Student"); System.out.println(c2.hashCode());//1956725890 //方法三 Class c3 = Student.class; System.out.println(c3.hashCode());//1956725890 //方法四 Class c4 = Integer.TYPE; System.out.println(c4);//int //获得父类类型 Class c5 = c1.getSuperclass(); System.out.println(c5);//class com.cnblogs.reflection.Person } } class Person{ public String name; public Person() { } public Person(String name) { this.name = name; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + '}'; } } class Student extends Person{ public Student() { this.name = "学生"; } } class Teacher extends Person{ public Teacher(String name) { this.name = "老师"; } }
加载:将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区的运行时数据结构,然后生成一个代表这个类的java.lang.Class对象。
链接:将Java类的二进制代码合并到JVM的运行状态之中的过程
初始化:
类的主动引用(一定会发生类的初始化)
类的被动引用(不会发生类的初始化)
类加载的作用:将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区的运行时数据结构,然后再堆中生成一个代表这个类的java.lang.Class对象,作为方法区中类数据的访问入口
类缓存:标准的JavaSE类加载器可以按要求查找类,但一旦某个类被加载到类加载器中,它将维持加载(缓存)一段时间。不过JVM垃圾回收机制可以回收这些Class对象
类加载器作用是用来把类(class)装载进内存的。JVM规范定义了如下类型的类的加载器