Java反射Method和Field简单实例

目录

定义       

使用方法

1.Field

2.Method

3.简单实例

 


定义       

JAVA反射机制是在运行状态中,对于任意一个实体类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

 JAVA反射的方法主要有三种:Class,Method,Field。这里主要简单使用一下Method和Field方法。

 

使用方法

1.Field

获取对象的属性,给对象属性赋新值

(1)获取Field的常用方法:

getFields():获取public类型的属性(也可以获取到父类的public修饰的属性)并返回一个Field数组;

getDeclaredFields(): 获取所有属性(包括public、protected、default、private权限类型,但不能获取继承父类的属性)并返回一个Field数组;

getField(String name):获取特定的public对象属性,name为属性名;

getDeclaredField(String name): 获取特定的对象属性,属性的访问权限可以是public、protected、default、private,name为属性名;

(2)Field对象的常用方法:

getType():返回Field对象的类型

getName():返回Field对象的名字

set(Object obj,Object value):设置对象属性的值,obj为实例对象,value为要为属性设置的新值

 

2.Method

获取对象方法,执行对象方法

继承的方法(包括重载、重写和隐藏的)会被编译器强制执行,这些方法都无法反射。

(1)获取Method对象的方法

getMethod(String name,Object type):获取特定的public对象方法,name为方法名,type为参数类型;

getDeclaredMethod(String name,Object type): 获取特定的对象方法,属性的访问权限可以是public、protected、default、private,name为方法名,type为参数类型;

(2)Method对象的常用方法:

getReturntype():获取Method对象返回类型

getName():返回Method对象的名字

invoke(Object obj,Object value):执行对象方法,obj为实例对象,value为方法参数,没有参数写null

(3)提示

    invoke方法的参数和返回类型必须是Object类型的,这就意味着必须进行多次的类型 转化,这样势必会造成代码出错几率。不仅如此,使用反射获得方法指针的代码要比仅仅直接调用方法慢一些。

 

3.简单实例

公用对象People

public class People {

    public String name = "小白";

    //类构造方法
    public People(String name){
        this.name = name;
    }

    //属性的get,set方法
    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ReflectTest {
    public static void main(String[] args) {

        //创建一个People类对象
        People people = new People("小白");
        System.out.println("初始化后name值:"+people.getName());

        //初始化
        Field attribute = null;
        Method method = null;

        System.out.println("Field方法执行结果;");
        //用Field对象获取people对象的属性信息
        try {
            //先用getClass方法获取对象实例,再用getField方法获取name属性的Field类对象
            attribute = people.getClass().getField("name");
            //getName方法获取name属性名
            String attrName = attribute.getName();
            //getType方法获取name属性类型
            String attrType = attribute.getType().toString();
            System.out.println("属性名:"+attrName+"\n属性类型:"+attrType+"\n属性值:"+people.getName());
            //set方法重新给name属性赋值
            attribute.set(people,"大白");
            System.out.println("用set方法重新赋值后name值:"+people.getName());
        }catch(Exception e){
            e.printStackTrace();
        }
        System.out.println("Method方法执行结果;");
        //用Method对象获取people对象的方法信息
        try{
            //用getMethod方法获取setName方法的Method对象
            method = people.getClass().getDeclaredMethod("setName",String.class);
            //用Method的getName方法获取setName方法的方法名
            String methodName = method.getName();
            //用Method的getReturnType方法获取setName方法的返回值类型
            String methodType = method.getReturnType().toString();
            System.out.println("方法名:"+methodName+"\n方法类型:"+methodType);
            //用Method的invoke方法执行该方法
            method.invoke(people,"中白");
            System.out.println("invoke方法执行后name值:"+people.getName());
        }catch(Exception e){
            e.printStackTrace();
        }

    }
}

控制台输出结果

初始化后name值:小白
Field方法执行结果;
属性名:name
属性类型:class java.lang.String
属性值:小白
用set方法重新赋值后name值:大白
Method方法执行结果;
方法名:setName
方法类型:void
invoke方法执行后name值:中白

4.使用泛型编写泛型数组代码

1)首先获取数组的类对象

2)确认它是一个数组

3)使用Class类(只能定义表示数组的类对象)的getComponent方法确定数组对应类型

4)使用Array类中的静态方法newInstance方法构造新的数组,它有两个参数,一个是数组元素类型,一个是数组长度。

5)用System类中的arraycopy方法将原来数组的数据copy进新数组中,变相实现数据扩容。

import java.lang.reflect.Array;
import java.util.Arrays;

public class ReflectTest {

    //泛型数组copy正确方法
    public static Object goodCopyOf(Object a,int newLength){
        Class c1 = a.getClass();
        if(!c1.isArray())
            return null;
        Class componentType = c1.getComponentType();
        int length = Array.getLength(a);
        Object newArray = Array.newInstance(componentType,newLength);
        System.arraycopy(a,0,newArray,0,Math.min(length,newLength));
        return newArray;
    }

    //泛型数组copy错误方法
    public static Object[] badCopy(Object[] a, int newLength){
        Object[] newArray = new Object[newLength];
        System.arraycopy(a,0,newArray,0,Math.min(a.length,newLength));
        return newArray;
    }

    public static void main(String[] args) {
        int [] a = {1,2,3};
        a = (int[])goodCopyOf(a,10);
        System.out.println(Arrays.toString (a));
        String b[] = {"a","b","c"};
        b = (String[])goodCopyOf(b,10);
        System.out.println(Arrays.toString(b));

        System.out.println("This is a bad copy method!");
        b = (String[])badCopy(b,10);//抛出错误:java.lang.ClassCastException
    }

}

 

你可能感兴趣的:(Java基础)