Java的动态性支持学习二 反射机制 属性、方法、对象的操作

Java的动态性支持学习一 - 反射机制 概念概述
Java的动态性支持学习二 - 反射机制 属性、方法、对象的操作
Java的动态性支持学习三 - 反射机制 取消属性、方法、构造器的访问限制
Java的动态性支持学习四 - 反射调用的性能对比
Java的动态性支持学习五 - 方法句柄 概念和句柄类型
Java的动态性支持学习六 - 方法句柄 获取和调用
Java的动态性支持学习七 - 方法句柄调用的性能对比

这篇博文学习下通过反射操作属性、方法、对象。

属性 Filed

Filed类的对象代表成员变量,携带成员变量的信息,其中有几个重要的方法:

  • Object get(Object obj) 返回obj对象的成员变量值,返回的Object类型;
  • xxx getXxx(Object obj) 返回obj对象的成员变量值,其中xxx代表8种基本数据类型,返回为指定的数据类型;
  • set(Object obj, Object value) 设置obj对象的属性值;
  • setXxx(Object obj, xxx value)设置obj对象的属性值,其中xxx代表8种基本数据类型;
  • Class getType() 返回Field对象对应的成员变量的类型。如果成员变量为基本类型,则返回的是"<基本数据类型封装名>.TYPE"。

Demo:

package net.oseye;
import java.lang.reflect.*;

public class ReflectTest {
	public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException{
		User user=new User();
		user.name="osEye";
		Class c=user.getClass();
		Field field=c.getDeclaredField("name");
		System.out.println(field.get(user));
		field.set(user, "kevin");
		System.out.println(field.get(user));
	}
}

class User{
	public String name;	
}

输出:

osEye
kevin

方法 Method

Method类的对象代表一个方法,携带方法 ,其中最重要的方法是invoke,声明:Object invoke(Object obj, Object... args)

  • 不管实际对应的方返回值是什么类型,都返回Object类型。若返回值为基本类型,则返回对应封装类的对象;
  • obj参数指出要被调用方法所属的对象,若调用静态方法则用null;
  • args是方法的参数序列,若方法没有参数则传递空数组:new Object[0];

Demo:

package net.oseye;
import java.lang.reflect.*;

public class ReflectTest {

	public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
		User user=new User();
		user.name="osEye";
		Class c=user.getClass();
		Method mth=c.getDeclaredMethod("SayHello", String.class);
		mth.invoke(user, "kevin");
	}
}

class User{
	public String name;
	
	public void SayHello(String name){
		System.out.println(this.name+" say to "+name+": 'Hello'.");
	}	
}

输出:

osEye say to kevin: 'Hello'.

创建对象 Constructor

Constructor类的对象代表一个构造器,携带构造器的相关信息,其只要方法是newInstance,声明如下:Object newInstance(Object... initargs)

Demo:

package net.oseye;

public class ReflectTest {

	public static void main(String[] args) throws InstantiationException, IllegalAccessException{
		Class c=User.class;
		User user=(User) c.newInstance();
		user.name="oseEye";
		user.SayHello("kevin");
	}
}

class User{
	public String name;
	
	public void SayHello(String name){
		System.out.println(this.name+" say to "+name+": 'Hello'.");
	}	
}

输出:

oseEye say to kevin: 'Hello'.

顺便提下,数组比较特殊,它没有提供构造器,因此不能通过Class或Constructor类的newInstance方法创建数组,但可以使用java.lang.reflect.Array类中提供了动态创建数组的newInstance方法,如果需要可自行查看。

原文地址:https://www.cnblogs.com/zhaiqianfeng/p/4618320.html