美文网首页
java 反射机制及动态代理

java 反射机制及动态代理

作者: nade_s | 来源:发表于2018-07-17 16:27 被阅读0次

反射概述
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

先看一下 实体类

/**

  • Constructor
    */
    public class ConStudent {

    public ConStudent(){
    System.out.print("ConStudent空参构造函数"+"\n");
    }

    public ConStudent(double score) {
    System.out.print("ConStudent有参构造函数"+"\n");
    }

    private ConStudent(int age) {
    System.out.print("ConStudent私有构造带参数"+age+"\n");
    }
    protected ConStudent(String name){
    System.out.print("ConStudent受保护的构造参数"+name+"\n");
    }

}
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
实体也是三个参数 代表三种权限

/**

  • Filed
    */
    public class FiledStudent {
    public int age;
    private String name;
    protected double score;

    @Override
    public String toString() {
    return "FiledStudent{" +
    "age=" + age +
    ", name='" + name + ''' +
    ", score=" + score +
    '}';
    }

    public int getAge() {
    return age;
    }

    public void setAge(int age) {
    this.age = age;
    }

    public String getName() {
    return name;
    }

    public void setName(String name) {
    this.name = name;
    }

    public double getScore() {
    return score;
    }

    public void setScore(double score) {
    this.score = score;
    }
    }

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

/**

  • Method
    */
    public class MethodStudent{
    int age;
    String name;
    double score;

    public void showName( ){
    System.out.print("(公共)姓名:");
    }
    private void showAge(){
    System.out.print("(私有)年龄:");
    }
    protected void showScore(){
    System.out.print("(保护)分数:");
    }

    public String printName(String name){
    System.out.print("(公共string)name:"+name);
    return name;
    }
    private double printScore(double score){
    System.out.print("(私有double)score:"+score);
    return score;
    }
    protected int printAge(int age){
    System.out.print("(保护age)age:"+age);
    return age;
    }

}

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();
}

}

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

相关文章

  • Java反射机制详解(二)

    本篇文章继续介绍Java反射机制,不同的是侧重于介绍动态代理。动态代理是代理模式中的一种,是通过Java反射机制来...

  • Java反射机制总结(二)

    本篇文章继续介绍Java反射机制,不同的是侧重于介绍动态代理。动态代理是代理模式中的一种,是通过Java反射机制来...

  • Java 动态代理

    前言 关于动态代理 JDK动态代理 CGLIB动态代理 区别 java动态代理是利用反射机制生成一个实现代理接口的...

  • java 反射机制及动态代理

    反射概述Reflection(反射)是Java被视为动态语言的关键,反射机制允许程序在执行期借助于Reflecti...

  • 第6讲 | 动态代理是基于什么原理?

    谈谈 Java 反射机制,动态代理是基于什么原理? 典型回答 反射机制是 Java 语言提供的一种基础功能,赋予程...

  • Java动态代理机制分析

    前言 Java动态代理通过反射的机制实现在运行时,基于传入的指定一组接口及委托类对象,动态的产生代理类,代理类负责...

  • Spring笔记

    1.Spring用到的动态代理分为java动态代理和CGILB动态代理,相同点是都是通过反射机制创建运行时被代理类...

  • Java基础:反射

    反射注解动态代理相关阅读 Java基础:类加载器 Java基础:反射 Java基础:注解 Java基础:动态代理 ...

  • java代理模式2_动态代理_jdk

    动态代理 相对于静态代理,动态代理在创建代理对象上更加的灵活,动态代理类的字节码在程序运行时,由java反射机制动...

  • java代理模式2.2_动态代理_cglib

    动态代理 相对于静态代理,动态代理在创建代理对象上更加的灵活,动态代理类的字节码在程序运行时,由java反射机制动...

网友评论

      本文标题:java 反射机制及动态代理

      本文链接:https://www.haomeiwen.com/subject/gabwpftx.html