网站首页 > java教程 正文
一 , 什么是java反射机制?
JAVA反射机制是在运行状态中,对于任意一个实体类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
- JAVA反射(放射)机制:“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。但是JAVA有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods
- Java 反射是Java语言的一个很重要的特征,它使得Java具体了“动态性”
JAVA反射提供的功能
- 在运行时判断任意一个对象所属的类
- 在运行时构造任意一个类的对象
- 在运行时判断任意一个类所具有的成员变量和方法
- 在运行时调用任意一个对象的方法
在JDK中,主要由以下类来实现Java反射机制,这些类都位于java.lang.reflect包中:
Class类:代表一个类
Field 类:代表类的成员变量(成员变量也称为类的属性)
Method类:代表类的方法
Constructor 类:代表类的构造方法
Array类:提供了动态创建数组,以及访问数组的元素的静态方法
Reflection API的实际运用
在java.lang.Object 类中定义了getClass()方法,因此对于任意一个Java对象,都可以通过此方法获得对象的类型。Class类是Reflection API 中的核心类,它有以下方法
getName():获得类的完整名字。
getFields():获得类的public类型的属性。
getDeclaredFields():获得类的所有属性。
getMethods():获得类的public类型的方法。
getDeclaredMethods():获得类的所有方法。
getMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes 参数指定方法的参数类型。
getConstructors():获得类的public类型的构造方法。
getConstructor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes 参数指定构造方法的参数类型。
newInstance():通过类的不带参数的构造方法创建这个类的一个对象。
利用反射机制运行时复制对象
public class User {
private Long id;
private String name;
private int age;
public User() {
}
public Customer(final String name, final int age) {
this.name = name;
this.age = age;
}
public Long getId() {
return id;
}
public void setId(final Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName (final String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(final int age) {
this.age = age;
}
}
ublic class ReflectTest {
public Object copy(final Object object) throws Exception {
Class<?> classType = object.getClass(); // 获得对象的类型
System.out.println("Class:" + classType.getName());
// 通过默认构造方法创建一个新的对象
Object objectCopy = classType.getConstructor(new Class[]{}).newInstance(new Object[]{});
Field fields[] = classType.getDeclaredFields(); // 获得对象的所有属性
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
String fieldName = field.getName();
String firstLetter = fieldName.substring(0, 1).toUpperCase();
String getMethodName = "get" + firstLetter + fieldName.substring(1); // 获得和属性对应的getXXX()方法的名字
String setMethodName = "set" + firstLetter + fieldName.substring(1); // 获得和属性对应的setXXX()方法的名字
// 获得和属性对应的getXXX()方法
Method getMethod = classType.getMethod(getMethodName, new Class[]{});
// 获得和属性对应的setXXX()方法
Method setMethod = classType.getMethod(setMethodName, new Class[]{field.getType()});
Object value = getMethod.invoke(object, new Object[]{}); // 调用原对象的getXXX()方法
System.out.println(fieldName + ":" + value);
setMethod.invoke(objectCopy, new Object[]{value}); // 调用拷贝对象的setXXX()方法
}
return objectCopy;
}
public static void main(final String[] args) throws Exception {
User user= new User("Tom", 21);
user.setId(new Long(1));
User userCopy = (User) new ReflectTest().copy(customer);
System.out.println("Copy information:" + userCopy.getId() + " " + userCopy.getName() + " "
+ userCopy.getAge());
}
}
动态创建和访问数组元素的各种静态方法。
例程ArrayTest 类的main()方法创建了一个长度为15 的字符串数组,接着把索引位置为11 的元素设为“hello word”,然后再读取索引位置为10 的元素的值
public class ArrayTester1 {
public static void main(String args[]) throws Exception {
Class<?> classType = Class.forName("java.lang.String");
Object myArray = Array.newInstance(classType, 15); // 创建一个长度为15的字符串数组
Array.set(myArray, 10, "hello word"); // 把索引位置为10的元素设为"hello"
String s = (String) Array.get(array, 10); // 获得索引位置为10的元素的值
System.out.println(s);
}
}
main()方法创建了一个 10 x 20 x 30 的整型数组,并把索引位置为[4][10][20] 的元素的值为设50。
public class ArrayTest {
public static void main(String args[]) {
int[] dimArray = new int[]{10, 20, 30};
Object array = Array.newInstance(Integer.TYPE, dimArray);//创建一个具有指定的数值类型和三个维度的新数组。
final Object arrayObjecy = Array.get(array, 4);
final Class<?> myClass = arrayObjecy.getClass().getComponentType();
System.out.println(myClass);
arrayObj = Array.get(arrayObj, 10);
Array.setInt(arrayObj, 20, 50);
int arrayCast[][][] = (int[][][]) array;
System.out.println(arrayCast[3][5][10]);
}
}
利用反射机制修改对象
运行时变更field内容
与先前两个动作相比,“变更field内容”轻松多了,因为它不需要参数和自变量。首先调用Class的getField()并指定field名称。获得特定的Field object之后便可直接调用Field的get()和set()。
public class RefFiled {
public double x;
public Double y;
public static void main(String args[]) throws NoSuchFieldException, IllegalAccessException {
Class c = RefFiled.class;
Field xf = c.getField("x");
Field yf = c.getField("y");
RefFiled obj = new RefFiled();
System.out.println("变更前x=" + xf.get(obj));
//变更成员x值
xf.set(obj, 1.1);
System.out.println("变更后x=" + xf.get(obj));
System.out.println("变更前y=" + yf.get(obj));
//变更成员y值
yf.set(obj, 2.1);
System.out.println("变更后y=" + yf.get(obj));
}
}
猜你喜欢
- 2024-09-12 学习java应该如何理解反射?(怎么理解java反射)
- 2024-09-12 Java反射详解(java反射总结)
- 2024-09-12 读懂框架设计的灵魂—Java 反射机制
- 2024-09-12 Java的反射机制(java的反射机制是什么)
- 2024-09-12 java反射机制Java反射机制是什么?原理详解
- 2024-09-12 聊一聊Java当中的反射机制(java的反射机制是什么)
- 2024-09-12 Java反射机制的理解(java反射机制的理解和认识)
- 2024-09-12 聊一聊Java的反射机制?(java的反射机制是什么)
- 2024-09-12 Java学习之二——JAVA反射机制(java 反射机制原理)
- 2024-09-12 实操讲解Java的反射机制,你要是再看不懂,神仙都没救了
你 发表评论:
欢迎- 最近发表
-
- Java常量定义防暴指南:从"杀马特"到"高富帅"的华丽转身
- Java接口设计原则与实践:优雅编程的艺术
- java 包管理、访问修饰符、static/final关键字
- Java工程师的代码规范与最佳实践:优雅代码的艺术
- 编写一个java程序(编写一个Java程序计算并输出1到n的阶乘)
- Mycat的搭建以及配置与启动(mycat部署)
- Weblogic 安装 -“不是有效的 JDK Java 主目录”解决办法
- SpringBoot打包部署解析:jar包的生成和结构
- 《Servlet》第05节:创建第一个Servlet程序(HelloSevlet)
- 你认为最简单的单例模式,东西还挺多
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)