[Reflect]Java反射机制详解

首先想要远程执行某一个类的某一个方法,或在程序执行中动态执行某一个类的某一个方法就要用到反射。

JAVA反射机制是在运行状态中,对于任意一个类 (class文件),都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个属性和方法;这种动态获取信息以及动态调用对象的方法的功能称为java语言的反射机制。 
一、如何得到反射类:(以Person类为栗子,文末贴出)

 1. Object类中的getClass()方法的。想要用这种方式,必须要明确具体的类,并创建对象。特点:麻烦

Person p=new Person();
Class clazz= p.getClass();

 2. 任何数据类型都具备一个静态的属性.class来获取其对应的Class对象。相对简单,但是还是要明确用到类中的静态成员。特点:扩展性不强

Class clazz2=Person.class;
 3. 一个类只可能是Class类的一个实例对象, 只要通过给定的类的字符串名称就可以获取该类,用Class类中的  forName 方法完成。 这种方式只要有具体名称即可。  特点: 方便,扩展性强

Class clazz4=Class.forName("reflect.Person");


二、对构造函数的操作

对构造函数的操作,在反射机制中有两种方法

1、针对无变量的构造方法,直接调用Class类中的newInstance()

Object obj=clazz.newInstance();//此时调用的是无参数构造函数

显示结果为:

无参构造函数...

2、针对带参数的构造方法,需要调用该Class对象的getConstructor()方法获得一个专属的Constructor的对象,再调用Constructor类中newInstance()方法。

Constructor<?> constructor=clazz.getConstructor(String.class,int.class);//获取到了指定的构造函数对象
Object obj1=constructor.newInstance("章北海",18);//通过该构造器对象的newInstance方法进行对象的初始化

显示结果为:

有参构造函数...章北海18

在这里需要说明的是只有两个类拥有newInstance()方法,分别是Class类和Constructor类。

Class类的newInstance()方法是不带参数的,而Constructor类的newInstance()方法是带参数的需要提供必要的参数。

三、对属性的操作

在java.lang.reflect.Field中,Field类封装了关于成员变量的操作。以下为部分方法

 ---getField()  得到指定名称的属性 (强调公有属性,包含继承下来的)     

---getFields()   得到所有属性(强调公有属性,包含继承下来的)  
 ---getDeclaredField()得到指定名称的属性 (所有属性,强调的本类中属性)
 
---getDeclaredFields()得到所有属性     (所有属性,强调的本类中属性)

----get(Object obj) 返回指定对象上此 Field 表示的字段的值。

  ----getModifiers() 以整数形式返回由此 Field 对象表示的字段的 Java 语言修饰符。
  ----getName() 返回此 Field 对象表示的字段的名称。
  ----getType() 返回一个 Class 对象,它标识了此 Field 对象所表示字段的声明类型。
  ----set(Object obj, Object value) 将指定对象变量上此 Field 对象表示的字段设置为指定的新值。  
   ----setAccessible(true);设置安全检查,如果设为true,表示可以进行修改字段值

Field field=clazz1.getField("name");//getField()只能获取公有的,运行会出错
Field field=clazz1.getDeclaredField("age");//getDeclaredField()只获取本类,但包含私有

//对私有字段的访问取消权限检查。暴力访问
		field.setAccessible(true);
		Object obj=clazz1.newInstance();
		field.set(obj, 22);
		Object o=field.get(obj);
		System.out.println(o);

显示结果为:

private int reflect.Person.age
无参构造函数...
22

四、对方法的操作

-----getMethod(String name, Class<?>... parameterTypes) 返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法 
-----getMethods() 返回一个包含某些 Method 对象的数组
---- getDeclaredMethod(String name, Class<?>... parameterTypes) 返回一个 Method 对象,它反映此 Class 对象本类中所有的方法
-----getDeclaredMethods() 返回一个包含所有DeclaredMethod对象的数组

Method[] method1=clazz2.getMethods();
		for(Method method:method1){
			System.out.println(method+"...getMethods()");
		}
Method[] method2=clazz2.getDeclaredMethods();
		for(Method method:method2){
			System.out.println(method+"...getDeclaredMethods()");
		}	
Method method=clazz2.getMethod("publicMethod", String.class,int.class);
Object obj=clazz2.newInstance();
method.invoke(obj, "云天明",8);
显示结果为:

public void reflect.Person.publicMethod(java.lang.String,int)...getMethods()
public void reflect.Person.show()...getMethods()
public static void reflect.Person.staticMethod()...getMethods()
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException...getMethods()
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException...getMethods()
public final void java.lang.Object.wait() throws java.lang.InterruptedException...getMethods()
public boolean java.lang.Object.equals(java.lang.Object)...getMethods()
public java.lang.String java.lang.Object.toString()...getMethods()
public native int java.lang.Object.hashCode()...getMethods()
public final native java.lang.Class java.lang.Object.getClass()...getMethods()
public final native void java.lang.Object.notify()...getMethods()
public final native void java.lang.Object.notifyAll()...getMethods()
public void reflect.Person.publicMethod(java.lang.String,int)...getDeclaredMethods()
public void reflect.Person.show()...getDeclaredMethods()
private void reflect.Person.privateMethod()...getDeclaredMethods()
public static void reflect.Person.staticMethod()...getDeclaredMethods()
无参构造函数...
公有的有参数成员方法...云天明:8
Person类:

package reflect;

public class Person {
	private String name;
	private int age;
	public Person(){
		System.out.println("无参构造函数...");
	}
	public Person(String name,int age){
		this.name=name;
		this.age=age;
		System.out.println("有参构造函数..."+name+age);
	}
	public void show(){
		System.out.println("公有的无参数成员方法..."+name+age);
	}
	private void privateMethod(){
		System.out.println("私有的无参数成员方法...");
	}
	public void publicMethod(String name,int age){
		System.out.println("公有的有参数成员方法..."+name+":"+age);
	}
	public static void staticMethod(){
		System.out.println("静态的无参数成员方法...");
	}
}






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值