Java的动态性支持学习一 反射机制 概念概述

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

反射是Java语言提供的一项非常吸引人的特性,利用反射可以在应用运行时对程序进行动态的控制。

反射技术中用到的特别重要的一个类就是java.lang.Class。Class对象携带类的相应信息,主要包括构造器、方法、成员变量等。其实在Java程序运行过程中,每个类被加载后都在内存中产生一个对应的Class类对象,普通应用程序中这个对象是由系统自己自动维护的,开发者无需关心。

虽然反射为Java提供了动态的能力,但也带来了性能的开销。比如调用同一个方法,使用反射来动态实现比直接在源代码中编写的方式大概慢一到两个数量级,所以请谨慎使用反射。

Class类有几个使用比较频繁的方法:

  • forName(String classname)和 forName(String classname,boolean initialze,ClassLoader loader)
    该方法返回给定串名相应的Class 对象。若给定一个类或接口的完整路径名,那么此方法将试图定位、装载和连接该类。若成功,返回该类对象。否则,抛出 ClassNotFoundException 异常。 例如,下面代码段返回名为java.lang.Thread 的运行 Class 描述器。Class t = Class.forName("java.lang.Thread") ;  此方法是需要指定类加载器的,当用到仅有一个String参数的forName方法时,Class对象将默认调用当前类加载器作为加载器和将第二参数为true。第二个参数说明:如果是false时,调用forName方法只是在命令类加载器载入该类,而不初始化该类的静态区块,只有当该类第一次实例化时,静态区块才被调用。当为true时,则载入时就调用静态区块。
  • getField(String) 获取类的指定名称的public类型属性,包括从祖先类中的继承的。
  • getFields() 获取类的public类型的属性,包括从祖先类中的继承的。
  • getDeclaredFields() 获取类的所有属性,包括public、protected、默认和private访问级别的属性,不包括从祖先类中的继承的。 
  • getMethods() 获取类的public类型的方法。 
  • getDeclaredMethods() 获取类的所有方法。
  • newInstance() 创建类的新实例。 

如果想了解更多可以查看Java doc的Class文档

获取Class实例的三种方式:

  1. 使用Class类的静态方法forName();
  2. 利用对象调用getClass()方法获取,java.lang.Object专门提供了getClass方法获取对象所在类对应的Class对象;
  3. 使用<类名>.class的方式来获取,这里的class可以看做是类的静态成员,表示执行此类对应的Class对象的引用。对于基本数据类型的封装类,还可以采用.TYPE来获取相对应的基本数据类型的Class实例;

通过Demo简单示例:

package net.oseye;

import java.lang.reflect.*;

public class ReflectTest {

	public static void main(String[] args) throws ClassNotFoundException {
		Class<?> c=Class.forName("net.oseye.User");
//		Class c=User.class;
//		Class c=new User().getClass();
		Field[] fileds=c.getDeclaredFields();
		System.out.print("通过反射获取的属性名:");
		for(Field f:fileds){
			System.out.print(f.getName()+"\t");
		}
		System.out.print("\r\n通过反射获取的方法:");
		for(Method m:c.getMethods()){
			System.out.println(m.toString());
		}
		System.out.print("通过反射获取的构造器:");
		for(Constructor<?> mc:c.getConstructors()){
			System.out.print(mc.getName()+"\t");
		}
	}
}

class User{
	private String name;
	public User(){}
	public User(String name){
		this.name=name;
	}	
	
	public void setName(String name){
		this.name=name;
	}
	public String getName(){
		return this.name;
	}
	
	public void SayHello(String name){
		System.out.println(this.name+" say to "+name+" 'Hello'.");
	}
	
}

输出:

通过反射获取的属性名:name	
通过反射获取的方法:public void net.oseye.User.SayHello(java.lang.String)
public java.lang.String net.oseye.User.getName()
public void net.oseye.User.setName(java.lang.String)
public final native java.lang.Class java.lang.Object.getClass()
public native int java.lang.Object.hashCode()
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
通过反射获取的构造器:net.oseye.User	net.oseye.User	
原文地址:https://www.cnblogs.com/zhaiqianfeng/p/4618274.html