java反射机制

在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法?

答案是肯定的。

这种动态获取类的信息以及动态调用对象的方法的功能来自于Java语言的反射(Reflection)机制

来通过代码来看看java反射机制的使用。

package com.lql.demo;


import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;




public class test2 {


<span style="white-space:pre">	</span>
<span style="white-space:pre">	</span>public static void main(String[] args) {
<span style="white-space:pre">		</span>
<span style="white-space:pre">		</span>String str = new String();
<span style="white-space:pre">		</span>System.out.println(str.getClass());//通过getClass()获取对象的类
<span style="white-space:pre">		</span>
<span style="white-space:pre">		</span>try {
<span style="white-space:pre">			</span>Class class1 = Class.forName("java.util.Date");//通过forName("包名+类名"),指定包下的类
<span style="white-space:pre">			</span>System.out.println(class1);
<span style="white-space:pre">			</span>
<span style="white-space:pre">		</span>} catch (ClassNotFoundException e) {
<span style="white-space:pre">			</span>// TODO Auto-generated catch block
<span style="white-space:pre">			</span>e.printStackTrace();
<span style="white-space:pre">		</span>}
<span style="white-space:pre">		</span>
<span style="white-space:pre">		</span>Class class2 = String.class;//通过.class获取某个类的类
<span style="white-space:pre">		</span>System.out.println(class2);
<span style="white-space:pre">		</span>System.out.println("-------------------------------");
<span style="white-space:pre">		</span>
<span style="white-space:pre">		</span>//通过Class的class2对象所对应的类中所声明的所有方法,
<span style="white-space:pre">		</span>Method[] methods = class2.getDeclaredMethods();
<span style="white-space:pre">		</span>for(Method method2 : methods){
<span style="white-space:pre">			</span>System.out.println(method2);
<span style="white-space:pre">		</span>}
<span style="white-space:pre">		</span>System.out.println("-------------------------------");
<span style="white-space:pre">		</span>
<span style="white-space:pre">		</span>//通过Class的class2对象所对应的类中所声明的字段,
<span style="white-space:pre">		</span>Field[] fields = class2.getDeclaredFields();
<span style="white-space:pre">		</span>for(Field field : fields){
<span style="white-space:pre">			</span>System.out.println(field);
<span style="white-space:pre">		</span>}
<span style="white-space:pre">		</span>System.out.println("-------------------------------");
<span style="white-space:pre">		</span>
<span style="white-space:pre">		</span>//通过Class的class2对象创建一个class2所对应类的一个对象,
<span style="white-space:pre">		</span>try {
<span style="white-space:pre">			</span>Object object = class2.newInstance();//通过java的反射机制会调用class2所对应类的无参构造方法
<span style="white-space:pre">			</span>System.out.println(object instanceof String);//打印true,说明class2对应的是类是String
<span style="white-space:pre">		</span>} catch (InstantiationException e) {
<span style="white-space:pre">			</span>// TODO Auto-generated catch block
<span style="white-space:pre">			</span>e.printStackTrace();
<span style="white-space:pre">		</span>} catch (IllegalAccessException e) {
<span style="white-space:pre">			</span>// TODO Auto-generated catch block
<span style="white-space:pre">			</span>e.printStackTrace();
<span style="white-space:pre">		</span>}
<span style="white-space:pre">		</span>
<span style="white-space:pre">		</span>//获取class2所对应类的所有构造方法
<span style="white-space:pre">		</span>System.out.println("-------------------------------");
<span style="white-space:pre">		</span>try {
<span style="white-space:pre">			</span>Constructor[] constructors = class2.getConstructors();
<span style="white-space:pre">			</span>for(Constructor constructor : constructors){
<span style="white-space:pre">				</span>System.out.println(constructor);
<span style="white-space:pre">			</span>}
<span style="white-space:pre">		</span>} catch (SecurityException e) {
<span style="white-space:pre">			</span>// TODO Auto-generated catch block
<span style="white-space:pre">			</span>e.printStackTrace();
<span style="white-space:pre">		</span>}
<span style="white-space:pre">		</span>
<span style="white-space:pre">		</span>
<span style="white-space:pre">	</span>}
}

以上代码中,无论是获取某个对象的Class,还是通过Class 的一个对象class2获取其对应的类下的Method,Field,Constructor,都是通过java的反射机制来实现的。

java通过反射机制为我们提供了以下功能:

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

在运行时构造任意一个类的对象

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

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

在运行时创建新类对象

在使用Java的反射功能时,基本首先都要获取类的Class对象,再通过Class对象获取其他的对象。

再来看看如何通过反射调用

package com.lql.demo;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class test3 {

	
	public static void main(String[] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException {
		NumAdd numAdd = new NumAdd();
		
		//获取numAdd所对应的Class对象,当然也可以通过类名.class()或者forName();的方式
		Class class1 = numAdd.getClass();
		System.out.println(class1);
		System.out.println("-------------------------------------------------");
		//通过反射获取NumAdd的所有属性
		Field[] fields = class1.getDeclaredFields();
		for(Field field : fields){
			System.out.println(field);
		}
		System.out.println("-------------------------------------------------");
		//通过反射获取NumAdd的所有方法
		Method[] methods = class1.getDeclaredMethods();
		for(Method method : methods){
			System.out.println(method);
		}
		System.out.println("-------------------------------------------------");
		//通过反射获取NumAdd的所有构造方法
		Constructor[] constructors = class1.getConstructors();
		for(Constructor constructor : constructors){
			System.out.println(constructor);
		}
		System.out.println("-------------------------------------------------");
		//获取指定的参数的方法,然后调用,不使用NumAdd的对象调用,而是使用反射机制
		//第一个参数是方法名,第二个参数是方法中的参数类型的数组
		Method addMethod = class1.getDeclaredMethod("add",new Class[]{int.class , int.class});
		
		//调用addMethod,addMethod,先获取一个class1所对应类的一个对象,然后给addMethod指定所需参数
		Object instance = class1.newInstance();
		addMethod.invoke(instance,new Integer[]{1,2});
		System.out.println("-------------------------------------------------");
		//同样通过反射调用另一个打印方法
		Method printMethod = class1.getDeclaredMethod("myprint",new Class[]{String.class});
		printMethod.invoke(instance, new String("hello world"));
	}
	
}

class NumAdd{
	
	private int num;
	public String str;
	
	public NumAdd(){
		
	}
	
	public NumAdd(int num){
		this.num = num;
	}
	
	public NumAdd(int num,String str){
		this(num);
		this.str = str;
	}
	
	public void add(int a , int b){
		System.out.println(a + b);
	}
	
	public void myprint(String message){
		System.out.println(message);
	}
	
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值