java之反射

反射机制是在运行状态中:

1、对任意一个类,都能知道这个类的所有属性和方法,

2、对任意一个对象,都能调用他的任意一个方法和属性方法和属性。

 

反射提供的功能:

1、在运行时判断任意一个对象所属的类

2、在运行时构造任意一个类的对象

3、在运行时判断任意一个类所具有的成员变量和方法

4、在运行时调用任意一个类的方法

5、生成动态代理

 

获取反射对象的入口:Class  (三种方法)

1、Class.forname("全类名")

2、类名.class

3、对象.getClass()

 

 

 

下面用一些具体的代码来体现反射的功能

1、创建一个接口

package com;
public interface MyInterface {
    void interfaceMethod();
}

2、创建一个实现该接口的类

package com;

public class Person implements MyInterface{
    private Integer id;
    private Integer age;
    private String name;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public void interfaceMethod() {
        System.out.println("i am a person");
    }
    private void privateMethod() {
        System.out.println("我是一个私有的方法");
    }
    private void privateMethod2(String str) {
        System.out.println(str);
    }
}

 

下面是一些具体操作的实例

(1)通过3总方式获取反射入口

public static void demo1{
    try {
            Class<?> personClass = Class.forName("com.Person");
            System.out.println(personClass);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        //2、通过类名的.class获取反射入口
        Class<?> personClass2 = Person.class;
        System.out.println(personClass2);
        //3、通过对象.getClass获取反射入口
        Person person = new Person();
        Class<?> personClass3 = person.getClass();
        System.out.println(personClass3);
}    

(2)、获取类的方法

public static void testDemo2() {
        Class<?> personClass = null;
        try {
            personClass = Class.forName("com.Person");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
//        获取所有的公有方法
//        1、本类、父类及接口中的所有方法,
//        2、符合访问修饰符的所有方法
        Method[] methods = personClass.getMethods();
        for(Method me : methods) {
            System.out.println(me);
        }
        System.out.println("======================这是一个分介线");
        //获取当前类的所有方法,(1、只能是当前类,2、忽略访问修饰符限制)
        Method[] declaredMethods = personClass.getDeclaredMethods();
        for(Method me : declaredMethods) {
            System.out.println(me);
        }
    }

打印结果

public java.lang.String com.Person.getName()
public void com.Person.setName(java.lang.String)
public java.lang.Integer com.Person.getId()
public java.lang.Integer com.Person.getAge()
public void com.Person.setId(java.lang.Integer)
public void com.Person.setAge(java.lang.Integer)
public void com.Person.interfaceMethod()
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
======================这是一个分介线
public java.lang.String com.Person.getName()
public void com.Person.setName(java.lang.String)
public java.lang.Integer com.Person.getId()
public java.lang.Integer com.Person.getAge()
private void com.Person.privateMethod()
private void com.Person.privateMethod2(java.lang.String)
public void com.Person.setId(java.lang.Integer)
public void com.Person.setAge(java.lang.Integer)
public void com.Person.interfaceMethod()

 

 (2)操作类的属性以及方法。

 

public static void testDemo3() {
        Class<?> personClass = null;
        try {
            personClass = Class.forName("com.Person");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        try {
            //获取当前反射所代表类(接口)的对象(实例)
            Person person = (Person) personClass.newInstance();
            Field field = personClass.getDeclaredField("age");
            //访问的是private修饰的id,但是private是私有的
            //修改属性的访问权限:使用反射时,如果因为访问修饰符造成异常,可以通过field.setAccessible()将这个属性值设置为true,来获得访问权限
            field.setAccessible(true);

       // 对象、 方法 和 值 field.set(person,
18);//把这个对象的id属性设置微18 System.out.println(person.getAge()); System.out.println("=========================================="); //参数分别代表方法 和 方法的参数,没有参数时为null Method me = personClass.getDeclaredMethod("privateMethod", null); //同样的想要获取私有方法的访问权限,也需要设置下这个属性 me.setAccessible(true); me.invoke(person, null); Method me2 = personClass.getDeclaredMethod("privateMethod2", String.class); me2.setAccessible(true); me2.invoke(person, "song"); } catch (Exception e) { e.printStackTrace(); } }

打印结果

18
==========================================
我是一个私有的方法
song

 

同样可以通过反射获取类的公共构造方法、本类构造方法等等,和上面属性和方法的方式类似,加了Declared的方法是获取本类的所有的,未加的是获取包括本类父类和接口的公共的(public)

可以用构造方法来创建对象(newInstance)。(懒得粘代码,直接看图片吧)

posted @ 2019-03-05 23:24  宋songsong  阅读(220)  评论(0编辑  收藏  举报