反射(reflaction)的用法介绍

反射(reflaction)的用法介绍
在程序运行期间,每一个对象都属于一个类,同样,所有的类也是Class类的对象。反射就是在程序运行过程中,可以使用 java.lang.reflect 包中的工具获得出类的名称、属性和方法等信息。
现在介绍一下这些用法。
首先,取得类的类型,它是一个Class<?>类型的变量。取得类型的方式有三种:1、类的 class成员;2、Class.forName(String)方法,参数就是类的名字,如果类在包中定义,参数里也要把包名加上;3、通过一个类的其中的一个对象的getClass()获得。
有了Class类型的对象之后,就可以使用Class中的方法来获得一个类的各种信息的了。
  • Class类的方法列表中,含有declared的方法,是获得本类的方法或者属性,不含declared的方法,可以获得其父类的公有方法或者属性。获得的属性或者参数,里面都有一个getType()的方法,可以取得对应的类型;获得的方法里面有个getReturnType()的方法,可以获得对应的返回值类型。
  • 如果方法中的含有一个字符串参数,那是获得指定名字的方法或者属性。
  • 含有field的方法,表示可以取得类的属性。
  • 含有method的方法,表示可以取得类的方法。
  • 含有construnctor的方法,表示可以取得类的构造器。
  • 含有annotation的方法,是用来取得对应的注解的方法。
  • 还有其他获得接口和父类的方法。

下面举例说明这些方法的使用。

InterfaceA.java 的源代码

package com.baby;

public interface InterfaceA {
	public void dosomething();

	public void dosomething(String string);
}

ClassA.java 的源代码

package com.baby;

public class ClassA implements InterfaceA {
	public String publicFieldA1;
	protected String protectedFieldA2;
	private int privateFieldA3;

	public ClassA() {
		super();
		System.out.println("public ClassA()\t" + this);
	}

	public ClassA(String publicFieldA1, String protectedFieldA2, int privateFieldA3) {
		super();
		this.publicFieldA1 = publicFieldA1;
		this.protectedFieldA2 = protectedFieldA2;
		this.privateFieldA3 = privateFieldA3;

		System.out.println("public ClassA(String publicFieldA1, String protectedFieldA2, int privateFieldA3)\t" + this);
	}

	public String getPublicFieldA1() {
		return publicFieldA1;
	}

	public void setPublicFieldA1(String publicFieldA1) {
		this.publicFieldA1 = publicFieldA1;
	}

	public String getProtectedFieldA2() {
		return protectedFieldA2;
	}

	public void setProtectedFieldA2(String protectedFieldA2) {
		this.protectedFieldA2 = protectedFieldA2;
	}

	public int getPrivateFieldA3() {
		return privateFieldA3;
	}

	public void setPrivateFieldA3(int privateFieldA3) {
		this.privateFieldA3 = privateFieldA3;
	}

	@Override
	public void dosomething() {
		System.out.println("public void dosomething() from ClassA\t" + this);

	}

	@Override
	public void dosomething(String string) {
		System.out.println("public void dosomething() from ClassA. string is [" + string + "]\t" + this);

	}

}

ClassB.java 的源代码

package com.baby;

public class ClassB extends ClassA implements InterfaceA {
	public boolean publicFieldB1;
	public int publicFieldB2;
	private String privateFieldB3;
	protected String protectedFieldB4;

	public ClassB() {
		super();
		System.out.println("public ClassB()\t" + this);
	}

	public ClassB(String publicFieldA1, String protectedFieldA2, int privateFieldA3) {
		super(publicFieldA1, protectedFieldA2, privateFieldA3);
		System.out.println("public ClassB(String publicFieldA1, String protectedFieldA2, int privateFieldA3)\t" + this);
	}

	public ClassB(boolean publicFieldB1, int publicFieldB2, String privateFieldB3, String protectedFieldB4) {
		super();
		this.publicFieldB1 = publicFieldB1;
		this.publicFieldB2 = publicFieldB2;
		this.privateFieldB3 = privateFieldB3;
		this.protectedFieldB4 = protectedFieldB4;

		System.out.println(
				"public ClassB(boolean publicFieldB1, int publicFieldB2, String privateFieldB3, String protectedFieldB4)\t"
						+ this);
	}

	public boolean isPublicFieldB1() {
		return publicFieldB1;
	}

	public void setPublicFieldB1(boolean publicFieldB1) {
		this.publicFieldB1 = publicFieldB1;
	}

	public int getPublicFieldB2() {
		return publicFieldB2;
	}

	public void setPublicFieldB2(int publicFieldB2) {
		this.publicFieldB2 = publicFieldB2;
	}

	public String getPrivateFieldB3() {
		return privateFieldB3;
	}

	public void setPrivateFieldB3(String privateFieldB3) {
		this.privateFieldB3 = privateFieldB3;
	}

	public String getProtectedFieldB4() {
		return protectedFieldB4;
	}

	public void setProtectedFieldB4(String protectedFieldB4) {
		this.protectedFieldB4 = protectedFieldB4;
	}

	@Override
	public void dosomething() {
		System.out.println("public void dosomething() from ClassB\t" + this);

	}

	@Override
	public void dosomething(String string) {
		System.out.println("public void dosomething() from ClassB string is [" + string + "]\t" + this);

	}

}

ReflectTest.java 主程序的测试代码

package com.baby;

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

public class ReflectTest {

	/**
	 * @param args
	 * @throws InvocationTargetException
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 */
	public static void main(String[] args)
			throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		ClassA classA = new ClassA();
		classA.dosomething();

		ClassB classB = new ClassB();
		classB.dosomething();

		System.out.println("========获得类类型的方法========");
		// 获得类类型的方法1
		Class<?> typeOfClassB1 = ClassB.class;
		System.out.println("typeOfClassB1\t" + typeOfClassB1);

		// 获得类类型的方法2
		try {
			Class<?> typeOfClassB2 = Class.forName("com.baby.ClassB");
			System.out.println("typeOfClassB1\t" + typeOfClassB2);
		} catch (ClassNotFoundException e) {
			System.out.println("class [com.baby.ClassB] is not found");
		}

		// 获得类类型的方法3
		Class<?> typeOfClassB3 = classB.getClass();
		System.out.println("typeOfClassB3\t" + typeOfClassB3);

		System.out.println("========获得类的属性1========");

		// 获得类的属性。getFields能获得类的非privte的属性
		Field[] fields = ClassB.class.getFields();
		for (Field field : fields) {
			System.out.println("属性的全称名称:" + field.toString());
			System.out.println("\t属性的类型:" + field.getType() + "\t属性的名称:" + field.getName() + "\t");
		}

		System.out.println("========获得类的属性2========");
		// 获得类的属性
		Field[] declaredFields = ClassB.class.getDeclaredFields();
		for (Field field : declaredFields) {
			System.out.println("属性的全称名称:" + field.toString());
			System.out.println("\t属性的类型:" + field.getType() + "\t属性名称:" + field.getName() + "\t");
		}
		
		try {
			ClassB.class.getDeclaredField("file1");
		} catch (NoSuchFieldException e) {
			System.out.println("cat find filed file1");
		}

		System.out.println("========获得类的方法========");
		Method[] methods = ClassB.class.getDeclaredMethods();
		for (Method method : methods) {
			System.out.println("类的方法:" + method);
			System.out.println("\t方法的返回值:" + method.getReturnType() + "\t方法的名称:" + method.getName());
			Parameter[] parameters = method.getParameters();
			for (Parameter parameter : parameters) {
				System.out.println("\t参数类型:" + parameter.getType());
			}
		}

		try {
			ClassB.class.getDeclaredMethod("method1");
		} catch (NoSuchMethodException e) {
			System.out.println("cat find method method1");
		}

		System.out.println("========获得类的构造器========");
		Constructor<?>[] constructors = ClassB.class.getConstructors();
		for (Constructor<?> constructor : constructors) {
			System.out.println("类的构造器:" + constructor);
			Parameter[] parameters = constructor.getParameters();
			for (Parameter parameter : parameters) {
				System.out.println("\t参数类型:" + parameter.getType());
			}
		}

		System.out.println("========获得类的接口========");
		Class<?>[] classBInterfaces = ClassB.class.getInterfaces();
		for (Class<?> itf : classBInterfaces) {
			System.out.println("interface from Person is [" + itf.getName() + "] or [" + itf.getSimpleName() + "]");
		}

		System.out.println("========获得类的父类========");
		Class<? super ClassB> classBSuperClasses = ClassB.class.getSuperclass();
		System.out.println("super class of Person is [" + classBSuperClasses.getName() + "] or ["
				+ classBSuperClasses.getSimpleName() + "]");

		//使用invoke来调用对象,即运行对象的一个方法。
		System.out.println("========获得调用类的方法========");
		try {
			Method methodDosomething1 = ClassB.class.getMethod("dosomething");
			methodDosomething1.invoke(classB);
			
		} catch (NoSuchMethodException e) {
			System.out.println("can not find method dosomething");
		}
		
		try {
			Method methodDosomething2 = ClassB.class.getMethod("dosomething", String.class);
			methodDosomething2.invoke(classB, "test string2");
			
		} catch (NoSuchMethodException e) {
			System.out.println("can not find method dosomething(String)");
		}

	}
}

程序的运行结果:

public ClassA()    com.baby.ClassA@139a55
public void dosomething() from ClassA    com.baby.ClassA@139a55
public ClassA()    com.baby.ClassB@1db9742
public ClassB()    com.baby.ClassB@1db9742
public void dosomething() from ClassB    com.baby.ClassB@1db9742
========获得类类型的方法========
typeOfClassB1    class com.baby.ClassB
typeOfClassB1    class com.baby.ClassB
typeOfClassB3    class com.baby.ClassB
========获得类的属性1========
属性的全称名称:public boolean com.baby.ClassB.publicFieldB1
    属性的类型:boolean    属性的名称:publicFieldB1    
属性的全称名称:public int com.baby.ClassB.publicFieldB2
    属性的类型:int    属性的名称:publicFieldB2    
属性的全称名称:public java.lang.String com.baby.ClassA.publicFieldA1
    属性的类型:class java.lang.String    属性的名称:publicFieldA1    
========获得类的属性2========
属性的全称名称:public boolean com.baby.ClassB.publicFieldB1
    属性的类型:boolean    属性名称:publicFieldB1    
属性的全称名称:public int com.baby.ClassB.publicFieldB2
    属性的类型:int    属性名称:publicFieldB2    
属性的全称名称:private java.lang.String com.baby.ClassB.privateFieldB3
    属性的类型:class java.lang.String    属性名称:privateFieldB3    
属性的全称名称:protected java.lang.String com.baby.ClassB.protectedFieldB4
    属性的类型:class java.lang.String    属性名称:protectedFieldB4    
cat find filed file1
========获得类的方法========
类的方法:public void com.baby.ClassB.dosomething()
    方法的返回值:void    方法的名称:dosomething
类的方法:public void com.baby.ClassB.dosomething(java.lang.String)
    方法的返回值:void    方法的名称:dosomething
    参数类型:class java.lang.String
类的方法:public int com.baby.ClassB.getPublicFieldB2()
    方法的返回值:int    方法的名称:getPublicFieldB2
类的方法:public boolean com.baby.ClassB.isPublicFieldB1()
    方法的返回值:boolean    方法的名称:isPublicFieldB1
类的方法:public void com.baby.ClassB.setPublicFieldB2(int)
    方法的返回值:void    方法的名称:setPublicFieldB2
    参数类型:int
类的方法:public void com.baby.ClassB.setPublicFieldB1(boolean)
    方法的返回值:void    方法的名称:setPublicFieldB1
    参数类型:boolean
类的方法:public java.lang.String com.baby.ClassB.getPrivateFieldB3()
    方法的返回值:class java.lang.String    方法的名称:getPrivateFieldB3
类的方法:public java.lang.String com.baby.ClassB.getProtectedFieldB4()
    方法的返回值:class java.lang.String    方法的名称:getProtectedFieldB4
类的方法:public void com.baby.ClassB.setPrivateFieldB3(java.lang.String)
    方法的返回值:void    方法的名称:setPrivateFieldB3
    参数类型:class java.lang.String
类的方法:public void com.baby.ClassB.setProtectedFieldB4(java.lang.String)
    方法的返回值:void    方法的名称:setProtectedFieldB4
    参数类型:class java.lang.String
cat find method method1
========获得类的构造器========
类的构造器:public com.baby.ClassB(boolean,int,java.lang.String,java.lang.String)
    参数类型:boolean
    参数类型:int
    参数类型:class java.lang.String
    参数类型:class java.lang.String
类的构造器:public com.baby.ClassB(java.lang.String,java.lang.String,int)
    参数类型:class java.lang.String
    参数类型:class java.lang.String
    参数类型:int
类的构造器:public com.baby.ClassB()
========获得类的接口========
interface from Person is [com.baby.InterfaceA] or [InterfaceA]
========获得类的父类========
super class of Person is [com.baby.ClassA] or [ClassA]
========获得调用类的方法========
public void dosomething() from ClassB    com.baby.ClassB@1db9742
public void dosomething() from ClassB string is [test string2]    com.baby.ClassB@1db9742

说明:

这个例子里面介绍了一般的用法,没有包含获得并使用注解的介绍。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值