JAVA中的反射

JAVA中的反射是什么?

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.


反射的使用

 

获取Class对象的三种方式

1 Object ——> getClass();
2 任何数据类型(包括基本数据类型)都有一个“静态”的class属性
3 通过Class类的静态方法:forName(String  className)(常用)

我们先通过一个例子分别对这三种获取class进行实现

package reflect2;

/**
 * 获取Class对象的三种方式
 * 1 Object ——> getClass();
 * 2 任何数据类型(包括基本数据类型)都有一个“静态”的class属性
 * 3 通过Class类的静态方法:forName(String  className)(常用)
 *
 */
public class Fanshe {
	public static void main(String[] args) {
		//第一种方式获取Class对象  
		Student stu1 = new Student();//这一new 产生一个Student对象,一个Class对象。
		Class stuClass = stu1.getClass();//获取Class对象
		System.out.println(stuClass.getName());
		System.out.println(stuClass);
		
		//第二种方式获取Class对象
		Class stuClass2 = Student.class;
		System.out.println(stuClass == stuClass2);//判断第一种方式获取的Class对象和第二种方式获取的是否是同一个
		System.out.println(stuClass2);
		//第三种方式获取Class对象
		try {
			Class stuClass3 = Class.forName("reflect2.Student");//注意此字符串必须是真实路径,就是带包名的类路径,包名.类名
			System.out.println(stuClass3 == stuClass2);//判断三种方式是否获取的是同一个Class对象
			System.out.println(stuClass3);
		} catch (ClassNotFoundException e) {
			System.out.print("error");
			//e.printStackTrace();
		}
		
		
		
		
		
	}
}
package reflect2;

public class Student {
	
	//---------------构造方法-------------------
	//(默认的构造方法)
	Student(String str){
		System.out.println("(默认)的构造方法 s = " + str);
	}
	
	//无参构造方法
	public Student(){
		System.out.println("调用了公有、无参构造方法执行了。。。");
	}
	
	//有一个参数的构造方法
	public Student(char name){
		System.out.println("姓名:" + name);
	}
	
	//有多个参数的构造方法
	public Student(String name ,int age){
		System.out.println("姓名:"+name+"年龄:"+ age);//这的执行效率有问题,以后解决。
	}
	
	//受保护的构造方法
	protected Student(boolean n){
		System.out.println("受保护的构造方法 n = " + n);
	}
	
	//私有构造方法
	private Student(int age){
		System.out.println("私有的构造方法   年龄:"+ age);
	}
 
}

执行后,

发现三种方法都可以成功调用class方法。因为Object类中的getClass方法、因为所有类都继承Object类。从而调用Object类来获取。

三种方式常用第三种,第一种对象都有了还要反射干什么。第二种需要导入类的包,依赖太强,不导包就抛编译错误。一般都第三种,一个字符串可以传入也可写在配置文件中等多种方法

除此之外还有一些其他的方法需要用到

static Class forName(String className)返回描述类名为className的Class对象

Object newInstance() 返回这个类的新实例

Object newInstance(Object[] args)  构造一个这个构造器所属类的新实例

参数 args 这是提供构造器的参数。

void printStackTrace()  将Throwable对象和栈的轨迹输出到便标准错误流

Field[] getFields() 

Field[] getDeclaredFields() 

getFields方法也将返回包含Field对象的数组,这些对象记录了这个类的全部公有域

getDeclaredFields方法也将返回包含Field对象的数组,这些对象记录了这个类的全部域

Method[] getMethods()

Method[] getDeclaredMethods()

返回包含Method对象的数组,getMethods方法将返回所有的共有方法,包括从超类继承来的公有方法。

getDeclaredMethods返回这个类的全部方法,但是不包括从超类继承来的方法。

Constructor[] getConstructors()

Constructor[] getDeclaredConstructors()

返回包含Constructor对象的数组,其中包含Class对象描述的类的所有公有构造器(getConstructors)。或所有构造器

Class getDeclaringClass()
返回一个用于描述类中定义的构造器方法或者与的Class对象

Class getExceptionTypes() 在Constructor和Method类返回一个用于描述方法抛射出异常类型的Class对象数组

int getModifiers() 返回一个用于描述构造器 方法或者与的修饰符的整形数据,使用Method可以分析这个返回值

String getName  返回一个用于描述构造器 方法或者与的字符串

Class[] getParameterTypes() 在Constructor和Method类返回一个用于描述参数类型的Class对象数组

Class[] getReturnType()在Method类返回一个用于描述返回类型的Class对象

上面的一些实现

package reflection;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Scanner;

public class ReflectionTest extends ReflectionTestFather{

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String name;
		if(args.length>0) name=args[0];
		else {
			Scanner in=new Scanner(System.in);
			System.out.println("Enter class name (e.g. java.util.Date):");
			name=in.next();
			
		}
		try {
			Class cl=Class.forName(name);
			Class supercl=cl.getSuperclass();
			String modifiers=Modifier.toString(cl.getModifiers());
			if(modifiers.length()>0) System.out.println(modifiers+"");
			System.out.println("class"+name);
			if(supercl!=null&&supercl!=Object.class)System.out.println("extends"+supercl.getName());
			System.out.println("\n{\n");
			printConstructors(cl);
			System.out.println();
			printMethods(cl);
			System.out.println();
			printFields(cl);
			System.out.println("}");
		}
		catch(ClassNotFoundException e){
			e.printStackTrace();
		}
		System.exit(0);
	}

	
	
	public static void printConstructors(Class cl){
		Constructor[] constructors=cl.getDeclaredConstructors();
		for(Constructor c:constructors)
		{
			String name=c.getName();
			System.out.println("  ");
			String modifiers=Modifier.toString(c.getModifiers());
			if(modifiers.length()>0)
				System.out.println(modifiers+"");
				System.out.println(name+"(");
				Class[] paramTypes=c.getParameterTypes();
			for(int j=0;j<paramTypes.length;j++)
			{
				if(j>0)
					System.out.println(",");
				System.out.println(paramTypes[j].getName());
			}	
			System.out.println(");");
		}
		
	}
	
	public static void printMethods(Class cl) 
	{
		Method[] methods= cl.getMethods();
		for(Method m:methods)
		{
			Class retType= m.getReturnType();
			String name=m.getName();
			System.out.println("   ");
			String modifiers=Modifier.toString(m.getModifiers());
			if(modifiers.length()>0)	
				System.out.println(modifiers +"  ");
			System.out.println(retType.getName()+" "+name+"(");
			Class[] paramTypes=m.getParameterTypes();
			for(int j = 0;j<paramTypes.length;j++)
			{
				if(j>0)
					System.out.println(",  ");
				System.out.println(paramTypes[j].getName());
			}
			System.out.println(");");
		}
	}
	public static void printFields(Class cl) {
		Field[] fields=cl.getFields();
		for(Field f:fields)
		{
			Class type=f.getType();
			String name=f.getName();
			System.out.println("   ");
			String modifiers=Modifier.toString(f.getModifiers());
			if(modifiers.length()>0)
				System.out.println(modifiers+"  ");
			System.out.println(type.getName()+" "+name+";");
		}
	}

}
package reflection;

public class ReflectionTestFather {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int key=0;

	}
	public  void tryTest() {
		System.out.println("由父类继承的方法");
	}
	public ReflectionTestFather() {
		System.out.println("这是父类的构造器");
	}
	public ReflectionTestFather(String key) {
		System.out.println("这是父类的构造器");
	}
}

执行输入:reflection.ReflectionTest

回车键结果为:

Enter class name (e.g. java.util.Date):
reflection.ReflectionTest
public
classreflection.ReflectionTest
extendsreflection.ReflectionTestFather

{

  
public
reflection.ReflectionTest(
);

   
public static  
void main(
[Ljava.lang.String;
);
   
public static  
void printConstructors(
java.lang.Class
);
   
public static  
void printMethods(
java.lang.Class
);
   
public static  
void printFields(
java.lang.Class
);
   
public  
void tryTest(
);
   
public final native  
void wait(
long
);
   
public final  
void wait(
long
,  
int
);
   
public final  
void wait(
);
   
public  
boolean equals(
java.lang.Object
);
   
public  
java.lang.String toString(
);
   
public native  
int hashCode(
);
   
public final native  
java.lang.Class getClass(
);
   
public final native  
void notify(
);
   
public final native  
void notifyAll(
);

}


本文参考于原文:https://blog.csdn.net/sinat_38259539/article/details/71799078 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值