java反射

一、反射的概述

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

二、获取class对象

要使用反射,我们首先获取这个类的class对象,获取class对象有三种方法:

1.类名.class;

Class stringClass = String.class;

2.类的对象名.getClass();

String s="";
Class stringClass1 = s.getClass();

3.Class.forName("类的全限定名");

Class stringClass2 = Class.forName("java.lang.String");

三、反射的使用

获取了class对象后,我们就可以使用class提供的各种方法来获取我们所需要的各种信息。

测试类

package com;

public class ReflectDemo {
	
	public ReflectDemo(){
		
	}
	
	public ReflectDemo(String a){
		
	}
	
	private ReflectDemo(int message){
		
	}
	
	protected ReflectDemo(char c){
		
	}
	
	private static char c = 'q';	
	private int a = 10;
	public String b = "我啊";
	public static byte d = 1;	
	public long lo = 147L;
	
	public void fun(){
		System.out.println("fun");
	}
	private void demo(String mes){
		System.out.println("私有方法"+mes);
	}
	
	protected String mad(){
		return "ada";
	}
	
	private static void stafun(){
		
	}
	
	public static void pubfun(){
		
	}
	

}

构造方法

----------------------------------------------------------------------------------------------------------------------------------

1. 获取共有的构造方法。

Class re = ReflectDemo.class;
Constructor a[] =  re.getConstructors();		
for (Constructor constructor : a) {
	System.out.println(constructor);
}

2. 获取所有的构造方法。

Class re = ReflectDemo.class;
Constructor a[] =  re.getDeclaredConstructors();
		
for (Constructor constructor : a) {
	System.out.println(constructor);
}

3. 获取单个私有的构造方法。(可以获取私有、公有、保护、默认等所有的单个构造方法)

Class re = ReflectDemo.class;
Constructor a =  re.getDeclaredConstructor(int.class);
System.out.println(a);

4. 获取单个公有的构造方法。

Class re = ReflectDemo.class;
Constructor a =  re.getConstructor();
System.out.println(a);

实例字段

----------------------------------------------------------------------------------------------------------------------------------

1. 获取公共单个静态字段

Class re = ReflectDemo.class;		
Field f = re.getField("d");
System.out.println(f.get(f));

2. 获取所有字段

Class re = ReflectDemo.class;				
Field f[] = re.getDeclaredFields();
for (Field field : f) {
	System.out.println(field);
}

3. 获取私有字段

Class re = ReflectDemo.class;				
Field f = re.getDeclaredField("a");
System.out.println(f);

4. 获取所有公共字段

Class re = ReflectDemo.class;				
Field f[] = re.getFields();		
for (Field field : f) {
	System.out.println(field);
}

获取方法

----------------------------------------------------------------------------------------------------------------------------------

1. 获取所有公共方法(包括继承的所有公共方法)

Class re = ReflectDemo.class;				
Method m[] = re.getMethods();
		
for (Method method : m) {
	System.out.println(method);
}

2. 获取所有方法(不包括继承的方法,只包含自己声明的方法)

Class re = ReflectDemo.class;				
Method m[] = re.getDeclaredMethods();
		
for (Method method : m) {
	System.out.println(method);
}
3. 获取单个公共方法(包含继承的公共方法)
Class re = ReflectDemo.class;				
		
		Method m = re.getMethod("wait");
		
		System.out.println(m);

4. 获取单个方法(只有自己类,不包含继承)

Class re = ReflectDemo.class;				
		
Method m = re.getDeclaredMethod("demo", String.class);
		
System.out.println(m);
总结上面的,反射可以获取一个类的所有属性和方法。


4.2. getDeclaredFields的实现

在JDK源码中,可以知道class.getDeclaredFields()方法实际调用的是native方法getDeclaredFields0(),它在JVM主要实现步骤如下

  1. 根据Class结构体信息,获取field_countfields[]字段,这个字段早已在load过程中被放入了
  2. 根据field_count的大小分配内存、创建数组
  3. 将数组进行forEach循环,通过fields[]中的信息依次创建Object对象
  4. 返回数组指针

主要慢在如下方面

  1. 创建、计算、分配数组对象
  2. 对字段进行循环赋值

4.3. Method.invoke的实现

以下为无同步、无异常的情况下调用的步骤

  1. 创建Frame
  2. 如果对象flag为native,交给native_handler进行处理
  3. 在frame中执行java代码
  4. 弹出Frame
  5. 返回执行结果的指针

主要慢在如下方面

  1. 需要完全执行ByteCode而缺少JIT等优化
  2. 检查参数非常多,这些本来可以在编译器或者加载时完成

4.4. class.newInstance的实现

  1. 检测权限、预分配空间大小等参数
  2. 创建Object对象,并分配空间
  3. 通过Method.invoke调用构造函数(<init>())
  4. 返回Object指针
参考: http://www.importnew.com/21211.html


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值