反射

作者: 面向星辰大海的程序员 | 来源:发表于2020-04-20 23:44 被阅读0次

反射之中包含了一个【反】字,了解反射先从【正】开始
1.一般情况下,我们使用某个类:

 Student student = new Student();
        student.setName("小明");

上面就是正

2.不用 new 关键字实例化,利用jdk反射api获得实例

  try {

            Class studentClass = Class.forName("com.dbf.javastudy.reflect.Student");
            Student classStudent = (Student) studentClass.newInstance();
            classStudent.setName("xiaoqiang");
            System.out.println("\nreflect get Student name =" + classStudent.getName() + "\n\n\n");

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
reflect1.png

多种获取Class对象方式:

           Class studentClass = Class.forName("com.dbf.javastudy.reflect.Student");
            Class studentClass1=Student.class;
            Class studentClass2=student.getClass();

获取构造器:

   try {

            Class studentClass = Class.forName("com.dbf.studyandtest.javastudy.reflect.Student");
            Class studentClass1 = Student.class;
            Class studentClass2 = student.getClass();

            Student classStudent = (Student) studentClass.newInstance();
            classStudent.setName("小强");
            System.out.println("反射实例设置的名字:" + classStudent.getName());


            String className = "com.dbf.studyandtest.javastudy.reflect.Student";
            Class<Student> clazz = (Class<Student>) Class.forName(className);

            System.out.println("获取所有构造器:");
            Constructor<Student>[] constructors = (Constructor<Student>[]) clazz.getConstructors();
            for (Constructor<Student> constructor : constructors) {
                System.out.println(constructor);
            }
            System.out.println("获取无参构造器:");
            Constructor<Student> constructor = clazz.getConstructor();
            System.out.println(constructor);
            System.out.println("获取有参构造器:");
            Constructor<Student> argumentsConstructor = clazz.getConstructor(String.class, int.class, boolean.class);
            System.out.println(argumentsConstructor);
            System.out.println("使用构造器实例化:");
            Student zhangsan = argumentsConstructor.newInstance("张三", 18, true);
            System.out.println(zhangsan.toString());

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
constructor.png

获取方法:

 try {
            Class clazz = Class.forName("com.dbf.studyandtest.javastudy.reflect.Student");
            System.out.println("获取clazz对应类中所有的公有方法,包括从父类继承来的公有方法");
            Method[] methods = clazz.getMethods();
            for (Method method : methods) {
                System.out.println("" + method);
            }
            System.out.println("----------------------------------");
            System.out.println("获取当前类的所有方法,包括私有方法,且" +
                    "只能获取当前类的方法");
            Method[] declaredmethods = clazz.getDeclaredMethods();
            for (Method method : declaredmethods) {
                System.out.println("" + method);
            }
            System.out.println("获取指定方法,需要参数名称和参数列表,无参则不需要传");
            Method method = clazz.getMethod("setName", String.class);
            System.out.println("" + method);
            System.out.println("执行取得的方法");
            Object object = clazz.newInstance();
            method.invoke(object, "李四");
            System.out.println("method.invoke=" + ((Student) object).getName());
            System.out.println("执行私有方法");
            Method privateMethod = clazz.getDeclaredMethod("privateMethod", String.class);
            privateMethod.setAccessible(true);
            privateMethod.invoke(object, "我是私有方法,我被执行了");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
method.png

获取字段:

//使用getClass().getSuperclass()获取父类的私有字段
 try {
            Field field = mAlert.getClass().getSuperclass().getDeclaredField("mIconView");
            field.setAccessible(true);
            ImageView imageView = (ImageView) field.get(mAlert);
            FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) imageView.getLayoutParams();
            layoutParams.width = 50;
            layoutParams.height = 50;
        } catch (NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
        }
 try {
            Class clazz = Class.forName("com.dbf.studyandtest.javastudy.reflect.Student");
            Student student = (Student) clazz.newInstance();
            student.setName("my name is TestField");
            System.out.println("获取当前类所有公有字段,包括继承来的公有字段");
            Field[] fields = clazz.getFields();
            for (Field field : fields) {
                System.out.println(field);
            }
            System.out.println("获取当前类所有字段,包括私有字段,不能获取父类字段");
            Field[] declaredfields = clazz.getDeclaredFields();
            for (Field field : declaredfields) {
                System.out.println(field);
            }

            System.out.println("获取指定公有字段");
            Field hobbyfield = clazz.getDeclaredField("hobby");
            System.out.println("hobbyfield=" + hobbyfield.getName());
            System.out.println("hobbyfield=" + hobbyfield.get(student));


            System.out.println("获取指定私有字段");
            Field field = clazz.getDeclaredField("name");
            field.setAccessible(true);
            System.out.println("field=" + field.get(student));
            field.set(student, "my name is TestField2");
            System.out.println("field=" + field.get(student));

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }

field.png

静态代理 :违反开闭原则,可扩展性差 可维护性差
开闭原则:对修改关闭 对新增开放

动态代理:
主要两个类:Proxy ,InvocationHandler

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class DynamicProxyPerson implements InvocationHandler {
    private Object factory;

    public void setFactory(Object factory) {
        this.factory = factory;
    }

    //通过Proxy获得动态代理对象
    public Object getProxyInstance() {
        return Proxy.newProxyInstance(factory.getClass().getClassLoader()
                , factory.getClass().getInterfaces(), this);
    }

    @Override
    public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
        befor();
        Object re = method.invoke(factory, objects);
        after();
        return re;
    }

    private void befor() {
        System.out.println("befor()");
    }

    private void after() {
        System.out.println("after()");
    }
}

//接口
public interface ProxyFruitsInterface {
    void proxyFruits(int number);
}

//实现接口ProxyFruitsInterface
public class PersonOne implements ProxyFruitsInterface {
    @Override
    public void proxyFruits(int number) {
        System.out.println("PersonOne buy " + number + " Fruits");
    }
}

使用:
 public static void main(String[] args) {
proxyFuniture(15);

        ProxyFruitsInterface fruitsFactory = new PersonOne();
        DynamicProxyPerson dynamicProxyPerson = new DynamicProxyPerson();
        dynamicProxyPerson.setFactory(fruitsFactory);

        ProxyFruitsInterface fruitsFactory1 = (ProxyFruitsInterface) dynamicProxyPerson.getProxyInstance();
        fruitsFactory1.proxyFruits(18);
    }

dynamicproxy.png

相关文章

  • Java基础之反射

    Java基础之反射 反射基本介绍 反射的使用通过反射调用属性和方法通过反射获取配置文件 反射基本介绍 Java反射...

  • 镜面反射矩阵的推导

    镜面反射是以镜面作为反射平面,实物与反射物到反射平面的距离相等,实物与反射物方向相反,所以,反射矩阵由反射平面确定...

  • reflect.go包学习_之二 指针操作提高反射性能 反射应用

    reflect.go包学习_之二 指针操作提高反射性能 反射应用 反射创建实例 反射信息、反射调用方法、反射修改值...

  • Java互联网公司-经典面试题附答案

    基础:Java 反射?反射有什么缺点?你是怎么理解反射的(为什么框架需要反射)?优点:反射具有解耦性,缺点:反射属...

  • Java反射与joor反射库的使用

    java原生反射的使用 反射构造对象 反射方法 反射字段 joor反射库的使用 github:https://gi...

  • Java反射

    什么是反射? 反射的作用? 反射性能优化?

  • 反射三定律

    反射第一定律:反射可以将interface类型变量转换成反射对象 反射第二定律:反射可以将反射对象还原成inter...

  • 反射

    1.反射是什么?反射的定义,概念 2.为什么要学反射? 3.怎么使用反射?反射的使用

  • 一周岁前做好两件事,孩子就不会语言迟缓,保证口齿伶俐

    与语言发展相关的原始反射有四个:张口反射、足跖反射、抓握反射和手拉反射,每个反射的发生、发展和整合都是次第进行的,...

  • 面试官问go反射第一弹

    目录 反射概念 reflect包 反射类型(Type)和种类(Kind) 反射类型(Type)使用 反射类型对象(...

网友评论

      本文标题:反射

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