java Reflection(反射)机制

在java的运行环境中,对于一个人任意的类,如果要获取这个类的所有属性和方法(公有的和私有的),并且能够调用这个类的任意方法,那么可以借助Java语言的反射(Reflection)机制来动态获取类的信息。

         Java反射机制提供的功能有:

1.在运行时候判构造一个类的对象

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

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

4.生成动态代理

5 在运行时调用任意一个对象的方法

软件开发人员进行单元测试有时候要访问类的非公有成员或方法,这时候就要利用好java的反射机制了。

但是访问类的私有变量和方法违反了 Java 语言封装性的基本规则,所以是否要用反射机制看具体情况。

访问类的私有变量和方法一般来说有2种方式:一种是直接修改权限修饰符,将private改成public,protected,或者直接将private修饰符删除。一种是借助反射和安全性管理器相结合的方式。

Java 运行时依靠一种安全性管理器来检验调用代码对某一特定的访问而言是否有足够的权限。具体来说,安全性管理器是 java.lang.SecurityManager 类或扩展自该类的一个类,且它在运行时检查某些应用程序操作的权限。换句话说,所有的对象访问在执行自身逻辑之前都必须委派给安全管理器,当访问受到安全性管理器的控制,应用程序就只能执行那些由相关安全策略特别准许的操作。因此安全管理器一旦启动可以为代码提供足够的保护。默认情况下,安全性管理器是没有被设置的,除非代码明确地安装一个默认的或定制的安全管理器,否则运行时的访问控制检查并不起作用。我们可以通过这一点在运行时避开 Java 的访问控制检查,达到我们访问非公有成员变量或方法的目的。为能访问我们需要的非公有成员,我们还需要使用 Java 反射技术。Java 反射是一种强大的工具,它使我们可以在运行时装配代码,而无需在对象之间进行源代码链接,从而使代码更具灵活性。在编译时,Java 编译程序保证了私有成员的私有特性,从而一个类的私有方法和私有成员变量不能被其他类静态引用。然而,通过 Java 反射机制使得我们可以在运行时查询以及访问变量和方法。由于反射是动态的,因此编译时的检查就不再起作用了。这种方式的缺点是:1.性能问题,用于字段和方法接入时反射要远慢于直接代码。第二个是权限问题,有些涉及 Java 安全的程序代码并没有修改安全管理器的权限,此时本方法失效。

public class Test {
	public static void main(String[] args) {
		String a="com.ccc.Day0409.Reflection.Test";
		String m="m";
		
		Class<String> c=String.class;
		Class<List> c1=List.class;
		Test t=new Test();
		
		Class<? extends Test> tc=t.getClass();
		System.out.println("t.getClass()= "+tc);//t.getClass()= class com.ccc.Day0409.Reflection.Test
		
		try {
			//获取class com.ccc.Day0409.Reflection.Test对象
			Class<?> ca=Class.forName(a);//Class.forName(a)=class com.ccc.Day0409.Reflection.Test
			System.out.println("Class.forName(a)="+ca);
			System.out.println();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		Class<ArrayList> al=ArrayList.class;
		System.out.println("ArrayList.class="+al.getName());
		Class<?>[] aa=al.getInterfaces();
		for(Class<?> class1:aa){
			System.out.println("class1.getSimpleName()="+class1.getSimpleName());
			System.out.println("class1.getName()="+class1.getName());
		}
		
	}
}

使用反射调用方法的步骤:

      1)要想使用反射,首先需要获得待处理类或对象所对应的Class对象。

      2)获取某个类或某个对象所对应的Class对象的常用的3种方式:

a).类名.class

  b)getClass()方法

c)Class.forName()方法

getName(): 获得类的名称,包括包名
getSimpleName(): 获得类的名称,不包括包名
getSuperClass(): 获得本类的父类的class对象
getInterfaces():获得本类所实现的所有接口的class对象


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值