java 反射机制详解编程语言
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
注意:反射是在运行的时候进行的,不是在编译的时候运行的。
反射的功能
Java反射机制主要提供了以下功能:
在运行时判断任意一个对象所属的类; 在运行时构造任意一个类的对象; 在运行时判断任意一个类所具有的成员变量和方法; 在运行时调用任意一个对象的方法;生成动态代理。API简介
在这里先看一下sun为我们提供了那些反射机制中的类:
— java.lang.Class; 代表一个类
— java.lang.reflect.Constructor; 代表类的构造方法
— java.lang.reflect.Field; 代表类的成员变量(成员变量也称为类的属性)
— java.lang.reflect.Method; 代表类的方法
— java.lang.reflect.Array; 提供了动态创建数组,以及访问数组的元素的静态方法
注意:java中无论生成某个类的多少对象, 这些对象都会对应于同一个Class对象。
方法介绍
获取Class的三种方式
1)、使用Class类的forName(String className)静态方法。改方法需要传入字符串参数,改字符串参数的值是某个类的全限定类名(必须添加完整的包名)。
Class.forName("java.lang.String");
2)、调用某个类的class属性来获取该类对应的class对象,如
String.class
3)、调用某个对象的getClass方法。
String s = "aa"; Class ? clazz = s.getClass();
生成对象
1)、通过不带参数的构造方法生成对象有两种方法
a)、先获得Class对象,然后通过该Class对象的newInstance()方法直接生成即可:
newInstance()方法可以返回一个实例,但是构造方法要是没有参数列表的,它相当于调用某个类的不带参数的构造方法,但是如果在初始化对象的时候要传参数,就要使用Constructor
Class ? classType = String.class;
Object obj = classType.newInstance();
b)、先获得Class对象,然后通过该对象获得相应的Constructor对象,再通过该Constructor对象的newInstance()方法生成:
Class ? classType = object.getClass(); Constructor cons = classType.getConstructor(new Class[]{}); Object obj = cons.newInstance(new Object[]{});
2)、若想通过类的带参数的构造方法生成对象,只能使用下面一种方式:
Class ? classType = object.getClass(); Constructor cons = classType.getConstructor(new Class[]{String.class,int.class}); Object obj = cons.newInstance(new Object[]{"hello",3});
例子
public class ReflectTester //方法实现对Customer对象的拷贝操作 public Object copy(Object object) throws Exception Class ? classType = object.getClass(); /*Constructor cons = classType.getConstructor(new Class[]{}); Object obj = cons.newInstance(new Object[]{}); System.out.println(obj); System.out.println("-----------");*/ //以上的两行代码等价于下面一行 //Object obj2 = classType.newInstance(); Constructor cons2 = classType.getConstructor(new Class[]{String.class, int.class}); Object obj2 = cons2.newInstance(new Object[]{"hello",3}); System.out.println(obj2); return null; public static void main(String[] args) throws Exception { ReflectTester test = new ReflectTester(); test.copy(new Customer()); class Customer private Long id; private int age; private String name; public Customer() public Customer(String name,int age) this.name = name; this.age= age; public Long getId() { return id; public void setId(Long id) { this.id = id; public int getAge() { return age; public void setAge(int age) { this.age = age; public String getName() { return name; public void setName(String name) { this.name = name; }
相对复杂的例子
import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; public class ReflectTester //方法实现对Customer对象的拷贝操作 public Object copy(Object object) throws Exception Class ? classType = object.getClass(); Object ObjectCopy = classType.getConstructor(new Class[]{}).newInstance(new Object[]{}); //获得成员变量 Field[] fields = classType.getDeclaredFields(); for(Field field : fields) String name = field.getName(); String firstLetter = name.substring(0,1).toUpperCase(); //将属性的首字母转换为大写 String getMethodName = "get" + firstLetter + name.substring(1); String setMethodName = "set" + firstLetter + name.substring(1); Method getMethod = classType.getMethod(getMethodName, new Class[]{}); Method setMethod = classType.getMethod(setMethodName, new Class[]{field.getType()}); Object value = getMethod.invoke(object, new Object[]{}); setMethod.invoke(ObjectCopy, new Object[]{value});
public static void main(String[] args) throws Exception { Customer customer = new Customer("tom",20); customer.setId(1L); ReflectTester test = new ReflectTester(); Customer cus = (Customer)test.copy(customer); System.out.println(cus.getAge()+","+cus.getName()+","+cus.getId()); class Customer private Long id; private int age; private String name; public Customer() public Customer(String name,int age) this.name = name; this.age= age; public Long getId() { return id; public void setId(Long id) { this.id = id; public int getAge() { return age; public void setAge(int age) { this.age = age; public String getName() { return name; public void setName(String name) { this.name = name; }
注意:Integer.TYPE返回的是int,而Integer.class返回的是Integer类所对应的Class对象。
反射生成多维数组
import java.lang.reflect.Array; * 用反射构造一个多维数组 public class ArrayTester2 { public static void main(String[] args) { int[] dims = new int[]{5,10,15}; //newInstance()方法的第二个参数是代表生成数组的维度,所以生成的数组维度为5,10,15,长宽高 Object array = Array.newInstance(Integer.TYPE,dims); //arrayObj是一个二维的数组 Object arrayObj = Array.get(array,3); Class ? classType = arrayObj.getClass().getComponentType(); //arrayObj是一个一维的数组 arrayObj = Array.get(arrayObj, 5); Array.setInt(arrayObj, 10, 37); int[][][] arrayCast = (int[][][])array; System.out.println(arrayCast[3][5][10]); }
反射访问私有(private)的方法
private 限制的方法没有办法在另外的类中使用,但可以使用反射进行使用。而getMethod()方法只能获取public的方法。如果要使用private的方法就要使用 getDeclaredMethod()方法。
例子1、获取privete方法、
public class PrivateTest { private String sayHello(String name) return "hello" + name; }
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class TestPrivate { public static void main(String[] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException { PrivateTest p = new PrivateTest(); Class ? classType = p.getClass(); Method method = classType.getDeclaredMethod("sayHello", new Class[]{String.class}); method.setAccessible(true); //压制java的访问控制检查 String str = (String)method.invoke(p, new Object[]{"aaa"}); System.out.println(str); }
例子2、改变private的属性
public class Private2 { private String name = "zhangsan"; public String getName() return name; }
致谢:感谢您的阅读!
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/15134.html
cjava相关文章
- Java爱心代码_java怎么敲入代码
- Java反射(超详细!)[通俗易懂]
- JAVA项目集锦 Java项目视频20套
- Java 8 的 java.util.function.* POJO 的反射新方法
- forkjoin并发分页查数据_java fork join
- Java注解的介绍和反射使用
- Java基础学习笔记二十三 Java核心语法之反射详解编程语言
- 你需要理解的 Java 反射机制知识总结详解编程语言
- Java反射获取类和对象信息全解析详解编程语言
- 通过Java反射机制,动态给对象属性赋值,并获取属性值详解编程语言
- Java 反射工具类详解编程语言
- Java学习笔记之七java函数的语法规则总结详解编程语言
- Java学习笔记之五java数组详解编程语言
- java反射机制详解编程语言
- 在 Java 的反射中,Class.forName 和 ClassLoader 的区别详解编程语言
- java之反射基础知识介绍详解编程语言
- Java反射机制详解编程语言
- 开启Java之门:访问MySQL数据库(java访问mysql数据库)
- 通过Java反射调用方法详解编程语言
- Java问题-java进程占用内存过高,排查原因详解编程语言
- Java编程操作Oracle数据库(java操作oracle)
- 工具Linux上使用Java开发的利器:选择指南(linux选择java)
- 掌握必备技能:Linux下Java命令的使用(java命令linux)
- Linux系统中下载Java的方法(linux下java下载)
- Java实现Linux:跨平台解决方案(java 实现linux)
- 市场Oracle公司助力Java攻克市场(oracle公司java)
- Java锁表与Oracle数据库协调实现数据安全(java锁表oracle)