java反射技术的应用(二)

反射技术中,最重要的一点:先获取到那个类。如何获取那个类呢?这是最重要的一步操作。
反射技术:动态的获取类以及类中的成员,并可以调用该类成员,以前是有什么类,就new什么类,现在是没有类,给什么类就new什么对象。
无论new 什么对象,都需要先获取字节码文件,如何获取呢?发现java已对字节码文件进行了描述,用的是Class类完成的(首字母大写)。
每一个class文件都有可能生产一个Class对象,可以这么去理解:一个Person类,可以new出很多人,例如person1, person2等等,这里一个class类就好比是一个人,Class好比是Person类。

如何获取一个字节码文字的对象呢?

1、假设存在一个Person类,以获取Person类为例

public class Person{
        String Name = "";
        Int age = "";
        public Person(){
                System.out.println("this is person");
        }
}
2、主函数调用一个获取类名称的方法

public class refectDemo{
	public static void main(String args[]){
		method();
	}
}
3、获取类的操作如下
反射里最常用的找类方法:通过给定的类名称,找到对应的类

public static void method() throws ClassNotFoundException{
	String className ="";
	Class clazz = Class.forName(className);
	System.out.println(clazz);
}
forName方法:通过给定的类名,找到对应的类,找到之后自动加载这个类进内存。例如传入类名:com.study.Person ,找到对应的com.study.Person.class文件,加载并封装成一个Class对象。

但是获取名称肯定还还不够,如何通过找到的这个类建立它的对象呢?
public class ReflectDemo2{
	public static void main(String args[]){
		getObject();
	}
	
	public staic void getObject() throws ClassNotFoundException{
		//1、根据给定的类名获取大Class对象
		String className = "com.study.Person";
		Class clazz = class.forName(className);
		
		<strong><span style="color:#ff0000;">Object obj = clazz.newInstance();</span></strong>
		
		<span style="color:#ff0000;"><strong>//动态创建一个Person对象,默认调用其空参数构造方法
	      //不能使用  Person p = new Person()方法,因为不知道具体的类是什么
	      常见异常:java.lang.InstantiationException: 没有调用与之对应的构造函数
	      记住:一般被反射的类通常都有空参数的构造方法</strong></span>
	}
}
这时候可以看到会自动调用Person里的无参构造方法,输出一串字符: this is a person

问题来了:如果构造方法中没有空参数怎么办呢?例如:public Person(String Name, Int age){ …… }

需求:万一给定类中没有空参数呢?可以先获取指定的构造函数,再通过该构造函数进行实例化。
1、通过大Class获取指定的构造函数:class 文件中的构造函数,也被封装成一个对象,万物皆对象。
   Constructor cons = clazz.getConstructor(String.class,int.class);这里传入的是类型对象
2、通过指定的构造器对象进行对象的初始化
   Object obj = cons.newInstances("lisi",23); 

public static void getObject2()throws ClassNotFoundException{
	String className = "com.study.Person";
	Class clazz = calss.forName(className);
	Constructor cons = clazz.getConstrctor(String.class, int.class);
	Object obj = cons.newInstances("lisi",23);
}
反射技术,可以简单的理解成对类的解剖,通过得到了类,可以想拿啥就拿啥。

4、获取类的字段

例如获取类中的age属性,并对其操作

public static void getFileDemo() throws Exception{
	String className = "com.study.Person";
	Class clazz = Class.forName(className);
	//获取指定的age字段
	//Field field = clazz.getField("age");该方法只获取公有的
	Filed field = clazz.getDeclaredField("age");
	
	//要对非静态的字段操作必须有对象
	Object obj = clazz.newInstance();
	//使用父类的方法,将访问权限检查能力取消(如果定义的private,就不能访问)
	field.setAccessible(true);//暴力访问私有
	field.set(obj, 40);
	system.out.println(field.get(obj));
}


5、获取类的方法
//反射方法,非静态,无参数
public static void getMethodDemo() throws Exception{
	String className = "com.study.Person";
	Class clazz = Class.forName(className);
	
	
	Method method = clazz.getMethod("show",null);//show是方法名
	Object obj = clazz.newInstance();
	method.invoke(obj,null);
}
//反射方法,静态,无参数
public static void getMethodDemo2 thorws Exception{
	String className = "com.study.Person";
	Class clazz = Class.forName(className);
	
	Method method = clazz.getMethod("staticshow",null);
	//静态方法不需要对象也可以调用
	nethod.invoke(null,null);
}
//反射方法:非静态,有参数
public static void getMethodDemo3 throws Exception{
	String className = "com.study.Person";
	Class clazz = Class.forName(className);
	
	Method method = clazz.getMethod("show2", String.class,int.class);
	//上行代码的意思是,我要反射的是show2方法,携带的是String 和int两个类型的参数
	Object obj = clazz.newInstance();
	method.invoke(obj,"小强",20);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值