现在的位置: 首页 > 综合 > 正文

初学者学Java(二十一)——-反射机制

2013年08月07日 ⁄ 综合 ⁄ 共 3879字 ⁄ 字号 评论关闭

                                       
   初识反射机制

以前我们访问对象的方法和属性,都是在编译期的时候完成的。但Java可不可以在运行期来实现调用某个类的方法和属性,这个当然是可以的,Java就是通过反射来实现的,反射的英文是Reflection。
        Java 反射机制主要提供了以下功能:
• 在运行时判断任意一个对象所属的类。
• 在运行时构造任意一个类的对象。
• 在运行时判断任意一个类所具有的成员变量和方法。
• 在运行时调用任意一个对象的方法
下面我来说一下Java是如何来完成这个工作了。
我们首先来介绍一个最基本的类Class类。

反射的基础--------Class类

在Java中每个类都有一个且仅有一个Class对象,不管这个类生成多少个新的对象,他都只有一个。这个对象描述了这个类的包括名称在内的一些信息,要想使用反射必须先得到Class对象。下面我们写个程序来测试一下。我们来以String类测试一下:

package reflection;
public class TestOne {
	public static void main(String[] args) {
		Class classType = String.class;
		System.out.println(classType);
	}
}

这个测试程序的结果如下:

class java.lang.String

得到Class对象的三种方法
•第一种

因为所有的类都直接或间接的继承自Object类,而Object中有一个方法getClass()方法,这个方法可以得到这个对象所对应的类的Class对象,我们还是以String类为例:

package reflection;
public class TestOne {
	public static void main(String[] args) {
		String str ="滨州学院csdn高校俱乐部";
		Class classType = str.getClass();
		System.out.println(classType);
	}
}
这个测试程序的结果如下:

class java.lang.String

•第二种

Class类本身有个静态方法:

		public static Class<?> forName(String className)

这个方法可以返回与带有给定字符串名的类或接口相关联的 Class 对象。测试一下:

package reflection;
public class TestOne {
	public static void main(String[] args) throws Exception {
		Class classType = Class.forName("java.lang.String");
		System.out.println(classType);
	}
}

这个测试程序的结果如下:


class java.lang.String

•第三种

使用类的.class 语法,也可以得到Class对象,就像我第一个例子一样,我就不再演示了。
Class还有以下几个方法:
– getName():获得类的完整名字。
– getFields():获得类的public类型的属性。
– getDeclaredFields():获得类的所有属性。
– getMethods():获得类的public类型的方法。
– getDeclaredMethods():获得类的所有方法。


getMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes 参数指定方法的参数类型。

getConstructors():获得类的public类型的构造方法。

getConstructor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes 参数指定构造方法的参数类型。

newInstance():通过类的不带参数的构造方法创建这个类的一个对象。
下面来讲一下通过默认构造方法创建一个新对象:
例:

package reflection;
public class TestOne {
	public static void main(String[] args) throws Exception {
		Class classType = Class.forName("java.lang.String");
		String str =(String) classType.newInstance();
	}
}

因为newInstance()方法的返回值是Object类型,所以需要强制转换,或者使用泛型:

package reflection;
public class TestOne {
	public static void main(String[] args) throws Exception {
		Class<String> classType = String.class;
		String str =classType.newInstance();
	}
}

调用构造方法,普通方法,属性的类-------Constructor 类,Method类,Field 类

刚刚我们演示了通过默认构造方法创建一个新对象,但如果想要通过一个类的有参数的构造方法来创建一个对象,就必须通过

Constructor 类。用这个类来调用有参构造的方式如下例:

package reflection;
import java.lang.reflect.*;
class A
{
	public A(int a)
	{}
}
public class TestOne {
	public static void main(String[] args) throws Exception {
		Class<A> classType = A.class;
		Constructor<A>  con = classType.getConstructor(new Class[]{int.class});
		A a = con.newInstance(new Object[]{1});
	}
}

Class类的

getConstructor();方法是用来获取构造方法类的对象,参数是构造方法的参数类型,因为同一个类不同的构造方法只有参数不同,所以这样就可以获取类的构造方法,如果没有参数就是调用无参构造函数。

创建了对象后我们就要调用他的方法和属性,分别用到了

Method类,Field 类。

调用方法:

package reflection;
import java.lang.reflect.*;
class A
{
	public int a;
	public A(int a)
	{
		this.a = a;
	}
	public void b()
	{
		a  = 2;
	}
}
public class TestOne {
	public static void main(String[] args) throws Exception {
		Class<A> classType = A.class;
		Constructor<A>  con = classType.getConstructor(new Class[]{int.class});
		A a = con.newInstance(new Object[]{1});
		Method met = classType.getMethod("b", new Class[]{});
		met.invoke(a, new Object[]{});
	}
}

调用属性

package reflection;
import java.lang.reflect.*;
class A
{
	public int a;
	public A(int a)
	{
		this.a = a;
	}
	public void b()
	{
		a  = 2;
	}
}
public class TestOne {
	public static void main(String[] args) throws Exception {
		Class<A> classType = A.class;
		Constructor<A>  con = classType.getConstructor(new Class[]{int.class});
		A a = con.newInstance(new Object[]{1});
		Field fie = classType.getField("a");
		fie.set(a, 3);
		System.out.println(a.a);
	}
}

结果为3.

如果想要调用私有方法,就要像下面这个例子一样:

package reflection;
import java.lang.reflect.*;
class A
{
	private int a;
	public int getA() {
		return a;
	}
	public void setA(int a) {
		this.a = a;
	}
	public A(int a)
	{
		this.a = a;
	}
	public void b()
	{
		a  = 2;
	}
}
public class TestOne {
	public static void main(String[] args) throws Exception {
		Class<A> classType = A.class;
		Constructor<A>  con = classType.getConstructor(new Class[]{int.class});
		A a = con.newInstance(new Object[]{1});
		Field fie = classType.getDeclaredField("a");
		fie.setAccessible(true);
		fie.set(a, 3);
		System.out.println(a.getA());
	}
}

调用私有方法,和这个是同理的。就不再举例子了。

以上就是反射的一些基本内容。



抱歉!评论已关闭.