JAVA的反射机制简析

正常访问java类的方式是先导入要访问的类所在的包,然后实例化对象,最后调用包里面的方法。但是有时候也会存在这样的情况,你需要的类所在的包并不在你的开发套件(SDK)中,而且你也不能把相关的包导入到你的开发工程当中来,但是你又必须要使用这个包中的相关类。有没有一种方式可以在不需要包的情况下也能访问包中的类呢,在这种情况下就可以使用反射机制。关于反射机制的具体原理可以参考相关的书籍和文章,本文主要举几个小例子来说明一下反射机制的使用方法。


一、使用的一般步骤

a、获得指定的类

b、获得类中需要调用的方法

c、实例化对象 (如果是调用静态方法,不要实例化对象)

d、设置对象的属性 (这一步可以根据情况来决定是否需要设置对象的属性)

e、调用获得的方法

基本开发环境:

操作系统:Ubuntu12.04

JDK版本:java version "1.7.0_101"


二、反射机制的几种使用情景

1、访问类中静态方法

在指定类中实现两个静态方法,然后通过反射机制来获取这两个静态方法并调用它们。在这里定义两个类,一个类为cn/edu/syau/Demo.java,这个类中定义需要访问的方法和属性等;一个类为Reflect.java,在这个类中实现反射机制来访问Demo类中方法和属性。

Demo.java内容如下:

package cn.edu.syau;

/* Define a Demo class */
public class Demo {

	/* Define a static method */
	public static void printString(String str) {
		System.out.println(str);
	}

	public static void printHello() {
		System.out.println("Hello,world!");
	}
	
}
Reflect.java的内容如下:
import java.lang.reflect.Method;

public class Reflect {

	public static void main(String args[]) throws Exception{
		/* 1 get class */
		Class<?> cls = Class.forName("cn.edu.syau.Demo");

		/* 2 get method */
		Method printStr = cls.getMethod("printString", String.class);
		Method printHello = cls.getMethod("printHello");

		/* 3 create object */

		/* 4 call method */
		printStr.invoke(null, "TECH-PRO");	/* call printString method */
		printHello.invoke(null);	/* call printHello method */
	}
	
}
编译上面这个程序的具体命令:

javac cn/edu/syau/Demo.java
javac Reflect.java
java Reflect

通过分析,可以看出调用Demo类中两个静态方法,结果如下:

2、访问类中的普通方法

在Demo类中实现两个普通方法,Demo类如下所示:

package cn.edu.syau;

/* Define a Demo class */
public class Demo {

	/* Define a static method */
	public void printString(String str) {
		System.out.println(str);
	}

	public void printHello() {
		System.out.println("Hello,world!");
	}
	
}
在Reflect类中页要进行相应的修改,内容如下:
import java.lang.reflect.Method;

public class Reflect {

	public static void main(String args[]) throws Exception{
		/* 1 get class */
		Class<?> cls = Class.forName("cn.edu.syau.Demo");

		/* 2 get method */
		Method printStr = cls.getMethod("printString", String.class);
		Method printHello = cls.getMethod("printHello");

		/* 3 create object */
		Object obj = cls.newInstance();

		/* 4 call method */
		printStr.invoke(obj, "TECH-PRO");	/* call printString method */
		printHello.invoke(obj);		/* call printHello method */
	}
	
}
运行结果如下:

3、访问类实例化通过带参构造函数

Demo类的具体实现如下:

package cn.edu.syau;

/* Define a Demo class */
public class Demo {
	private String name = null;
	private int age = 0;

	/* Define a constructor method with parameters */
	public Demo(String name, int age) {
		this.name = name;
		this.age = age;
	}

	/* Define a print informations method */
	public void printInfo() {
		System.out.println("name : " + this.name);
		System.out.println("age  : " + this.age);
	}
	
}
Reflect类的实现如下:

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

public class Reflect {

	public static void main(String args[]) throws Exception{
		/* 1 get class */
		Class<?> cls = Class.forName("cn.edu.syau.Demo");

		/* 2 get method */
		Method printInfo = cls.getMethod("printInfo");

		/* 3 create object */
		Constructor<?> con = cls.getConstructor(String.class, int.class);	/* get constructor metho */
		Object obj = con.newInstance("TECH-PRO", 25);	/* create obj */

		/* 4 call method */
		printInfo.invoke(obj);		/* call printInfo method */
	}
	
}
运行结果如下:

4、设置、访问类中的属性

访问类中的属性有两种方式,一种是通过setter/getter方法来设置,第二种是直接获得属性并进行设置。

4.1 通过getter/setter方法

Demo类的定义如下:

package cn.edu.syau;

/* Define a Demo class */
public class Demo {
	private String name = null;
	private int age = 0;

	/* Define a empty constructor method */
	public Demo(){}

	/* Define a constructor method with parameters */
	public Demo(String name, int age) {
		this.name = name;
		this.age = age;
	}

	/* Define a print informations method */
	public void printInfo() {
		System.out.println("name : " + this.name);
		System.out.println("age  : " + this.age);
	}

	/* define setter and getter methods */
	public void setAge(int age){this.age = age;}
	public int getAge(){return this.age;}
	public void setName(String name){this.name = name;}
	public String getName(){return this.name;}
	
}
Reflect类的实现如下:
import java.lang.reflect.Method;
import java.lang.reflect.Constructor;

public class Reflect {

	public static void main(String args[]) throws Exception{
		/* 1 get class */
		Class<?> cls = Class.forName("cn.edu.syau.Demo");

		/* 2 get method */
		Method printInfo = cls.getMethod("printInfo");
		Method setName = cls.getMethod("setName", String.class);
		Method setAge = cls.getMethod("setAge", int.class);

		/* 3 create object */
		Object obj = cls.newInstance();

		/* 4 call method */
		setName.invoke(obj, "TECH-PRO");	/* call setName method */
		setAge.invoke(obj, 25);		/* call setAge method */
		printInfo.invoke(obj);		/* call printInfo method */
	}
	
}
编译运行结果如下:

4.2 直接对属性进行设置和访问

Demo类的实现和4.1相同,Reflect类的具体实现如下:

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

public class Reflect {

	public static void main(String args[]) throws Exception{
		/* 1 get class */
		Class<?> cls = Class.forName("cn.edu.syau.Demo");

		/* 2 get method */
		Method printInfo = cls.getMethod("printInfo");

		/* 3 create object */
		Object obj = cls.newInstance();

		/* 4 set member values */
		Field name = cls.getDeclaredField("name");	/* get private field */
		Field age = cls.getDeclaredField("age");

		name.setAccessible(true);	/* set field access is public */
		age.setAccessible(true);

		name.set(obj, "TECH-PRO");	/* set name's value */
		age.set(obj, 25);	/* set age's value */

		/* 5 call method */
		printInfo.invoke(obj);		/* call printInfo method */
	}
	
}
编译运行结果如下:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值