主要从这几个方面来介绍:
- 什么是反射?
- 理解Class类。
- 类加载机制
- 通过反射的操作类方法和属性
- 动态代理
1.反射机制
反射机制是指Java在运行时,可以获取任意一个类的属性和方法,任意一个对象可以调用它的任意一个方法和属性。这种动态获取信息和调用对象方法的功能称作是Java反射机制。
2.理解Class类
- Class类是什么?
- Class类就是用来描述类的类。也就是说它是一个类。
-
//Class的定义 public final class Class<T> implements java.io.Serializable, java.lang.reflect.GenericDeclaration, java.lang.reflect.Type, java.lang.reflect.AnnotatedElement { ..... ..... ..... }
- 这个类封装了什么信息?
Class是一个类,它封装了当前对象所对应了的信息。
一个类中有属性,方法,构造器等,比如说有一个Person类,一个Order类,一个Book类,这些都是不同的类,现在需要一个类,用来描述类,这就是Class,它应该有类名,属性,方法,构造器等。Class是用来描述类的类。
Class类是一个对象照镜子的结果,对象可以看到自己有哪些属性,方法,构造器,实现了哪些接口等等
- 如何获取Class对象?
- 三种方式:
- 类.class
- 对象.getClass()
- Class.forName("xxx")
- 三种方式:
package basic;
//Person类
public class Person {
private String name="tom";
private int age;
public String sex="男";
public Person(){}
public Person(int age){
this.age=age;
}
public void speak(){
System.out.println("你好!");
}
private void eat(){
System.out.println("好吃");
}
}
//1.通过类.class获取类对象
Class clazz=Person.class;
//2.对象.class
Person p=new Person();
Class clazz=p.getClass;
//3.Class.forName("")
Class clazz=Class.forName("basic.Person");
3.反射的类加载机制
ClassLoader(类加载器)是用来把class加载到jvm中的,jvm中规范了两种类加载器,启动类加载器(bootstrap)和用户自定义加载器(user-defined classloader).jvm在运行时会产生三个类加载器组成的初始化加载器曾其结构。如下图所示:
public class ReflectionTest {
public void Test() throws ClassNotFoundException {
//1.获取一个类的系统加载器(可以获取,这个类就是它加载的)
ClassLoader classLoader=ClassLoader.getSystemClassLoader();
System.out.println(classLoader);
//2.获取一个系统类加载器的父类加载器(扩展类加载器,可以获取)
classLoader=classLoader.getParent();
System.out.println(classLoader);
//3.获取一个系统类加载器的父类加载器(引导类加载器,不可以获取)
classLoader=classLoader.getParent();
System.out.println(classLoader);
//测试当前类由哪个类加载器加载(系统类加载器)
classLoader=Class.forName("basic.ReflectionTest").getClassLoader();
System.out.println(classLoader);
//测试超类由哪个加载器加载(引导类,不可获取)
classLoader=Class.forName("java.lang.Object").getClassLoader();
System.out.println(classLoader);
//使用类加载器获取当前类目录下的文件
InputStream in1=null;
InputStream in2=null;
//src下面可以直接加载
in1=this.getClass().getClassLoader().getResourceAsStream("text1.txt");
//不是src下的需要获取全路径
in2=this.getClass().getResourceAsStream(("basic/test2.txt"));
}
}
4.通过 Class 类获取成员变量、成员方法、接口、超类、构造方法等
getName():获得类的完整名字。
getFields():获得类的public类型的属性。
getDeclaredFields():获得类的所有属性。包括private 声明的和继承类
getMethods():获得类的public类型的方法。
getDeclaredMethods():获得类的所有方法。包括private 声明的和继承类
getMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes 参数 指定方法的参数类型。
getConstructors():获得类的public类型的构造方法。
getConstructor(Class[] parameterTypes):获得类的特定构造方法, parameterTypes 参数指定构造方法的参数类型。
newInstance():通过类的不带参数的构造方法创建这个类的一个对象。
Class clazz=Class.forName("basic.Person");
//使用newInstance()创建一个类的对象,调用无参构造器
Person ob=(Person) clazz.newInstance();
ob.speak();
System.out.println(ob);
//获得类的完整名字
String classname=clazz.getName();
//获得类的public属性
Field [] fields=clazz.getFields();
for(Field field:fields)
{
System.out.println(field.getName());
}
//获得类的所有属性
Field [] fields1=clazz.getDeclaredFields();
for(Field field1:fields1)
{
System.out.println(field1.getName());
}
//获得类的public类型的方法。这里包括 Object 类的一些方法
Method [] methods = clazz.getMethods();
for(Method method : methods){
System.out.println(method.getName());//speak equls toString hashCode notify等
}
//获得类的所有方法。
Method [] allMethods = clazz.getDeclaredMethods();
for(Method method : allMethods){
System.out.println(method.getName());//speak eat 不包括object类的方法
}
//获得指定的属性
Field f1 = clazz.getField("sex");
System.out.println(f1);
//获得指定的私有属性
Field f2 = clazz.getDeclaredField("name");
//启用和禁用访问安全检查的开关,值为 true,则表示反射的对象在使用时应该取消 java 语言的访问检查;反之不取消
f2.setAccessible(true);
System.out.println(f2.get(ob));//tom
//给对象的属性赋值。通过反射机制破坏封装性
f2.set(ob,"Bob");
System.out.println(f2.get(ob));//Bob
//获取构造方法
Constructor[] constructors = clazz.getConstructors();
for(Constructor constructor : constructors){
System.out.println(constructor.toString());//public com.ys.reflex.Person() public basic.Person(int)
}
5.理解并掌握动态代理
- 动态代理(以下称代理),利用Java的反射技术(Java Reflection),在运行时创建一个实现某些给定接口的新类(也称“动态代理类”)及其实例(对象)
- 解决特定问题:一个接口的实现在编译时无法知道,需要在运行时才能实现
- 实现某些设计模式:适配器(Adapter)或修饰器(Decorator)
- 面向切面编程:如AOP in Spring