java 反射机制及动态代理

2018-07-17  本文已影响0人  nade_s

反射概述
Reflection(反射)是Java被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的內部信息,并能直接操作任意对象的内部属性及方法。

Java反射机制主要提供了以下功能:

在运行时构造任意一个类的对象
在运行时获取任意一个类所具有的成员变量和方法
在运行时调用任意一个对象的方法(属性)
生成动态代理

Class 是一个类; 一个描述类的类.
   封装了描述方法的 Method,
描述字段的 Filed,
描述构造器的 Constructor 等属性.
下面我们以student为例 一一介绍

先说获取Class对象的三种方式
1.通过类名获取 类名.class
2.通过对象获取 对象名.getClass()
3.通过全类名获取 Class.forName(全类名)

   //类名.class
    Class<ConStudent> conSC = ConStudent.class;
    System.out.print("---------类名.class---------"+"\n");
    //对象名.getClass()
    ConStudent conStudent = new ConStudent();
    Class<? extends ConStudent> conSC1 = conStudent.getClass();
    System.out.print("---------对象名.getClass()---------"+"\n");
    //Class.forName(全类名)
    Class<?> conSC2 = Class.forName("com.reflection.ConStudent");
    System.out.print("---------Class.forName(全类名)---------");

---------类名.class---------
静态代码:10
---------对象名.getClass()---------
静态代码:10
---------Class.forName(全类名)---------

public class ConStudent {

public static int number = 10;
static {
    System.out.print("静态代码:"+number+"\n");
}

}

通过以上方式可以看出 第二第三种方式是直接调用静态代码的 从方便和效率来看 第三中方式是最好的 第一种也不错 第二种是不推荐的 个人建议 仅供参考

现在说一下 Constructor

先看一下 实体类

/**

}
private static void constructor() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {

    Class<?> conSC = Class.forName("com.reflection.ConStudent");
    Constructor<?>[] constructors = conSC.getConstructors();
    for (Constructor c :constructors){
        System.out.print("ReflectTest所有公有构造:"+c+"\n");
    }
    System.out.print("ReflectTest----------分割线-------------"+"\n");

    Constructor<?>[] declaredConstructors = conSC.getDeclaredConstructors();
    for (Constructor c : declaredConstructors){

        System.out.print("ReflectTest所有构造方法:"+c+"\n");
    }
    System.out.print("ReflectTest----------分割线-------------"+"\n");
    Constructor constructor = conSC.getConstructor();
    System.out.print("ReflectTest公有无参构造方法"+constructor+"\n");
    System.out.print("ReflectTest----------分割线-------------"+"\n");
    Constructor<?> declaredConstructor = conSC.getDeclaredConstructor(int.class);
    System.out.print("ReflectTest私有构造方法"+declaredConstructor+"\n");
    declaredConstructor.setAccessible(true);
    Object o = declaredConstructor.newInstance(11);
    System.out.print("ReflectTest调用私有构造"+o+"\n");
    System.out.print("ReflectTest----------分割线-------------"+"\n");
    Constructor<?> declaredConstructor1 = conSC.getDeclaredConstructor(String.class);
    declaredConstructor1.setAccessible(true);
    Object maoge = declaredConstructor1.newInstance("maoge");
    System.out.print("ReflectTest受保护的构造:"+maoge);

}

输出内容

ReflectTest所有公有构造:public com.reflection.ConStudent(double)
ReflectTest所有公有构造:public com.reflection.ConStudent()
ReflectTest----------分割线-------------
ReflectTest所有构造方法:protected com.reflection.ConStudent(java.lang.String)
ReflectTest所有构造方法:private com.reflection.ConStudent(int)
ReflectTest所有构造方法:public com.reflection.ConStudent(double)
ReflectTest所有构造方法:public com.reflection.ConStudent()
ReflectTest----------分割线-------------
ReflectTest公有无参构造方法public com.reflection.ConStudent()
ReflectTest----------分割线-------------
ReflectTest私有构造方法private com.reflection.ConStudent(int)
ConStudent私有构造带参数11
ReflectTest调用私有构造com.reflection.ConStudent@14ae5a5
ReflectTest----------分割线-------------
ConStudent受保护的构造参数maoge
ReflectTest受保护的构造:com.reflection.ConStudent@7f31245a
Process finished with exit code 0

下面看一下 Filed
实体也是三个参数 代表三种权限

/**

private static void filedTest() throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class<?> filedSC = Class.forName("com.reflection.FiledStudent");
Field[] fields = filedSC.getFields();
for (Field f :fields){
System.out.print("ReflectTest所有公有的参数:"+f+"\n");
}
System.out.print("ReflectTest----------分割线-------------"+"\n");
Field age = filedSC.getField("age");
Object o = filedSC.getConstructor().newInstance();
age.set(o,11);
FiledStudent student = (FiledStudent) o;
System.out.print("ReflectTest获取公有参数:"+student.getAge()+"\n");
System.out.print("ReflectTest----------分割线-------------"+"\n");
Field[] declaredFields = filedSC.getDeclaredFields();
for (Field f :declaredFields){
System.out.print("ReflectTest获取所有参数:"+f+"\n");
}
System.out.print("ReflectTest----------分割线-------------"+"\n");
Field name = filedSC.getDeclaredField("name");
name.setAccessible(true);
name.set(o,"Maoge");

    System.out.print("ReflectTest获取指定的私有参数:"+student.getName()+"\n");
    System.out.print("ReflectTest----------分割线-------------"+"\n");
    Field score = filedSC.getDeclaredField("score");
    score.setAccessible(true);
    score.set(o,9.8);
    System.out.print("ReflectTest获取受保护的参数:"+student.getScore());

}

下面看 mothed

/**

}

private static void methodTest() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class<?> methodSC = Class.forName("com.reflection.MethodStudent");
Method[] declaredMethods = methodSC.getDeclaredMethods();
for (Method m : declaredMethods){
System.out.print("ReflectTest 获取所有的方法:"+m+"\n");
}
System.out.print("ReflectTest----------分割线-------------"+"\n");
Method[] methods = methodSC.getMethods();
for (Method m : methods){
System.out.print("ReflectTest获取所有的公有方法"+m+"\n");
}
System.out.print("ReflectTest----------分割线-------------"+"\n");
Method score = methodSC.getDeclaredMethod("printScore", double.class);
Object o = methodSC.getConstructor().newInstance();
score.setAccessible(true);
Object invoke = score.invoke(o, 9.8);
System.out.print("ReflectTest调用制定的私有方法:"+invoke+"\n");
System.out.print("ReflectTest----------分割线-------------"+"\n");

    Method printName = methodSC.getMethod("printName", String.class);
    Object maoge = printName.invoke(o, "Maoge");
    System.out.print("ReflectTest公有有参数方法:"+maoge+"\n");
    System.out.print("ReflectTest----------分割线-------------"+"\n");
    Method showName = methodSC.getMethod("showName", null);
    System.out.print("ReflectTest公有无参方法:"+showName+"\n");
    System.out.print("ReflectTest----------分割线-------------"+"\n");
    Method printAge = methodSC.getDeclaredMethod("printAge", int.class);
    printAge.setAccessible(true);
    Object invoke1 = printAge.invoke(o, 20);
    System.out.print("ReflectTest受保护的方法:"+invoke1);
}

这是反射的一些基础使用

下面说一下动态代理 (代理可以让我们的方法或者类进行功能扩展 解耦等好处)

新建一个接口

public interface Person {
void work();
}

新建一个接口实现类(被角色代理)

public class PersonImpl implements Person{

@Override
public void work() {
    System.out.print("i am PersonImpl.calss");

}

}

新建一个代理角色

public class PersonHandler implements InvocationHandler {
public Object px;

public PersonHandler(Object px) {
    this.px = px;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    System.out.print("do work"+"\n");
    return method.invoke(px,args);
}

}

绑定代理

public class PersonProxyTest {
public static void main(String[] args) {
Person person = new PersonImpl();
Person o = (Person) Proxy.newProxyInstance(Person.class.getClassLoader(), new Class[]{Person.class}, new PersonHandler(person));
o.work();
}

}

好了 本文到此结束 欢迎留言或私信

上一篇 下一篇

猜你喜欢

热点阅读