java反射系列一

一.概念认知
1.1  ●Java Reflection
Reflection (反射)是被视为动态语言的关键,
反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,
并能直接操作任意对象的内部属性及方法

1.2 ●Java反射机制提供的功能
➢在运行时判断任意一 个对象所属的类
➢在运行时构造任意-个类的对象
➢在运行时判断任意一个类所具有的成员变量和方法
➢在运行时调用任意个对象的成员变量和方法
➢生成动态代理
 
1.3  Java反射机制研究及应用
●反射相关的主要API:
➢java.lang.Class:代表一 个类
➢java.lang.reflect,Method:代表 类的方法
➢java.lang.reflect.Field:代表 类的成员变量
➢java.lang.reflect.Constructor:代表 类的构造方法

二.代码示例
package reflect;

public class Person {
    public String name;
    private int age;
    public Person() {
        super();
        // TODO Auto-generated constructor stub
    }
    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public void show() {
        System.out.println("我是巫妖果子");
    }
    public void display(String nation) {
        System.out.println("我的国籍是: "+nation);
    }
    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }
    
}

 

package reflect;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class TestReflection {
    public static void main(String[] args) throws Exception {
        TestReflection t = new TestReflection();
        t.test2();
    }
     //反射思想.创建一个类的对象.并调用其中的结构
    public void test2() throws Exception {
        //此代码指向Person类,其所有属性.方法均暴露
        ①Class clazz = Person.class;
        
        /*
         * 1.创建clazz对应的运行时类Person类的对象
         * public T newInstance()
              throws InstantiationException,
                     IllegalAccessException创建由此类对象表示的类的新实例。 
         */
        ②Person p = (Person)clazz.newInstance();
        System.out.println(p);
        /*
         * getField(String name) 
         * 返回一个 Field对象,它反映此表示的类或接口的指定公共成员字段 类对象。 
         */
        ③Field f1 = clazz.getField("name");
        /*
         * set(Object obj, Object value) 
         * 将指定对象参数上的此 Field对象表示的字段设置为指定的新值。
         */
        ④f1.set(p, "巫妖果子");
        System.out.println(p);
        /*
         * 2.私有属性
         * getDeclaredField(String name) 返回一个 Field对象,
         * 它反映此表示的类或接口的指定已声明字段 类对象。
         */
        ⑤Field f2 = clazz.getDeclaredField("age");
        ⑥f2.setAccessible(true);
        f2.set(p, 20);
        System.out.println(p);
        
        /*
         * 3.通过反射调用运行时类的指定的方法
         *getMethods() 返回包含一个数组 方法对象反射由此表示的类或接口的所有公共方法 类对象,
         *包括那些由类或接口和那些从超类和超接口继承的声明
         */
        ⑦Method m1 = clazz.getMethod("display", String.class);
        /*
         * invoke(Object obj, Object... args) 
         * 在具有指定参数的 方法对象上调用此 方法对象表示的底层方法。
         */
        ⑧m1.invoke(p, "中国");
        
        ⑨Method m2 = clazz.getMethod("show");
        m2.invoke(p);
    }
    
    //面向对象的思想.创建一个类的对象,并调用其中的方法.属性
    public void test1(){
        Person p = new Person();
        p.setAge(20);
        p.setName("巫妖果子");
        System.out.println(p);
        p.show();
        p.display("中国");
    }
}

程序分析:①②处相当于面向对象的

Person p = new Person();
这行代码,创建实例

③处是指定Person中的属性(公共权限)④处设置属性值⑤处由于age属性的权限是私有的,所以

getDeclaredField("age")

起声明作用⑥仅仅是这样还不足以设置私有属性,故有此行代码⑦处指定有参方法⑧处传参

⑨处是无参方法

 

 
posted @ 2019-01-28 13:33  静心*尽力  阅读(159)  评论(0编辑  收藏  举报