Java反射机制原理及使用(一)

1.Java反射机制是在运行状态中,对于任意一个类(class文件),都能够知道该类的所有属性和方法。
(1)对于任意一个对象,都能够调用它的任一方法和属性。
(2)java语言的反射机制:动态获取信息及动态调用对象。也可以理解为对类的解剖。
2.为什么要出现反射机制,它的优势在哪里?
(1)反射机制可以动态的调用对象及动态的获取对象的属性和方法,可以极大的提高程序的扩展性。试想反射机制出现之前,扩展程序功能的主要方式就是继承与多态,但是每次继承与多态的实现,都需要对代码进行重写,这对于已经完成的应用来说几乎是不可能做到的。而反射机制仅仅需要修改其配置文件即可完成同样的工作。这就是反射机制的优势。
(2)反射机制的工作需要帮助文档的参与,因为获取类的属性和功能需要预先知道该类提供了哪些数据及方法。
3.反射机制的工作原理
一旦应用程序使用反射机制,就需要为该应用提供配置文件,应用程序运行时读取相应的配置文件,从配置文件中获取所需要的类名等相关信息。然后通过相应的方法获取到该类的对象。通过对象获取该类的数据及相应的方法,进而对该类进行操作,实现相应的功能。
4.Java完全面相对象的特点:
在java语言中,任何数据都是以对象的形式存在的。最简单的代码就是一个公共类,任何类都直接或者间接的继承了Object类。对象,基本数据类型,引用数据类型都是以对象的方式存在的。这就为反射机制的存在提供了可能。
5.类Class的作用:
由于Java面向对象的特点,想要对一个类进行完全的解剖,首先就需要获取该类的字节码文件,就可以使用Class类获取字节码文件中的所有内容,而反射也就是依靠该类来完成的。下面就讲解具体的使用方式。
6.获取字节码文件对象的方式:

事例Person类:

		class Person 
		{
			private int age;
			private String name;
			Person(){
				System.out.println("Person run");
			}
			Person(String name,int age){
				this.name = name;
				this.age = age;
				System.out.println("Person run +  name ::"+name +" age :"+age);
			}
			public void show(){
				System.out.println("Person name :"+name +" age :"+age);
			}
			public void set(String name,int age){
				this.name = name;
				this.age = age;
				System.out.println("Person  set   run");
			}
		}
(1)由于任何类都直接或间接的继承了Object类,故可以使用Object类中的方法getClass()来获取相应类的字节码文件对象。

	public static void getClassObject_1(){
		Person p = new Person();
		Class clazz = p.getClass();
		System.out.println("结果:" + clazz);
	}
	结果:
		---------- java ----------
		Person run
		结果:class Person

不足:使用这种方法,必须首先创建该类的对象,由该对象调用父类中的方法getClass()来获取相应的字节码。不过该类对象已经存在,获取字节码文件已经没有意义,并且书写麻烦。

(2)任何数据类型都具备静态属性class,可以通过该属性来获取类的字节码文件。
	public static void getClassObject_2(){
		Class clazz = Person.class;
		System.out.println("结果:" + clazz);
	}
	---------- java ----------
	结果:class Person

不足:该方法简单,但是还是要明确使用到类中的静态成员,即在程序中明确使用的类名,该方法扩展性不足。


(3)使用类Class中的forName()方法,只要给定类的字符串名就可以获取类的字节码文件。该方法更为扩展,可以通过字符串进行随意的更改。
需要注意的是:
(1)使用forName()方法需要抛出访问异常ClassNotFoundException。
(2)若类包含在包中,则字符串需要包含包名。

	public static void getClassObject_3() throws ClassNotFoundException {
		String className = "Person";
		Class clazz = Class.forName(className);
		System.out.println("结果:" + clazz);
	}
	---------- java ----------
	结果:class Person
优势:该方法只要有名称即可,更为方便,扩展性更高。


7.新的创建对象的方式:
(1)旧的方式:
以前创建对象都是使用new关键字。过程为:现根据被new的类的名字找寻该类的字节码文件并将该文件加载进内存,并创建该字节码文件对象。然后创建该字节码文件所对应的类的对象。
(2)新的方式:新的方式看起来很麻烦,实际应用中会发现这种方式的可扩展性和复用性极高。
首先通过字符串找到该类名称,通过名称找到对应的字节码文件,将字节码文件加载进内存产生对应的Class对象。通过Class对象的成员方法创建对应的类的对象。
以Person类为例,创建对象过程如下:

(1)创建空参的对象

			/*注:为书写方便,本人直接抛出Exception。*/
			public static void creatNewObject_1()  throws Exception{
				String className = "Person";
				Class clazz = Class.forName(className);
				Object obj = clazz.newInstance();
				System.out.println("对象创建结果:" + obj);
			}
			---------- java ----------
			Person run
			对象创建结果:Person@1db9742

(2)创建带参的对象
创建带参的对象过程如下:思路与空参创建方法基本相同,只不过需要首先获取带参的对象构造器即可。
需要注意:构造器的访问权限是default,而getConstructor只能获取字节码文件中的公共类,故必须使用getDeclaredConstructor才能获取字节码文件中的构造器。

			public static void creatNewObject_2()  throws Exception{
		
			String className = "Person";
			Class clazz = Class.forName(className);
			@SuppressWarnings("unchecked")
			//Constructor constructor = clazz.getConstructor(String.class,int.class);
			Constructor constructor = clazz.getDeclaredConstructor(String.class,int.class);
			Object obj = constructor.newInstance("小米",50);
			((Person)obj).show();
		}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值