Java反射

反射是什么?

 一个类有多个组成部分,例如,构造函数(创建对象,完成对象初始化),成员变量(封装数据),方法(执行功能)。反射就是加载类,并反射出类的各个组成部分;

1、加载类,获取类的字节码可以通过三种形式来获取

		Class cl=Class.forName("com.java.xiong.reflet0301.Person");
		Class cl1=new Person().getClass();
		Class cl2=Person.class;


2、通过获取得到类的字节码之后就可以来反射类:通过Class对象如下的几个方法可以获取类的构造函数,成员变量与方法

 

Constructor<T>getConstructor(Class<?>... parameterTypes)
          返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法

 

Constructor<T>getDeclaredConstructor(Class<?>... parameterTypes)
          返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法

 

FieldgetField(String name)
          返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段。

 

FieldgetDeclaredField(String name)
          返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。

 

MethodgetMethod(String name,Class<?>... parameterTypes)
          返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。

 

MethodgetDeclaredMethod(String name,Class<?>... parameterTypes)
          返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。

 

实例:

package com.java.xiong.reflet0301;

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

import org.junit.Test;

public class Test1 {
	//反射类的构造函数
	//无参构造函数
	@Test
	public void  test() throws Exception{
		//获取Class对象
		Class<?> cl=Class.forName("com.java.xiong.reflet0301.Person");
		//获取类构造函数的对象
		Constructor<?> cons=cl.getConstructor();
		//获取类的对象
		Person person=(Person)cons.newInstance();
		System.out.println(person.aa);
	}
	//带参数的构造函数
	@Test
	public void test1() throws Exception{
		Class<?> cl=Class.forName("com.java.xiong.reflet0301.Person");
		//构造函数传入参数的参数类型
		Constructor<?> cons=cl.getConstructor(String.class);
		//构造函数的参数的值
		Person person=(Person)cons.newInstance("xiong");
		System.out.println(person.aa);
	}	
	@Test
	public void test2()throws Exception{
		Class<?> cl=Class.forName("com.java.xiong.reflet0301.Person");
		Constructor<?> cons=cl.getConstructor(String.class,int.class);
		Person person=(Person)cons.newInstance("xiong",23);
		System.out.println(person.aa);
	}
	//反射类的方法
	@Test
	public void fc()throws Exception{
		//获取Class对象
		Class<?> cl=Class.forName("com.java.xiong.reflet0301.Person");
		//获取方法的对象
		Method method=cl.getMethod("fc");
		//执行方法
		method.invoke(new Person());
	}
	
	@Test 
	public void fc1()throws Exception{
		Class<?> cl=Class.forName("com.java.xiong.reflet0301.Person");
		//第一个参数表示方法名 后面的可变参数表示 方法中的参数的参数类型
		Method method=cl.getMethod("fc", String.class,int.class);
		//一个表示执行者的对象 后面的可变参数表示方法的参数值
		method.invoke(new Person(), "xiong",23);
	}
	
	@Test
	public void fc2()throws Exception{
		Class<?>cl=Class.forName("com.java.xiong.reflet0301.Person");
		Method  method=cl.getMethod("fc", String.class);
		//获取方法的返回值
		Object  []invoke =(Object[]) method.invoke(new Person(),"xiong");
		System.out.print(invoke[0]);
	}
	@Test
	public void fc3()throws Exception{
		Class<?> cl=Class.forName("com.java.xiong.reflet0301.Person");
		//调用类的私有方法用getDeclaredMethod 
		Method method=cl.getDeclaredMethod("privatefc");
		System.out.println(method.getName());
		//method.invoke(new Person()); 类私有方法不能执行
		method.setAccessible(true);//获取私有访问权限
		method.invoke(new Person());
	}
	
	@Test
	public void fc4()throws Exception{
		Class<?> cl=Class.forName("com.java.xiong.reflet0301.Person");
		Method method=cl.getMethod("arr", String[].class);
		//当反射类的方法的参数是数组时  需要特别的注意 
		//因为在jdk1.4的时候 当方法有多个参数aa(String a,String b)时 invoke()的方法是invoke(new Person(),new []Object{"a","b"}) 这个Object
		//就是表示两个参数 a和b的值 所以jdk1.5时为了兼容1.4 当方法的参数是数组时也是拆开来传入的  
		//两种方法来解决这个问题
		method.invoke(new Person(),new Object[]{new String[]{"1","2"}});
		method.invoke(new Person(),(Object)new String[]{"1","2"});
	}
	//反射类的成员变量
	
	@Test
	public void bl()throws Exception{
		Person person=new Person();
		Class<?> cl=Class.forName("com.java.xiong.reflet0301.Person");
		//获取字段
		Field  file=cl.getField("aa");
		Field files=cl.getField("A");
		Class<?> types=file.getType();//获取字段的类型
		if(types.equals(String.class)){
			//获取那个类的对象的字段
			String str1=(String)file.get(person);
			System.out.println(str1);
			file.set(person, "file");
			System.out.println(person.aa);
			String str2=(String)file.get(person);
			System.out.println(str2);
		}
		System.out.println(files.get(person));
	}
	
	
	
}

 


package com.java.xiong.reflet0301;

public class Person {
	
	public String aa="aa";
	
	public  static final int A=1;
	
	
	//构造函数
	public Person(){
		System.out.println("Person()");
	}
	
	public Person(String name){
		System.out.println("Person(String name)  name :"+name);
	}
	public Person(String name,int age){
		System.out.println("Person(String name,int age)"+" name:"+name+"  age:"+age);
	}
	
	//方法
	public void fc(){
		System.out.println("fc()");
	}
	public void fc(String name,int age){
		System.out.println("fc(String name)  name:"+name +"age:"+age);
	}
	public String [] fc(String name ){
		return new String[]{name};
	}
	
	private void privatefc(){
		System.out.println("privatefc()");
	}
	
	public void arr(String []arg){
		System.out.println("arr(String []arg)");
	}

}


 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小哥、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值