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