Java之反射(20190108)

2019-01-09  本文已影响3人  watayouxiang

Java之反射(20190108)

源码:https://github.com/watayouxiang/JavaDemo

Person.java

package com.wata.javademo.reflect;

public class Person {
    private int age;
    private String name;
    
    public Person() {
        super();
    }

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

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

1. 获取字节码的三种方式

/**
 * 获取字节码的三种方式
 * 
 * @param args
 */
public static void main(String[] args) {

    // 1. Object类中的getClass()方法
    Person person = new Person();
    Class personClass1 = person.getClass();

    // 2. 任何数据类型都具有一个静态属性.class来获取对应的Class对象
    Class personClass2 = Person.class;

    // 3. 通过给定类的字符串名称获取(最常用)
    try {
        Class personClass3 = Class.forName("com.wata.javademo.reflect.Person");
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }

}

2. 获取Class中的构造函数

/**
 * 获取Class中的构造函数
 * 
 * @param args
 * @throws Exception
 */
public static void main(String[] args) throws Exception {

    // 寻找该名称类文件,并加载进内存,产生Class对象
    Class personClazz = Class.forName("com.wata.javademo.reflect.Person");

    // 通过空参数的构造函数进行对象的初始化
    Object person = personClazz.newInstance();
    System.out.println(person);

    // 获取指定的构造函数
    Constructor personConstructor = personClazz.getConstructor(int.class, String.class);
    // 通过该构造器newInstance()方法进行对象的初始化
    Object person2 = personConstructor.newInstance(18, "wata");
    System.out.println(person2);

}

3. 获取Class中的字段

/**
 * 获取Class中的字段
 * @param args
 * @throws Exception 
 */
public static void main(String[] args) throws Exception {

    // 获取Person的字节码
    Class personClazz = Class.forName("com.wata.javademo.reflect.Person");
    // 实例化Person对象
    Constructor personConstructor = personClazz.getConstructor(int.class, String.class);
    Object person = personConstructor.newInstance(21, "猪头");
    System.out.println(person);

    // 只能获取共有的
    // Field field = clazz.getField("name");

    // 获取Person的age字段(只能获取本类,但包含私有)
    Field nameField = personClazz.getDeclaredField("name");
    // 对私有字段的访问需要取消限制检查(也叫“暴力访问”)
    nameField.setAccessible(true);

    // 获取Person对象的Field值
    Object name = nameField.get(person);
    System.out.println(name);       
}

4. 获取Class中的方法

/**
 * 获取Class中的方法
 * 
 * @param args
 * @throws Exception
 */
public static void main(String[] args) throws Exception {

    Class personClazz = Class.forName("com.wata.javademo.reflect.Person");
    Constructor personConstructor = personClazz.getConstructor(int.class, String.class);
    Object person = personConstructor.newInstance(18, "猪头");

    // 获取所有的公有的方法
    Method[] methods = personClazz.getMethods();
    for (Method method : methods) {
        System.out.println(method);
    }

    System.out.println("=====================================");

    // 只获取本类中所有的方法,包含私有方法
    Method[] declaredMethods = personClazz.getDeclaredMethods();
    for (Method declaredMethod : declaredMethods) {
        System.out.println(declaredMethod);
    }

    System.out.println("=====================================");

    // 调用无参公有方法
    Method getNameMethod = personClazz.getMethod("getName", null);
    Object name = getNameMethod.invoke(person, null);
    System.out.println("name = " + name);

    System.out.println("=====================================");

    // 调用有参公有方法
    Method setNameMethod = personClazz.getMethod("setName", String.class);
    setNameMethod.invoke(person, "猪头头很大");
    System.out.println(person);

    System.out.println("=====================================");

    // 调用有参私有方法
    Method sayMethod = personClazz.getDeclaredMethod("say", String.class);
    sayMethod.setAccessible(true);// 取消访问限制,又叫“暴力访问”
    sayMethod.invoke(person, "猪年快乐~");

}
上一篇 下一篇

猜你喜欢

热点阅读