loading黑马程序员之高级编程:反射(4-2)

-------android培训 、java培训、期待与您交流! ----------

Java 反射API的第一个主要作用是获取程序在运行时刻的内部结构。这对于程序的检查工具和调试器来说,是非常实用的功能。只需要短短的十几行代码,就可以遍历出来一个Java类的内部结构,包括其中的构造方法、声明的域和定义的方法等。这不得不说是一个很强大的能力。只要有了java.lang.Class类 的对象,就可以通过其中的方法来获取到该类中的构造方法、域和方法。对应的方法分别是getConstructorgetFieldgetMethod。这三个方法还有相应的getDeclaredXXX版本,区别在于getDeclaredXXX版本的方法只会获取该类自身所声明的元素,而不会考虑继承下来的。ConstructorFieldMethod这三个类分别表示类中的构造方法、域和方法。这些类中的方法可以获取到所对应结构的元数据。

反射API的另外一个作用是在运行时刻对一个Java对象进行操作。 这些操作包括动态创建一个Java类的对象,获取某个域的值以及调用某个方法。在Java源代码中编写的对类和对象的操作,都可以在运行时刻通过反射API来实现。



基类:

package com.heima.reflection;

public class ReflectPoint {

		private int x;
		public int y;
		private String a = "a";
		public String b = "b";
		public String c = "ch";
		public ReflectPoint(int x, int y) {
			this.x = x;
			this.y = y;
		}
		public ReflectPoint(String a, String b) {
			this.a = a;
			this.b = b;
		}
		
		public String toString(){
			return "a="+this.getA()+"\t b="+this.getB()+"\t c="+this.getC();
		}
		
		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result + x;
			result = prime * result + y;
			return result;
		}
		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			ReflectPoint other = (ReflectPoint) obj;
			if (x != other.x)
				return false;
			if (y != other.y)
				return false;
			return true;
		}
		public int getX() {
			return x;
		}
		public void setX(int x) {
			this.x = x;
		}
		public int getY() {
			return y;
		}
		public void setY(int y) {
			this.y = y;
		}
		public String getA() {
			return a;
		}
		public void setA(String a) {
			this.a = a;
		}
		public String getB() {
			return b;
		}
		public void setB(String b) {
			this.b = b;
		}
		public String getC() {
			return c;
		}
		public void setC(String c) {
			this.c = c;
		}
		
		
}

字段Demo:

package com.heima.reflection;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
public class FieldDemo {

	public static void main(String[] args) throws Exception {
		Constructor<ReflectPoint> constructor = ReflectPoint.class.getConstructor(int.class,int.class);
		ReflectPoint point = constructor.newInstance(3,5);
		//field不是对象的变量,而是类的
		//getField只能拿到类中的非private成员
		Field fieldy = point.getClass().getField("y");
		System.out.println(fieldy.get(point));
		
		//getDeclaredField:暴力反射
		//看见了,拿不到
		Field fieldx = point.getClass().getDeclaredField("x");
		//拿到了
		fieldx.setAccessible(true);
		System.out.println(fieldx.get(point));
		
		
	}

}

方法Demo:

package com.heima.reflection;

import java.lang.reflect.Method;

public class MethodDemo {

	
	public static void main(String[] args) throws Exception{
		String str = "reflection method";
		Method method = String.class.getMethod("charAt", int.class);
		//method.invoke(null, 0):没有对象,那method就是静态方法咯
		System.out.println(method.invoke(str, 0));
		System.out.println(method.invoke(str, new Object[]{1}));//jdk5.0以前的invoke方法,向下兼容
	}

}

构造函数Demo:

package com.heima.reflection;

import java.lang.reflect.Constructor;


/**
 * 快捷键:alt+shift+字母:eclipse菜单栏
 * 反射:把Java类中的各个组件映射成相应的Java类
 * Class是一个类,Field,method,等也是一个类
 *反射很耗内存
 */
public class ConstructorDemo {

	public static void main(String[] args) throws Exception {
		//JDK5.0新特性:可变参数;5.0以前用的是数组
		Constructor<String> con = String.class.getConstructor(StringBuilder.class);
		System.out.println(con.getDeclaringClass());
		//1.正常创建对象
		String str1 = new String(new StringBuilder("normal"));
		//2.反射创建对象
		String str2 = con.newInstance(new StringBuilder("reflect"));
		//3.得到默认构造函数:缓存机制来保存默认构造函数的实例对象
		String str3 = String.class.newInstance();
		
	}

}


练习:

package com.heima.reflection;

import java.lang.reflect.Field;
/**
 * 变量的综合应用
 *
 */
public class practice {

	public static void main(String[] args) throws Exception {
		ReflectPoint point = new ReflectPoint("applyb", "beara");
		changeStringValue(point);
		System.out.println(point.toString());
		
	}

	/**
	 * 改变任意一个对象中所有String类型的值,把所有a改成b
	 * @param obj
	 * @throws Exception
	 */
	public static void changeStringValue(Object obj) throws Exception {
		// 1.得到所有声明的字段,包括private的
		Field[] fields = obj.getClass().getDeclaredFields();
		// 2.过滤String类型的字段
		for (Field f : fields) {
			f.setAccessible(true); // 暴力反射:可以得到私有成员
			// 字节码只有一份
			if (f.getType() == String.class) {
				// 3.改变值
				String value = (String) f.get(obj);
				value = value.replace("a", "b");
				f.set(obj, value);
			}
		}
	}

}

------- android培训  、 java培训 、期待与您交流! ----------






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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值