• JAVA反射机制


    1.运行环境

    jdk1.8.0_77 Intellij IDEA2018.3 x64

    2.JAVA反射机制

    Java 反射是Java语言的一个很重要的特征,它使得Java具有了“动态性”。 Java提供了一套机制来动态获取类的信息以及动态调用对象的方法的功能,这套机制就叫——反射 反射机制是如今很多流行框架的实现基础,其中包括Struts、Spring、Hibernate等。

    在运行时判断任意一个对象所属的类。 在运行时构造任意一个类的对象。 在运行时判断任意一个类所具有的成员变量和方法。 在运行时调用任意一个对象的方法

    Reflection 是Java被视为动态(或准动态)语言的一个关键性质。这个机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息,包括其modifiers(诸如public, static 等等)、superclass(例如Object)、实现之interfaces(例如Serializable),也包括fields和methods的所有信息,并可于运行时改变fields内容或调用methods 那么通过Reflection所获取的信息从什么地方获取呢?

    3.获取Class对象和方法

    对于每一个类在加载时都会有一个唯一的Class对象,Class对象中包含了所有需要动态获取的类的信息, 所以Class类是Reflection API 中的核心类 

    方法

    1)obj.getClass()

    2)class属性

    3)Class.forName()

    4)ClassLoader

    4.Class中的常用方法(获得类的信息)

    在Class对象的方法中,所有getXXX方法只能反射出public类型的成员,包括父类的public成员,所有getDeclaredXXX可以反射出类的所有成员(包括类的私有成员),但是只限于类本身的成员

    5.Class中的常用方法(获得类的构造方法)

    getConstructors():获得类的所有的public类型的构造方法。

    getDeclaredConstructors():获得类所有的构造方法 。

    getConstructor(Class[] parameterTypes):获得类的特定public的构造方法, parameterTypes 参数指定构造方法的参数类型。

    getDeclaredConstructor(Class[] parameterTypes):获得类指定的所有的构造方法。

    6.Class中的常用方法(获得类的属性)

    getFields():获得类的public类型的属性。

    getDeclaredFields():获得类本身的所有属性

    getField(String):获得指定名字的public类型的属性对象

    getDeclaredField(String)获得类自己的指定名字的属性对象

    Field类: getModifiers():获得属性的修饰符(Modifier.toString(int)显示对应的修饰符类型)

    getType() : 获得属性的类型

    7.Class中的常用方法(获得类的方法)

    getMethods():获得类的public类型的方法。

    getDeclaredMethods():获得类的所有方法。

    getMethod(String name, Class[] parameterTypes):获得类的特定public的方法, name参数指定方法的名字, parameterTypes 参数指定方法的参数类型。

    getDeclaredMethod(String name, Class[] parameterTypes) Method类:

    getParameterTypes() :获得方法的所有参数类型

    getReturnType():获得方法的返回值类型

    8.代码展示

    public class demo1 {
    public static void main(String[] args) throws ClassNotFoundException{
    //得到Class类对象的四种方法
    //1.
    Object obj=new String();
    Class clz1 = obj.getClass();

    //2.
    Class clz2 = String.class;

    //3.
    Class clz3 = Class.forName("java.lang.String");

    //4.
    ClassLoader cl = ClassLoader.getSystemClassLoader();
    Class clz4 = cl.loadClass("java.util.ArrayList");

    }
    }

    public class demo2 {
    public static void main(String[] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException {
    // 反射String类的所有构造方法
    Class clz = Students.class;

    System.out.println("所有构造方法");
    // Constructor[] cons = clz.getConstructors();
    Constructor[] cons = clz.getDeclaredConstructors();
    for (Constructor con : cons) {
    // System.out.println("访问修饰权限:" +
    // Modifier.toString(con.getModifiers()));
    // System.out.println("方法名:" + con.getName());
    // System.out.println("****************************");
    System.out.println(Modifier.toString(con.getModifiers()) + " "
    + con.getName());
    }


    //找无参的构造方法 Student s = new Student();
    Constructor con = clz.getDeclaredConstructor();
    Object obj = con.newInstance();
    System.out.println(obj);

    //找带string,int类型参数的构造方法 Student s = new Student("zhangsan",12)
    con = clz.getDeclaredConstructor(String.class, int.class);
    obj = con.newInstance("zhangsan", 12);
    System.out.println(obj);

    con = clz.getDeclaredConstructor(String.class);

    public class demo3 {
    public static void main(String[] args) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
    Class clz = Students.class;

    System.out.println("得所有字段:");
    Field[] fields = clz.getDeclaredFields();
    for(Field field : fields) {
    System.out.println(Modifier.toString(field.getModifiers())+" " + field.getType().getSimpleName() + " " + field.getName());
    }


    //利用反射为s学生对象的两个属性字段赋值
    Students s = new Students(); //
    Class clzz = s.getClass();

    //为x字段赋值
    Field field_x = clzz.getField("x");
    field_x.set(s, "hello");
    System.out.println(s.x);

    //得到name字段
    Field field_name = clzz.getDeclaredField("name");
    field_name.setAccessible(true);
    field_name.set(s, "zhangsan");
    field_name.setAccessible(false);

    Field field_age = clzz.getDeclaredField("age");
    field_age.setAccessible(true);
    field_age.set(s, 20);
    field_age.setAccessible(false);
    System.out.println(s);

    public class demo4 {
    public static void main(String[] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException {
    Class clz = Students.class;

    Method[] methods = clz.getDeclaredMethods();
    for (Method method : methods) {
    Class[] clzz = method.getParameterTypes();
    String temp = "";
    for(Class cz:clzz) {
    temp += cz.getSimpleName()+",";
    }

    System.out.println(Modifier.toString(method.getModifiers()) + " "
    + method.getReturnType().getSimpleName() + " "
    + method.getName()+"("+temp+")");
    }


    //调用类无参的构造方法实例化对象
    Students st = (Students)clz.newInstance();

    //调用无参的构造方法实例化
    // Student st = (Student)clz.getConstructor().newInstance();


    //得到fun1方法并调用
    Method method_fun1 = clz.getMethod("fun1", String.class, int.class);
    method_fun1.invoke(st, "hello", 100);


    Method method_fun2 = clz.getMethod("fun2", String.class, int.class, double.class);
    Object returnValue = method_fun2.invoke(st, "hello",200, 3.14);
    System.out.println(returnValue);


    public class demo5 {
    public static void main(String[] args) {
    Dog dog = new Dog();

    String propertyName = "age";
    int propertyValue = 12;

    setProperty(dog, propertyName, propertyValue);

    System.out.println(dog);
    }

    /**
    *
    * @param obj
    * ,要设置字段值的对象
    * @param propertyName
    * ,要设置的字段名
    * @param propertyValue
    * ,要设置的字段值
    */
    public static void setProperty(Object obj, String propertyName,
    Object propertyValue) {
    // 得到类对象
    Class clz = obj.getClass();
    // 得到字段
    Field field;
    try {
    field = clz.getDeclaredField(propertyName);
    // 根据字段名得到对应的set方法名
    String methodName = "set"
    + propertyName.substring(0, 1).toUpperCase()
    + propertyName.substring(1);

    Method method = clz.getMethod(methodName, field.getType());
    method.invoke(obj, propertyValue);

    } catch (SecurityException e) {
    e.printStackTrace();
    } catch (NoSuchFieldException e) {
    e.printStackTrace();
    } catch (NoSuchMethodException e) {
    e.printStackTrace();
    } catch (IllegalArgumentException e) {
    e.printStackTrace();
    } catch (IllegalAccessException e) {
    e.printStackTrace();
    } catch (InvocationTargetException e) {
    e.printStackTrace();
    }


    9.心得

    学习没有捷径,也不是你奋斗一天能完成的事情,而是你端正学习态度,一点点累积而成,所谓活到老学到老,

    如果一件事情有尽头,那做这件事情的人就没有高低可分,最高点的人都是平等的,

    但学习不一样,好比编程,你只能没有好和最好,只有更好

  • 相关阅读:
    Linux下状态查看相关命令
    Linux免密登录理解
    Linux下远程访问&拷贝&下载
    初识NAT、桥接和Host-Only
    Linux文件和文件夹权限管理
    Linux用户和用户组的操作
    Mac+Parallels+iTerm安装配置Linux Centos7
    SSM整合事务失效
    Linux用户和用户组管理命令
    Linux中{ }的用法
  • 原文地址:https://www.cnblogs.com/nanren/p/13542955.html
Copyright © 2020-2023  润新知