Java反射

反射(reflect),本来是动态语言中的特性。Java中的反射相对于Python来看就有点难看了。

为了体现反射。首先定义一个接口和一个实现类。

public interface TestInterFace {
	public void TestInterFace();
}

 

public class TestClass extends Object implements TestInterFace {
	// 字段
	private String testClassName = "";
	protected double[] doubleTestArray;
	public int testClassNum = 0;

	// 属性(get/set)
	public String getTestClassName() {
		return testClassName;
	}

	public void setTestClassName(String testClassName) {
		this.testClassName = testClassName;
	}

	public int getTestClassNum() {
		return testClassNum;
	}

	public void setTestClassNum(int testClassNum) {
		this.testClassNum = testClassNum;
	}

	// 构造器
	public TestClass() {
		System.out.println("调用构造器TestClass()");
	}

	public TestClass(String testClassName, int testClassNum) {
		this.testClassName = testClassName;
		this.testClassNum = testClassNum;
		System.out
				.println("调用构造器TestClass(String testClassName,int testClassNum)");
	}

	// 方法
	// 私有方法
	private void privateMethod() {

	}

	// 保护方法
	protected void protectedMethod() {

	}

	// 公有方法
	public void TestClassMethod() {
		System.out.println("调用了TestClass类的void TestClassMethod()方法");
	}

	public String TestClassMethod(String i) {
		System.out
				.println("调用了TestClass类的String TestClassMethod(String i)方法,传入的参数为"+ i);
		return i;
	}

	

	public void TestInterFace() {
		System.out.println("这是TestInterFace接口的实现");

	}

}

 

上面的类基本是照顾到了类的各个方面,除了内部类等。

 

说明:

(1)java.lang.reflect包中包含了反射的中使用的各种类。使用反射前需要导入。

(2) 若Class对象的方法名称中有Declared。则说明这个方法可以访问Class对象对应类的任意成员,无视访问权限(private,friendly,protected,public)。若没有则只能访问public的类成员。

(3)带Declared的方法破坏了oop的封装机制。

(4)若用反射调用类的方法,则无视多态的限制。可以没有限制的调用对象的运行时类型的方法。无视对象的编译时类型。这个在下篇文章中用代码阐述。

 

 接下来看Java的反射。

 

首先,

通过反射获得类的相关信息。

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

public class Reflect_to_get_ClassInformation {
	public static void main(String[] args) throws Exception {
		// 获得Class对象
		System.out.println("获得Class对象");
		// 方法1
		Class c1 = Class.forName("TestClass");
		System.out
				.println("方法1:使用Class.forName。如Class c=Class.forName(\"TestClass\");\t得到的Class对象为"
						+ c1);
		// 方法2
		Class c2 = TestClass.class;
		System.out
				.println("方法2:使用*(类).Class。如Class c2=TestClass.class;\t得到的Class对象为"
						+ c2);
		// 方法3
		TestClass testClassInstance = new TestClass();
		Class c3 = testClassInstance.getClass();
		System.out
				.println("方法3:使用*(实例).getClass()。如Class c3=testClassInstance.getClass();;\t得到的Class对象为"
						+ c3);

		
		// 从Class对象中获取信息。
		// 获取Class对象对应类的构造器Constructor对象
		System.out.println();
		System.out.println("获取Class对象对应类的构造器Constructor对象");
		// 方法1
		Constructor constructor1 = c1.getConstructor();
		Constructor constructor2 = c1.getConstructor(String.class, int.class);
		System.out.println("方法1:Constructor constructor1=c1.getConstructor();\t获得有参数构造器:"+ constructor1);
		System.out.println("      :Constructor constructor2=c1.getConstructor(String.class,int.class);\t获得有参数构造器:"+ constructor2);
		// 方法2
		Constructor[] constructor_array = c1.getConstructors();
		System.out.println("方法2:Constructor[] constructor_array=c1.getConstructors();以数组的形式返回所有构造器\t得到构造器数组");
		for (Constructor constructor : constructor_array) {
			System.out.println("\t\t\t构造器[]:" + constructor);
		}

		// 方法3

		// 方法4

		
		// 获取Class对象获取类的方法Method对象。
		System.out.println();
		System.out.println("获取Class对象获取类的方法Method对象。");
		// 方法1
		Method method1 = c1.getMethod("TestClassMethod");
		Method method2 = c1.getMethod("TestClassMethod", String.class);
		System.out.println("方法1:返回TestClassMethod无参数method对象" + method1);
		System.out.println("\t ;返回TestClassMethod有参数method对象" + method2);
		// Method method3 = c1.getMethod("privateMethod");
		// System.out.println("方法1:返回私有方法Method对象" + method3);
		System.out.println("该方法只能返回public方法Method对象,对private,protected则会报错。");

		// 方法2
		Method[] method_array = c1.getMethods();
		System.out.println("方法2:以数组方式返回类的所有的方法method对象");
		for (Method method : method_array) {
			System.out.println("\t\t\t方法:" + method);
		}
		//方法3
		 Method method3 = c1.getDeclaredMethod("privateMethod");
		 System.out.println("方法3:使用getDeclaredMethod().无视private,protected。返回私有方法Method对象" + method3);
		//方法4
		 Method[] method_all_array = c1.getDeclaredMethods();
			System.out.println("方法4:getDeclaredMethods(),以数组方式返回类的所有的方法method对象,无视private,protected");
			for (Method method4 : method_all_array) {
				System.out.println("\t\t\t方法[]:" + method4);
			}
		 
		 
		 

		System.out.println();
		// 获取Class对象对应类的字段Field对象。
		System.out.println();
		System.out.println("获取Class对象对应类的字段Field对象。");
		// 方法1
		Field field1 = c1.getField("testClassNum");
		System.out.println("方法1 ;返回TestClassMethod中的Field对象" + field1);
		// Field field2 = c1.getField("testClassName");
		// System.out.println("\t:返回TestClassMethod中的Field对象" + field2);
		System.out.println("该方法只能返回public字段Field对象,对private,protected则会报错。");
		// 方法2
		Field[] field_array = c1.getFields();
		System.out.println("方法2:以数组方式返回类的所有的public字段Field对象");
		for (Field field : field_array) {
			System.out.println("\t\t\t字段[]:" + field);
		}
		// 方法3
		Field field3 = c1.getDeclaredField("testClassNum");
		System.out.println("方法3:使用getDeclaredField()。该方法可以返回任意访问权限的字段。无视private,protected。返回TestClassMethod中的Field对象" + field3);
		// 方法4
		Field[] field_all_array = c1.getDeclaredFields();
		System.out.println("方法4:以数组方式返回类的所有的字段Field对象,无视private,protected。");
		for(Field field4:field_all_array){
			System.out.println("\t\t\t字段[]"+field4);
		}

		
		System.out.println();
		// 获取Class对象对应类的 注释 对象。

		
		System.out.println();
		// 获取Class对象对应类的 内部类Class对象。
		
		
		System.out.println();
		// 获取Class对象对应类的 外部类Class对象。
		
		
		
		System.out.println();
		// 获取Class对象对应类所实现的接口。
		System.out.println();
		System.out.println("获取Class对象对应类所实现的接口Class对象。");
		Class[] interface_array = c1.getInterfaces();
		System.out.println("方法2:以数组方式返回类的所有的public字段Field对象");
		for (Class inter : interface_array) {
			System.out.println("\t\t\t接口:" + inter);
		}
		
		
		System.out.println();
		// 获取Class对象对应类的父类Class对象。
		System.out.println();
		System.out.println("获取Class对象对应类的父类Class对象。");
		Class super_c = c1.getSuperclass();
		System.out.println("方法1:Class super_c = c1.getSuperclass();所得到的父类Class对象的super_c为"+super_c);
		
	}
}

  

通过反射实例化Class对象所对应类与方法调用。

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


public class Reflect_Operate_Class {
	public static void main(String[] args) throws Exception {
		//通过反射用Class对象实例化该对象对应类的实例。
		System.out.println("通过反射用Class对象实例化该对象对应类的实例。");
		Class c=Class.forName("TestClass");
		
		//方法1
		Object tc1=c.newInstance();
		System.out.println("方法1:Class c=Class.forName(\"TestClass\");该方法只能调用默认无参数构造");
		//方法2
		Constructor constructor1=c.getConstructor();
		Object tc2=constructor1.newInstance();
		System.out.println("方法2.1:Constructor constructor1=c.getConstructor();TestClass tc2=(TestClass)constructor1.newInstance();");
		
		Constructor constructor2=c.getConstructor(String.class,int.class);//注意到得到对应的构造器
		TestClass tc3=(TestClass)constructor2.newInstance("构造器",100);
		System.out.println("方法2.2:Constructor constructor2=c.getConstructor();TestClass tc3=(TestClass)constructor1.newInstance(\"构造器\",100);构造器有参数实例化");
		
		
		
		//调用Class所对应的类方法。
		Object obj=c.newInstance();
		Method method1=c.getMethod("TestClassMethod");
		method1.invoke(obj);
		
		Method method2=c.getMethod("setTestClassNum",int.class);
		method2.invoke(obj,100);
		
		//访问属性
		
		
	}
}

 

 

以上的代码均通过运行。基本可以体现反射的一些基本用法了。等有什么新的东西,再更新吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值