Java-反射机制

思考:
在Java运行环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法?

什么是反射机制?
简单的来说,反射机制指的是程序在运行时能够获取自身的信息。在java中,只要给定类的名字,那么就可以通过反射机制来获得类的所有信息。

利用反射机制能获得什么信息?
一句话,类中有什么信息,它就可以获得什么信息,不过前提是得知道类的名字,要不就没有后文了首先得根据传入的类的全名来创建Class对象。

获取Class对象的三种方式

  • 对象名.getClass()
  • 类名.class
  • Class.forName
package ReflectDemo;
public class Person {
    private int id;
    private String name;
    public Person() {
        super();
    }
    public Person(int id, String name) {
        super();
        this.id = id;
        this.name = name;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

package ReflectDemo;

public class Test {
    public static void main(String[] args) throws ClassNotFoundException {
        //获取Class对象的三种方式 
        Class c1 = null;
        Class c2 = null;
        Class c3 = null;
        
        //1、类名.class
        c1 = Person.class;
        //2、Class.forName(包名.类名)
        c2 = Class.forName("ReflectDemo.Person");
        //3、对象名.getClass()
        Person person = new Person();
        c3 = person.getClass();
        
        //打印测试
        System.out.println(c1);
        System.out.println(c2);
        System.out.println(c3);
    }
}

实例化对象:
1、以前的做法:类名 对象名 = new 类名();
2、反射做法:
Class c1 = Class.forName("com.lanqiao.demo3.Person");
Person per1 = (Person)c1.newInstance();

package ReflectDemo;
public class Test {
    public static void main(String[] args) throws Exception {
        //反射获取对象的写法:
        Class c = Class.forName("ReflectDemo.Person");
        Person person = (Person) c.newInstance();
        System.out.println(person);
    }
}

通过反射获取构造方法:

package ReflectDemo;
import java.lang.reflect.Constructor;

public class Test {
    public static void main(String[] args) throws Exception {
        //反射获取对象的写法:
        Class c = Class.forName("ReflectDemo.Person");
        //获取所有构造方法
        Constructor[] constructors = c.getConstructors();
        
        //遍历
        for (int i = 0; i < constructors.length; i++) {
            System.out.println(constructors[i]);
        }
        
        //执行构造方法
        Person person = (Person) constructors[1].newInstance(new Object[]{18,"张文"});
        System.out.println(person.getId()+"\t"+person.getName());
    }
}

获取类中的属性及执行操作

package ReflectDemo;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
public class Test {
    public static void main(String[] args) throws Exception {
        //1.获取Class对象
        Class c = Class.forName("ReflectDemo.Person");
        //2.实例化具体对象
        Person person = (Person) c.newInstance();
        //3.获取类中的所有属性
        Field[] fs = c.getFields();//只能查看自身以及父类中的公共的(public)属性,私有化属性看不到
        for (int i = 0; i < fs.length; i++) {
            System.out.println(fs[i].getName());
        }
        
        System.out.println("====");
        
        Field[] fs1 = c.getDeclaredFields();//这个方法只能获取本类的属性,包括私有公有,但是父类中的看不到
        for (int i = 0; i < fs1.length; i++) {
            System.out.println(fs1[i].getName());
        }
    }
}

获取指定属性并且设置属性

package ReflectDemo;
import java.lang.reflect.Field;
public class Test {
    public static void main(String[] args) throws Exception {
        //1.获取Class对象
        Class c = Class.forName("ReflectDemo.Person");
        //2.实例化具体对象
        Person person = (Person) c.newInstance();
        //3.获取类中的指定属性
        Field field = c.getDeclaredField("name");
        //因为属性私有化,这个方法是破解封装性,才能操作属性
        field.setAccessible(true);
        //设置属性值
        field.set(person, "测试名");
        //获取属性值
        String name = field.get(person).toString();
        System.out.println(name);
    }
}

获取类中的方法以及执行的操作

package ReflectDemo;
import java.lang.reflect.Method;
public class Test {
    public static void main(String[] args) throws Exception {
        //1.获取Class对象
        Class c = Class.forName("ReflectDemo.Person");
        //2.实例化具体对象
        Person person = (Person) c.newInstance();
        //3.获取所有的方法
        /**
         * getMethods()方法是获取当前类以及父类中所有的公开的方法
         */
        Method[] methods = c.getMethods();
        for (int i = 0; i < methods.length; i++) {
            System.out.println(methods[i]);
        }
        
        System.out.println("==========");
        
        /**
         * getDeclaredMethods()方法是获取当前类中所有的方法,包括私有公有
         */
        Method[] methods1 = c.getDeclaredMethods();、
        for (int i = 0; i < methods1.length; i++) {
            System.out.println(methods1[i]);
        }
    }
}

获取指定的方法

package ReflectDemo;
import java.lang.reflect.Method;
public class Test {
    public static void main(String[] args) throws Exception {
        //1.获取Class对象
        Class c = Class.forName("ReflectDemo.Person");
        //2.实例化具体对象
        Person person = (Person) c.newInstance();
        //3.获取指定的方法
        Method setMethod = c.getDeclaredMethod("setName", new Class[]{String.class});
        //4.执行方法
        setMethod.invoke(person, new Object[]{"测试名"});
        //3.获取指定的方法
        Method getMethod = c.getDeclaredMethod("getName", new Class[]{});
        //4.执行方法
        Object obj = getMethod.invoke(person, new Object[]{});
        System.out.println(obj.toString());
    }
}

工厂模式结合反射实现对象生成

你可能感兴趣的:(Java-反射机制)