Java的反射
来源:互联网 发布:他知而自不知的我属于 编辑:程序博客网 时间:2024/06/05 06:30
本文主要围绕以下几个点来详解反射:
1、反射机制是什么?
2、反射机制能做什么?
3、Java中反射的API以及应用
1.反射机制是什么?
借用百度百科的定义:
反射机制是在运行状态中:
1、对于任意一个类,都能够知道这个类的所有属性和方法;
2、对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
之所以强调属性、方法,是因为属性、方法是开发者对于一个类最关注的两个部分。实际上通过反射,不仅仅可以获知类的属性、方法,还可以获知类的父类、接口、包等信息
至于反射的原理,不难,Java类加载机制中讲到了,一个类在加载的时候,会在内存中生成一个代表这个.class文件的java.lang.Class对象,.classs文件里面就包含了描述这个类的信息的一切内容。至于.class文件,是由Java编译器(注意是Java编译器,指的不仅仅是Javac)编译而来的,是编译原理的领域。
2. 反射机制能做什么?
下面第二个问题,反射机制能做什么?
反射机制主要提供了以下功能:
1. 在运行时判断任意一个对象所属的类;
2. 在运行时构造任意一个类的对象;
3. 在运行时判断任意一个类所具有的成员变量和方法;
4. 在运行时调用任意一个对象的方法;
5. 生成动态代理。
3.发射机制的API以及应用实例
Class类库与java.lang.reflect类库一起对反射机制提供了支持。
1.通过一个实例对象获取完整的包名和类名
@Testpublic void test1(){ ReflectTest reflectTest = new ReflectTest(); System.out.println(reflectTest.getClass().getName());}/**output~test.ReflectTest*/
2.实例化class类对象
@Testpublic void test2() throws ClassNotFoundException { Class<?> class1 = null; class1 = Class.forName("test.ReflectTest"); System.out.println("类名称是:"+class1);}/**output~类名称是:class test.ReflectTest*/
3.获取一个对象的父类与实现的接口
@Testpublic void test3() throws ClassNotFoundException { Class<?> clazz = null; clazz = Class.forName("test.ReflectTest"); //获取父类 Class<?> parentClass = clazz.getSuperclass(); System.out.println("clazz的父类为:" + parentClass.getName()); // 获取所有的接口 Class<?> intes[] = clazz.getInterfaces(); System.out.println("clazz实现的接口有:"); for (int i = 0; i < intes.length; i++) { System.out.println((i + 1) + ":" + intes[i].getName()); }}/**output~clazz的父类为:java.lang.Objectclazz实现的接口有:1:java.io.Serializable*/
4.获取某一个类中全部构造函数 以及 实例化一个类对象
@Testpublic void test4() throws Exception { Class<?> class1 = null; class1 = Class.forName("test.User"); // 第一种方法,实例化默认构造方法,调用set赋值 User user = (User) class1.newInstance(); user.setAge(23); user.setName("LouLou"); System.out.println(user); // 结果 User [age=20, name=Rollen] // 第二种方法 取得全部的构造函数 使用构造函数赋值 Constructor<?> cons[] = class1.getConstructors(); // 查看每个构造方法需要的参数 for (int i = 0; i < cons.length; i++) { Class<?> clazzs[] = cons[i].getParameterTypes(); System.out.print("cons[" + i + "] ("); for (int j = 0; j < clazzs.length; j++) { if (j == clazzs.length - 1) System.out.print(clazzs[j].getName()); else System.out.print(clazzs[j].getName() + ", "); } System.out.println(")"); } // 结果 // cons[0] (int, java.lang.String) //cons[1] (java.lang.String) //cons[2] () user = (User) cons[0].newInstance(23, "LouLou"); System.out.println(user); // 结果 User [age=23, name=LouLou] user = (User) cons[1].newInstance("LouLou"); System.out.println(user); // 结果 User [age=0, name=LouLou]}//实体类class User { private int age; private String name; public User() { super(); } public User(String name) { super(); this.name = name; } public User(int age, String name) { super(); this.age = age; this.name = name; } 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; } @Override public String toString() { return "User [age=" + age + ", name=" + name + "]"; }}
5.获取某个类的全部属性
class Parent { private Integer pf1=1; protected Integer pf2=2; public Integer pf3=3; Integer pf4=4;}public class ReflectTest extends Parent implements Serializable{ private String field1="field1"; protected String field2="field2"; public String field3="field3"; String field4="field3"; @Test public void test5() throws Exception { Class<?> clazz = null; clazz = Class.forName("test.ReflectTest"); System.out.println("===============本类属性==============="); Field[] field = clazz.getDeclaredFields();//获取本类的全部属性(不包括父类或则实现的接口) for (int i = 0; i < field.length; i++) { // 权限修饰符 int mo = field[i].getModifiers(); String priv = Modifier.toString(mo); // 属性类型 Class<?> type = field[i].getType(); System.out.println(priv + " " + type.getName() + " " + field[i].getName() + ";"); } System.out.println("==========本类或则实现的接口或者父类的public的属性=========="); // 取得实现的接口或者父类的属性 Field[] filed1 = clazz.getFields(); for (int j = 0; j < filed1.length; j++) { // 权限修饰符 int mo = filed1[j].getModifiers(); String priv = Modifier.toString(mo); // 属性类型 Class<?> type = filed1[j].getType(); System.out.println(priv + " " + type.getName() + " " + filed1[j].getName() + ";"); } }}/**output~===============本类属性===============private java.lang.String field1;protected java.lang.String field2;public java.lang.String field3; java.lang.String field4;==========本类或则实现的接口或者父类的public的属性==========public java.lang.String field3;public java.lang.Integer pf3;*/
从上面的运行结果可知:
Class.getDeclaredFields()方法放回的是当前类里面的所有属性。Class.getFields()返回的是当前类已及父类和实现的接口的所有public修饰的属性。
6.获取某个类的全部方法
private void testtttt(){}/** * 获取某个类的全部方法 * @throws Exception */@Testpublic void test6() throws Exception { Class<?> clazz = Class.forName("test.ReflectTest"); Method[] method = clazz.getMethods();//获取本类以及继承类\实现接口的所有public修饰的方法 //Method[] method = clazz.getDeclaredMethods();//只获取本类的所有方法 for(int i=0; i<method.length; i++){ int mod = method[i].getModifiers(); String modifier = Modifier.toString(mod);//获取方法修饰符 Class<?> returnType = method[i].getReturnType();//获取返回值类型 Class<?> [] para = method[i].getParameterTypes();//获取参数类型 System.out.print(modifier + " "); System.out.print(returnType.getName() + " "); System.out.print(method[i].getName() + " "); System.out.print("("); for (int j = 0; j < para.length; ++j) { System.out.print(para[j].getName() + " " + "arg" + j); if (j < para.length - 1) { System.out.print(","); } } Class<?> exce[] = method[i].getExceptionTypes(); if (exce.length > 0) { System.out.print(") throws "); for (int k = 0; k < exce.length; ++k) { System.out.print(exce[k].getName() + " "); if (k < exce.length - 1) { System.out.print(","); } } } else { System.out.print(")"); } System.out.println(); }}
1)clazz.getMethods();//获取本类以及继承类\实现接口的所有public修饰的方法
//执行结果是:
可知,里面都是public修饰的方法,private修饰的testtttt()并没有打印出来;
2)clazz.getDeclaredMethods();//只获取本类的所有方法
//执行结果是:
本类的所有方法都被获取到了。
7.通过反射机制调用某个类的方法
public void reflect1() { System.out.println("Java 反射机制 - 调用某个类的方法1.");}public void reflect2(int age, String name) { System.out.println("Java 反射机制 - 调用某个类的方法2."); System.out.println("age -> " + age + ". name -> " + name);}/** * 通过反射机制调用某个类的方法 */@Testpublic void test7() throws Exception{ Class<?> clazz = Class.forName("test.ReflectTest"); // 调用TestReflect类中的reflect1方法 Method method = clazz.getMethod("reflect1"); method.invoke(clazz.newInstance()); //output: Java 反射机制 - 调用某个类的方法1. // 调用TestReflect的reflect2方法 method = clazz.getMethod("reflect2", int.class, String.class); method.invoke(clazz.newInstance(), 20, "张三"); // Java 反射机制 - 调用某个类的方法2. //output: age -> 20. name -> 张三}
8.通过反射机制操作某个类的属性
private String proprety = null;/** * 通过反射机制操作某个类的属性 */@Testpublic void test8() throws Exception{ Class<?> clazz = Class.forName("test.ReflectTest"); Object obj = clazz.newInstance(); // 可以直接对 private 的属性赋值 Field field = clazz.getDeclaredField("proprety"); field.setAccessible(true); field.set(obj, "Java反射机制"); System.out.println("proprety="+field.get(obj));}
所有源代码的github地址
- JAVA反射-反射的基本概念
- 反射,java的灵魂
- java的反射机制
- Java的反射机制
- Java的反射机制
- 说说Java的反射
- 反射,java的灵魂
- Java 的反射机制
- 反射,java的灵魂
- JAVA的反射机制
- Java 的反射机制
- java的反射机制
- Java的反射机制
- Java 的反射机制
- JAVA的反射机制
- Java 的反射机制
- java的反射机制
- java的反射机制
- 数组+链表 = [骗分]块状链表
- C#图解教程 第五章 方法
- 32. Longest Valid Parentheses
- Java集合框架综述
- c语言基本数据类型short、int、long、char、float、double
- Java的反射
- 七天使的通讯(angelus)
- strcpy()源代码
- 《程序员的自我修养》--目标文件有什么和ELF文件格式简述
- Cogs 1688. [ZJOI2008]树的统计Count(树链剖分+线段树||LCT)
- 顺序表和链表的比较
- c++优先队列用法
- Google C++单元测试框架---Gtest框架简介(译文)
- 问题四十五:怎么画ray tracing图形中的blending and joining surface