javaSE ---- 反射

反射

1. 获取类加载器的方法

/**
 * @Author xiaoqi
 * @Date 
 * Class类的理解:
 * 1.类的加载过程,程序通过javac.exe命令以后,会生成一个或多个字节码文件(.class结尾的文件),接着我们使用
 * java.exe命令对某个字节码文件进行解释运行,相当于将某个字节码文件加载到内存中,此过程就称为类的加载,
 * 加载到内存中的类,我们就称为运行时类,此运行时类,就作为一个Class的实例
 * 换句话说,Class的实例就代表这一个运行时类
 */
/**
 * 获取Class实例的三种方式
 */
public class ClassTest {
    public static void main ( String[] args ) throws ClassNotFoundException {
//        方式一:调用运行时类的属性
        Class<Person> clazz01 = Person.class;
//        方式二:通过运行时类的对象,调用getClass()
        Person person = new Person();
        Class clazz02 = person.getClass();
//        方式三:调用Class的静态方法:forName(类的全路径名)
        Class clazz03 = Class.forName("com.wcc.reflect.Person");
//        方式四:使用类的加载器, ClassLoader
        ClassLoader classLoader = ClassTest.class.getClassLoader();
        Class clazz04 = classLoader.loadClass("com.wcc.reflect.Person");
//        加载到内存中的运行时类,会缓存一定的时间,在此时间之内,我们可以通过不同的方式来获取此运行时类
        System.out.println(clazz01);   //class com.wcc.reflect.Person
        System.out.println(clazz02);   //class com.wcc.reflect.Person
        System.out.println(clazz03);   // class com.wcc.reflect.Person
        System.out.println(clazz04 );   // class com.wcc.reflect.Person

    }
}

2. 反射中的常用方法

1.定义一个类

/**
 * @Author xiaoqi
 * @Date 
 */
public class Person {

    private String name;
    public int age;

    public Person(){

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

    @Override
    public String toString () {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public void show(){
        System.out.println("我是公开的show方法");
    }
    private void test(String name){
        System.out.println("我是私有的test方法"+name);
    }
}

2. 进行反射方法的测试

/**
 * @Author xiaoqi
 * @Date
 * 反射中的常用方法
 */
public class PersonTest001 {
    /**
     * 以前对于Person的操作
     * 不能通过psrson对象来调用私有的方法,以及私有的构造器
     */
    @Test
    public void test01(){
        Person p = new Person("tom",10);
        System.out.println(p);
        p.show();
    }
    /**
     * 利用反射,对于Person的操作
     */
    @Test
    public void test002() throws Exception {
//        描述Pserson类的一个类   Class类
        Class<Person> clazz = Person.class;
//        利用反射获取对象
//        获取构造器   返回一个 Constructor 对象,它表示Class 对象所表示的类的指定公共构造方法。
        Constructor<Person> constructor = clazz.getConstructor(String.class, int.class);
        Person p = constructor.newInstance("tom", 12);
        System.out.println(p);

//        通过反射,来调用对象指定的方法,属性
//        获取名称是age的属性
        Field age = clazz.getField("age");
//        给属性赋值
        age.set(p,10);
        System.out.println(p);
//        调用方法 传入的是方法的名称
        Method method = clazz.getDeclaredMethod("show");
//        意思是调用的是person对象的show方法
        method.invoke(p);
    }
    /**
     * 通过反射,可以调用类的私有的属性和方法
     */
    @Test
    public void test003() throws Exception {
//        获取Class类
        Class<Person> clazz = Person.class;
//        返回一个 Constructor 对象,该对象反映 Class 对象所表示的类或接口的指定构造方法。
        Constructor<Person> con = clazz.getDeclaredConstructor(String.class);
//        这个方法设置为true,就可以访问私有的变量,取消java语言访问检查
        con.setAccessible(true);
//        获取对象的实例
        Person per = con.newInstance("jerry");
        System.out.println(per);
//        返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。
        Field name = clazz.getDeclaredField("name");
        name.setAccessible(true);
//        第一个参数表示属性所属的对象,第二个参数表示修改后的属性值
        name.set(per,"wangzi");
        System.out.println(per);

//        调用私有方法
        /**
         * 第一个参数: 方法名
         * 第二个参数: 传入的参数类型
         */
        Method method = clazz.getDeclaredMethod("test", String.class);
        method.setAccessible(true);
        method.invoke(per,"chaochao");


    }
    /**
     * 反射中其他API的使用
     */
    @Test
    public void test004() throws Exception {
        Class<Person> clazz = Person.class;
//        通过Class类的对象,直接创建Person对象
        Person person = clazz.newInstance();
//        获取所有的构造方法
        Constructor<?>[] con = clazz.getDeclaredConstructors();
        for (Constructor<?> c :con){
            System.out.println(c);
        }
//        获取所有的属性
        Field[] fields = clazz.getDeclaredFields();
        for (Field f:fields){
            System.out.println(f);
        }
//        获取所有的方法
        Method[] methods = clazz.getDeclaredMethods();
        for (Method m :methods){
            System.out.println(m);
        }

    }
}

你可能感兴趣的:(javaSE)