浅谈我对反射的了解


JAVA - reflection ( 反射 )

-----------------------------------------------------------------------------------------------------------------------------------

什么是反射 ?

其实就是通过Class 类实例, 返回该类相关的成员,函数,加载器,父类,接口,包等类信息。

事例:反射就好像镜子,你背对着我,我看不见你,假设你前方有一面镜子,虽然我看不见你,但是可以通过镜子看见你。

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

在 java.lang 包下,有一个 Class 类 。

Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的。

其实,每一个类被加载之后,系统就会为该类生成一个对应的 Class 对象,所以不用我们实例化 Class对象。


那么问题来了,如何取得 Class 对象 ?

通过3种方式获取:     1.  Class.forName(String className)

2. 类名.class

3. 实例化对象调用 getClass 方法


下面演示3种方式:

class ClassTest
{
	public static void main(String[] args) throws Exception {
		
		//第一种方式:
		Class c1 = Class.forName("ClassTest"); //注意:这种方式会引发ClassNotFoundException异常。

		//第二种方式:
		Class c2 = ClassTest.class;

		//第三种方式:
		ClassTest ct = new ClassTest();
		Class c3 = ct.getClass();

		System.out.println("第 1 种方式: "+c1.getName());
		System.out.println("第 2 种方式: "+c2.getName());
		System.out.println("第 3 种方式: "+c3.getName());

		/*
		printOut:
			第 1 种方式: ClassTest
			第 2 种方式: ClassTest
			第 3 种方式: ClassTest
		*/
	}
}

从输出结果发现, 所有类的对象其实都是Class的实例。 (果然是万物皆对象,类其实也是一种对象 )


下面演示Class示例:

import java.lang.reflect.*;

class Person
{
	private String name;
	public int age;
	public String content;
	String ccc;
	protected String qqq;

	Person(){
		System.out.println("执行了空参数的构造方法");
	}

	public Person(String name, int age) {
		this.name = name;
		this.age  = age;
	}

	private Person(String name, int age, String content) {
		this(name, age);
		this.content = content;
	}

	public String toString() {
		return "姓名"+name+" 年龄:"+age;
	}

	public void method_1() {
		System.out.println("it is my public method one");
	}

	public void method_1(String str) {
		System.out.println("it is my public method one");
	}

	private void method_2(String str, int age) {
		System.out.println("it is my private method one");
	}
}

class ClassTest
{
	public static void main(String[] args) throws Exception {
		
		Person p = new Person("zhangsan", 18);

		Class cls = p.getClass();

		Person p1 = (Person) cls.newInstance(); //该方法调用对象中空参数构造方法
		                                        //如果该对象不具备空参数的构造方法
						        //则会引发异常 java.lang.InstantiationException	

		/* Constructor 类 【构造方法】 */

		//获取所有被public修饰的构造方法
		Constructor[] c1 = cls.getConstructors();

		//获取所有构造方法
		Constructor[] c2 = cls.getDeclaredConstructors();

		//获取指定构造方法,只能是public
		Constructor c3 = cls.getConstructor(String.class, int.class); 

		//获取任意指定构造方法
		Constructor c4 = cls.getDeclaredConstructor(String.class, int.class, String.class);  


		/* Field 类 【成员】 */

		//获取指定成员,注意:只能是被public修饰的成员
		Field f1 = cls.getField("age");

		//获取对象中所有被public修饰的成员
		Field[] f2 = cls.getFields();

		//获取任意指定成员
		Field f3 = cls.getDeclaredField("name");

		//获取对象所有成员
		Field[] f4 = cls.getDeclaredFields();


		/* Method 类 【方法】 */

		//获取指定方法,注意:只能是被public修饰的成员
		Method m1 = cls.getMethod("method_1"); //注意,第一参数后面可以跟0..n个参数。必须要有一个参数。

		//获取对象中所有被public修饰的方法
		Method[] m3 = cls.getMethods();

		//获取任意指定方法,注意,第一参数后面可以跟0..n个参数。必须要有一个参数。
		Method m4 = cls.getDeclaredMethod("method_2",String.class,int.class);

		//获取对象所有方法
		Method[] m5 = cls.getDeclaredMethods();
	}
}


上面抽取了部分的方法,还有很多方法,例如包,接口,类加载器等等就略过了,拿的是比较常用的举例。


下面演示下反射的应用示例:


import java.lang.reflect.*;


class Demo
{
	public String s1, s2, s3;

	Demo(String s1, String s2, String s3)
	{
		this.s1 = s1;
		this.s2 = s2;
		this.s3 = s3;
	}

	public String toString()
	{
		return s1+"..."+s2+"..."+s3;
	}

	public static void main(String[] args) throws Exception
	{
		method_1();
		method_2();
		method_3();
	}

	/* 通过反射 调用构造函数 */
	public static void method_1() throws Exception
	{
		Constructor constructor = String.class.getConstructor(StringBuffer.class);

		String value = (String) constructor.newInstance(new StringBuffer("abc"));

		System.out.println(value);

	}


	/* 通过反射 调用对象方法 */
	public static void method_2() throws Exception {

		String str = "abcde";

		Method m = String.class.getMethod("charAt", int.class);

		System.out.println(m.invoke(str, 2));

	}

	/* 通过反射 调用对象成员 */
	public static void method_3() throws Exception {
		Demo d = new Demo("abc", "abb", "bbc");
		Class cls = d.getClass();
		Field[] f = cls.getFields();

		for(Field field : f)
		{
			if(field.getType() == String.class)
			{
				String oldValue = (String) field.get(d);

				String newValue = oldValue.replace('b','a');

				field.set(d, newValue);
			}
		}
		System.out.println(d);
	}
}











  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值