反射学习笔记

反射原理

得到一个对象不通过New的方式创建


1.首先需要把Java文件保存到本地硬盘.Java

2.编译Java文件,成.class文件

3.使用JVM,把class文件通过类加载加载带内存中

4.万事万物皆对象,class文件在内存中用Class内表示

5.当使用反射时,首先要获取内存中的Class类,得到这个类之后,就可以得到class文件里面的所有内容(包括属性、构造方法、普通方法)

属性可以通过一个类来表示        Filed    

普通方法可以通过一个类来表示        Constructor

构造方法可以通过一个类来表示        Method

反射学习笔记

反射使用

如果得到Class类,可以得到这个类中的所有内容  属性,普通方法,构造方法

得到Class类的三种方式:

(1)类名.class

(2)对象.getClass

(3)使用Class.forName(“类路径”)


一、使用反射得到一个对象。

1.建一个Person类

public class Person{
    private String name;
    private int id;

    public Person(String name, int id) {
        this.name = name;
        this.id = id;
    }

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

    public Person() {
    }
}

2.写Test

(1)使用反射操作无参构造方法

/*使用反射操作无参构造方法*/
@Test
public void Test1() throws Exception{

    /*得到Class*/
    Class c3 = Class.forName("Pojo.Person");

    /*获取实例*/
    Person p = (Person)c3.newInstance();

    p.setName("张三");

    System.out.println(p.getName());
}

(2)使用反射操作有参构造方法

    /*使用反射操作有参数的构造方法*/
    @Test
    public void Test2() throws Exception{

        /*得到Class*/
        Class c = Class.forName("Pojo.Person");

        /*获取有参构造器
          参数里面传入方法里面的参数类型,使用的是class传递*/
        Constructor cs = c.getConstructor(String.class,int.class);

        /*通过有参的构造器得到对象,并且传入参数*/
        Person p = (Person)cs.newInstance("lisi",18);
        System.out.println(p);
    }
}

二、使用反射操作类里面的属性

@Test
public void Test3() throws Exception{

    /*得到Class*/
    Class c = Class.forName("Pojo.Person");

    /*通过Class创建对象*/
    Person p = (Person)c.newInstance();

    /*得到一种属性,参数是属性的名称*/
    Field f = c.getDeclaredField("id");
    /*表示得到所有属性*/
    c.getDeclaredFields();

    /*设置可以操作私有属性
      因为不让直接操作私有属性*/
    f.setAccessible(true);

    /*第一个参数为对象,第二个参数为值
      属性调用方法来给对象中的该属性赋值*/
    f.set(p,18);

    /*通过属性调用对象,来得到对象的属性*/
    System.out.println(f.get(p));
}

三、操作普通方法

@Test
/*操作普通方法*/
public void Test4() throws Exception{

    /*得到Class*/
    Class c = Class.forName("Pojo.Person");

    /*通过Class创建对象*/
    Person p = (Person)c.newInstance();

    /*得到普通方法,第一个参数为需要得到的方法名,第二个为方法参数的类型*/
    Method method = c.getDeclaredMethod("setName", String.class);
    /*得到所有方法*/
    Method[] method1 = c.getDeclaredMethods();

    /*调用方法,第一个参数为对象,第二个参数为需设置的值*/
    method.invoke(p,"zhangsan");

    System.out.println(p.getName());
}

四、当操作的是一个静态方法的时候,因为静态方法调用的方式是  类名.方法名 不需要实例。所以使用反射操作静态方法的时候也是不需要实例的。

method.invoke(null,"lala");