概要总结笔记!!JAVA动态性——反射机制(二:通过反射获取类、操作类的信息)

自定义javabean类代码

    1

    2

    3

    4

    5

    6

    7

    8

    9

   10

   11

   12

   13

   14

   15

   16

   17

   18

   19

   20

   21

   22

   23

   24

   25

   26

   27

   28

   29

   30

   31

   32

   33

   34

   35

   36

   37

   38

   39

   40

   41

package first.reflect;

 

public class Bean {

    private int age;

    private String name;

    private int id;

 

    public Bean() {

 

    }

 

    public Bean(int age, String name, int id) {

        this.age = age;

        this.name = name;

        this.id = id;

    }

 

    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 int getId() {

        return id;

    }

 

    public void setId(int id) {

        this.id = id;

    }

}

 通过反射获取类的三种方式:

getClass()

通过类对象的getClass()方法获取

Class forname()

最常用的方式,通过Class类的静态方法forname(字符串的类名)获取

class语法

通过类的静态成员表示,每个类都有隐含的静态成员class

    1

    2

    3

    4

    5

    6

    7

    8

    9

   10

   11

   12

   13

   14

   15

   16

   17

   18

   19

   20

   21

   22

   23

   24

   25

   26

   27

   28

   29

   30

   31

   32

   33

package first.reflect;

 

public class test {

    public static void main(String[] args) throws ClassNotFoundException {

        String path = "first.reflect.Bean";

 

//方式一,最常用的方式,通过Class类的静态方法forname(字符串的类名)获取

        Class c1 = Class.forName(path);

        System.out.println(c1);

 

        Class<Bean> c2 = (Class<Bean>) Class.forName(path);

        System.out.println(c2);

        System.out.println(c1 == c2);//true

 

//方式二,通过类名获取,包括所有类型(基本数据类型和引用数据类型)

        Class c3 = String.class;

        System.out.println(c3);

 

        Class c4 = int.class;

        System.out.println(c4);

 

//方式三,通过类对象的getClass()方法获取

Bean bean=new Bean();

        Class c5 = bean.getClass();

        System.out.println(c5);

 

        //维数和类型相同数组的类对象相同

        int[] arr01 = new int[10];

        int[][] arr02 = new int[30][3];

        int[] arr03 = new int[30];

        double[] arr04 = new double[10];

        System.out.println(arr01.getClass().hashCode());

        System.out.println(arr02.getClass().hashCode());

        System.out.println(arr03.getClass().hashCode());

        System.out.println(arr04.getClass().hashCode());

    }

}

通过反射获取类的信息 :

    1

    2

    3

    4

    5

    6

    7

    8

    9

   10

   11

   12

   13

   14

   15

   16

   17

   18

   19

   20

   21

   22

   23

   24

   25

   26

   27

   28

   29

   30

   31

   32

   33

   34

   35

   36

   37

   38

   39

   40

   41

   42

   43

   44

   45

   46

   47

   48

   49

   50

   51

   52

   53

   54

   55

package first.reflect;

 

import java.lang.reflect.Constructor;

import java.lang.reflect.Field;

import java.lang.reflect.Method;

 

public class test02 {

    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {

        String path = "first.reflect.Bean";

        //获取类

        Class c = Class.forName(path);

 

        //获取类的名字

        System.out.println(c.getName());//包名+类名

        System.out.println(c.getSimpleName());//类名

 

        //获取属性信息

        //获得某个类的所有的public的字段,包括父类中的字段。

        Field[] field = c.getFields();

        System.out.println(field.length);

        //获得某个类的所有声明的字段,即包括public、private和protected,但是不包括父类的申明字段。

        Field[] fields = c.getDeclaredFields();

        for (Field f : fields)

            System.out.println(f);

 

        //获取方法信息

        //获取本类以及父类或者父接口中所有的公共方法

        Method[] method = c.getMethods();

        System.out.println(method.length);

        for (Method m : method)

            System.out.println(m);

        //获取本类中的所有方法,包括私有的(private、protected、默认以及public)的方法。

        Method[] methods = c.getDeclaredMethods();

        System.out.println(methods.length);

        for (Method m : methods)

            System.out.println(m);

        //获取指定方法,第一个参数为方法名,第二个参数为参数类型,没有参数即null

        Method m1 = c.getDeclaredMethod("getName", null);

        Method m2 = c.getDeclaredMethod("setName", String.class);

 

        //获取构造器信息

        //返回指定参数类型访问权限是public的构造器

        Constructor[] constructor = c.getConstructors();

        System.out.println(constructor.length);

        //返回指定参数类型的所有构造器,包括public的和非public的,当然也包括private的

        Constructor[] constructors = c.getConstructors();

        for (Constructor con : constructors)

            System.out.println(con);

        //获取指定构造器,参数为参数类型的类对象,无参则为null

        Constructor constructor1 = c.getConstructor(null);

        System.out.println(constructor1);

        Constructor constructor2 = c.getConstructor(int.class, String.class, int.class);

        System.out.println(constructor2);

    }

}

通过反射操作类的信息 

调用构造方法

  • 通过 public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 函数获取到构造方法

其中的参数为对应构造方法参数类型的class对象,如果为空构造函数则不加

  • 获取到的构造函数再调用 public T newInstance(Object...initargs)函数即调用了构造函数

其中的参数为对应构造函数的形参,如果为空构造函数则不加

调用普通方法  

  • 通过 public Method getDeclaredMethod(Stringname,Class<?>...parameterTypes)函数获取到指定方法

其中的第一个参数为指定方法的class对象,第二个的参数为指定方法返回类型的类对象

  • 获取到指定方法后调用 public Object invoke(Object obj, Object... args)函数即调用了该方法

其中的第一个参数为new出的类对象,后面的参数即为指定方法的形参

操作属性

  • 通过 public Field getDeclaredField(String name) 函数获取到指定属性

其中的参数为属性的名称

  • 获取到指定属性后可调用 public void set(Object obj, Object value)函数改变属性的值

其中的第一个参数为new出的类对象,第二个参数即为更改的值

  • 可以调用 public void setAccessible(boolean flag)函数来忽略安全检查,即可改变所有的属性值(包括private属性)

    1

    2

    3

    4

    5

    6

    7

    8

    9

   10

   11

   12

   13

   14

   15

   16

   17

   18

   19

   20

   21

   22

   23

   24

   25

   26

   27

   28

   29

   30

   31

   32

   33

   34

package first.reflect;

 

import java.lang.reflect.Field;

import java.lang.reflect.Method;

 

public class test03 {

    public static void main(String[] args) throws Exception {

        String path = "first.reflect.Bean";

 

        //获取类

        Class<Bean> c = (Class<Bean>) Class.forName(path);

 

        //通过反射API调用无参构造方法

        Bean bean = c.getDeclaredConstructor().newInstance();

        System.out.println(bean);

        //通过反射API调用有参构造方法

        Bean bean1 = c.getDeclaredConstructor(int.class, String.class, int.class).newInstance(20, "zsr", 2018217876);

        System.out.println(bean1);

        System.out.println(bean1.getAge() + " " + bean1.getName() + " " + bean1.getId());

 

        //通过反射API调用普通方法

        Bean bean2 = c.getDeclaredConstructor().newInstance();

        Method method = c.getDeclaredMethod("setName", String.class);

        method.invoke(bean2, "gcc");

        System.out.println(bean2.getName());

 

        //通过反射API操作属性

        Bean bean3 = c.getDeclaredConstructor().newInstance();

        Field field = c.getDeclaredField("name");

        field.setAccessible(true);//这个属性不需要做安全检查了,可以直接访问

        field.set(bean3, "zsr");//通过反射直接写属性

        System.out.println(bean3.getName()); //通过反射直接读属性的值

        System.out.println(field.get(bean3));

    }

}

 

你可能感兴趣的:(java)