1. 概念
反射,一种计算机处理方式。是程序可以访问、检测和修改它本身状态或行为的一种能力。
2. 反射机制的作用
通过反机制访问java类的属性,方法,构造方法等;
3.反射机制中的类
(1) java.lang.Class; 类的对象代表一个类的所有
(2) java.lang.reflect.Constructor; 类的对象代表构造函数
(3) java.reflect.Filed; 类的对象代表属性
(4) java.lang.Method; 类的对象代表方法
(5) java.lang.Modifier; 类的对象代表修饰符
例1:获取Class的三种方式

1 /* 2 获取Class的三种方式 3 */ 4 import java.util.Date; 5 class ReflectTest01 6 { 7 public static void main(String[] args) throws Exception 8 { 9 /*获取ReflectTest01test类*/ 10 //第一种方式 11 //c1引用保存内存地址只想堆中的对象,该对象代表的时ReflectTest01test整个类 12 Class c1= Class.forName("ReflectTest01test"); 13 //第二种方式 14 //java种每个类型都有clas属性 15 Class c2 = ReflectTest01test.class; 16 //第三种方式 17 //java语言种任何一个java对象都有getclass方法 18 ReflectTest01test e = new ReflectTest01test();//e的运行时类时ReflectTest01test 19 Class c3 = e.getClass();//c3时运行时类 20 21 22 System.out.println(c1); 23 System.out.println(c2); 24 System.out.println(c3); 25 /*获取java.util.Date类*/ 26 Class c4 = Class.forName("java.util.Date");//必须写类全名 27 Class c5 = Date.class; 28 29 Date d = new Date(); 30 Class c6 = d.getClass(); 31 32 System.out.println(c4); 33 System.out.println(c5); 34 System.out.println(c6); 35 36 37 } 38 }
例2:通过class对象创建java对象

1 /* 2 获取class类型的对象之后,可以创建该类的对象 3 */ 4 import java.util.*; 5 import java.text.*; 6 class ReflectTest03 7 { 8 public static void main(String[] args) throws Exception 9 { 10 Class c = Class.forName("ReflectTest01test"); 11 //创建此类Class对象所表示的类的一个新实例 12 Object o = c.newInstance();//ReflectTest01test类的无参数构造方法(此方法调用了无参数构造方法) 13 14 System.out.println(o);// ReflectTest01test@15db9742 15 16 //获得系统当前时间 17 Class c1 = Class.forName("java.util.Date"); 18 Object o1 = c1.newInstance(); 19 if(o1 instanceof Date){ 20 Date t = (Date)o1; 21 System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS").format(t)); 22 } 23 } 24 } 25 26 /* 27 ReflectTest01test类的无参数构造方法 28 ReflectTest01test@15db9742 29 2017-05-22 15:34:12 059 30 请按任意键继续. . . 31 */
例3:IO+Properties

/* IO+Properties 配置文件(属性文件通常以.Properties结束)test:(内容:username=zhangsan) 将配置文件中的中文转换成Unicode码方法: 命令行输入: 1. native2ascii 回车 2. 输入中文 3.将转换成的Unicode码复制到配置文件相应的位置 李四 */ import java.io.*; import java.util.*; class ReflectTest04 { public static void main(String[] args) throws Exception { //创建属性对象 Properties p = new Properties();//同map,单Key和Value只能是字符串,Key不能重复,如果重复则Value覆盖 //创建输入流 FileInputStream fis =new FileInputStream("test.Properties"); //将fis流中的所有数据加载到属性对象中 p.load(fis); fis.close(); String v = p.getProperty("username"); System.out.println(v); } }
例4:反射机制+IO+Properties+reflect动态创建java对象

1 /* 2 配置文件test1.Properties中的内容:className = java.util.Date 3 */ 4 import java.io.*; 5 import java.util.*; 6 class ReflectTest05 7 { 8 public static void main(String[] args) throws Exception 9 { 10 //1.创建属性对象 11 Properties p = new Properties(); 12 13 //2.创建流 14 FileInputStream fr = new FileInputStream("test1.Properties"); 15 //加载 16 p.load(fr); 17 //通过key获取value 18 String className = p.getProperty("className"); 19 System.out.println(className); 20 //通过反射机制创建对象 21 Class c = Class.forName(className); 22 Object o = c.newInstance(); 23 System.out.println(o); 24 } 25 } 26 /* 27 java.util.Date 28 Mon May 22 18:05:19 CST 2017 29 请按任意键继续. . . 30 31 */
例5:反编译类的所有Field
1.测试类

1 class User 2 { 3 private String id; 4 public int age; 5 protected String addr; 6 boolean sex; 7 8 }
2.java.lang.reflect.Filed类中的属性

1 /* 2 java.lang.reflect.Filed类中的属性 3 */ 4 import java.lang.reflect.*; 5 class ReflectTest06 6 { 7 public static void main(String[] args) throws Exception 8 { 9 //获取整个类 10 Class c = Class.forName("User"); 11 //获取属性Filed 12 //获取所有public修饰的属性 13 Field [] fs = c.getFields(); 14 System.out.println(fs.length); 15 System.out.println(fs[0].getName()); 16 System.out.println("............................."); 17 //获取所有的属性 18 Field [] fs1 = c.getDeclaredFields(); 19 for(Field field:fs1){ 20 //getModifiers作为整数返回由此 Member 所表示的成员或构造方法的 21 //Java 语言修饰符。应该使用 Modifier 类解码整数中的修饰符 22 int i = field.getModifiers(); 23 System.out.println(i); 24 System.out.println("............................."); 25 String strmodifiers = Modifier.toString(i); 26 System.out.println(strmodifiers); 27 System.out.println("............................."); 28 Class type = field.getType(); 29 System.out.println(type.getName());//获取类型的第一种方式 30 System.out.println(type.getSimpleName());//获取类型的第二种方式 31 System.out.println(field.getName()); 32 } 33 System.out.println("............................."); 34 35 //获取整个类 36 37 StringBuffer sb = new StringBuffer(); 38 sb.append(Modifier.toString(c.getModifiers())+"class"+" "+c.getSimpleName()+"{ "); 39 for(Field field:fs1){ 40 sb.append(" "); 41 sb.append(Modifier.toString(field.getModifiers())+" "); 42 sb.append(field.getType().getSimpleName()+" "); 43 sb.append(field.getName()+"; "); 44 } 45 sb.append("}"); 46 System.out.println(sb); 47 48 } 49 }
2.运行结果:

1 age ............................. 2 ............................. private ............................. java.lang.String String id 1 ............................. public ............................. int int age 4 ............................. protected ............................. java.lang.String String addr 0 ............................. ............................. boolean boolean sex ............................. class User{ private String id; public int age; protected String addr; boolean sex; } 请按任意键继续. . .
例6:反射某类具体某个Field

1 /* 2 java.lang.reflect.Field获取某个特定的属性 3 */ 4 import java.lang.reflect.*; 5 class ReflectTest07 6 { 7 public static void main(String[] args) throws Exception 8 { 9 //获取类 10 Class c = Class.forName("User"); 11 //获取id属性 12 Field idf = c.getDeclaredField("id"); 13 //获取某个特定的属性可以用来代替set..,get.. 14 Object o = c.newInstance(); 15 //打破封装,导致java属性不安全 16 idf.setAccessible(true); 17 idf.set(o,"001"); 18 System.out.println(idf.get(o));//001 19 } 20 }
例7:反编译某个类所有Method
1.测试类

1 class Test2 2 { 3 public boolean login(String name,String pwd){ 4 if("z".equals(name)&&"123".equals(pwd)){ 5 return true; 6 } 7 return false; 8 } 9 10 public void logout(){ 11 System.out.println("已退出"); 12 } 13 14 }
2. java.reflect.Method;

1 /* 2 java.reflect.Method; 3 */ 4 import java.lang.reflect.*; 5 class ReflectTest08 6 { 7 public static void main(String[] args) throws Exception 8 { 9 //获取类 10 Class c = Class.forName("Test2"); 11 //获取所有的方法 12 Method[] ms = c.getDeclaredMethods();//返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法 13 for(Method m : ms){ 14 System.out.println(Modifier.toString(m.getModifiers()));//Modifier对类和成员访问修饰符进行解码 15 //方法的返回值类型 16 Class returnType = m.getReturnType(); 17 18 System.out.println(returnType.getSimpleName());//得到类型的简写名称 19 //方法名 20 System.out.println(m.getName()); 21 //方法的形参列表 22 Class [] ParameterType = m.getParameterTypes();//getParameterTypes()按照声明顺序返回 Class 对象的数组,这些对象描述了此 Method 对象所表示的方法的形参类型。 23 for(Class ParmeterType:ParameterType ) 24 System.out.println(ParmeterType.getSimpleName()); 25 } 26 System.out.println("..............反编译............."); 27 //反编译 28 StringBuffer sb = new StringBuffer(); 29 sb.append(Modifier.toString(c.getModifiers())+"class"); 30 sb.append(c.getSimpleName()+"{ "); 31 for(Method m:ms){ 32 sb.append(" "); 33 sb.append(Modifier.toString(m.getModifiers())+" "); 34 sb.append(m.getReturnType().getSimpleName()+" "); 35 sb.append(m.getName()+"("); 36 //形参 37 Class [] parameterTypes = m.getParameterTypes(); 38 for(int i = 0;i<parameterTypes.length;i++){ 39 Class parameterType = parameterTypes[i]; 40 if(i==parameterTypes.length-1){ 41 sb.append(parameterType.getSimpleName()); 42 }else{ 43 sb.append(parameterType.getSimpleName()+","); 44 } 45 } 46 sb.append("){} "); 47 48 } 49 sb.append("} "); 50 51 System.out.println(sb); 52 } 53 }
运行结果:

1 public 2 void 3 logout 4 public 5 boolean 6 login 7 String 8 String 9 ..............反编译............. 10 classTest2{ 11 public void logout(){} 12 public boolean login(String,String){} 13 } 14 15 请按任意键继续. . .
例8.反编译某个类具体的Method

1 /* 2 java.lang.reflect 3 */ 4 import java.lang.reflect.*; 5 class ReflectTest09 6 { 7 public static void main(String[] args) throws Exception 8 { 9 //获取类 10 Class c = Class.forName("Test2"); 11 //获取某个特定的方法,通过方法名加形参列表 12 Method m = c.getDeclaredMethod("login",String.class,String.class); 13 //通过反射机制执行login方法 14 Object o = c.newInstance(); 15 //调用o对象的m方法,传递两个参数将结果存放在reValue中 16 Object reValue = m.invoke(o,"z","123"); 17 System.out.println(reValue); 18 } 19 }
例9.获取所有的构造方法

1 /* 2 获取构造方法 3 */ 4 import java.lang.reflect.*; 5 class ReflectTest10 6 { 7 public static void main(String[] args) throws Exception 8 { 9 Class c = Class.forName("Test2"); 10 //获取所有的构造方法 11 Constructor[] cs = c.getDeclaredConstructors(); 12 for(Constructor con : cs){ 13 //获取修饰符 14 System.out.println(Modifier.toString(con.getModifiers())); 15 //获取构造方法名 16 System.out.println(c.getName()); 17 //构造方法的形式参数列表 18 Class [] parameterTypes = con.getParameterTypes(); 19 for(Class parameterTyppe :parameterTypes){ 20 System.out.println(parameterTyppe.getSimpleName()); 21 } 22 } 23 //反编译 24 StringBuffer sb = new StringBuffer(); 25 sb.append(Modifier.toString(c.getModifiers())+"class"+c.getSimpleName()+"{ "); 26 //构造方法 27 for(Constructor con:cs){ 28 sb.append(" "); 29 sb.append(Modifier.toString(con.getModifiers())+" "); 30 sb.append(c.getSimpleName()+"("); 31 //形参 32 Class [] parameterTypes = con.getParameterTypes(); 33 for(int i=0;i<parameterTypes.length;i++){ 34 Class parameterType = parameterTypes[i]; 35 if(i==parameterTypes.length-1){ 36 sb.append(parameterType.getSimpleName()); 37 } 38 else{ 39 sb.append(parameterType.getSimpleName()+","); 40 } 41 } 42 sb.append("){} "); 43 } 44 sb.append("}"); 45 System.out.println(sb); 46 } 47 } 48 /* 49 public 50 Test2 51 classTest2{ 52 public Test2(){} 53 } 54 请按任意键继续. . . 55 */
例10.获取某个类的某个构造方法

1 /* 2 反射某个类某个构造方法,创建对象 3 */ 4 import java.lang.reflect.*; 5 class ReflectTest11 6 { 7 public static void main(String[] args) throws Exception 8 { 9 //获取类 10 Class c = Class.forName("Customer"); 11 //获取特定的构造方法 12 Constructor con = c.getDeclaredConstructor(String.class,int.class); 13 //创建对象 14 Object o = con.newInstance("zhangsan",90); 15 System.out.println(o); 16 } 17 } 18 class Customer 19 { 20 String name; 21 int age; 22 Customer(String name,int age){ 23 this.name = name; 24 this.age=age; 25 } 26 public String toString(){ 27 return "Customer["+name+","+age+"]"; 28 } 29 30 31 } 32 /* 33 Customer[zhangsan,90] 34 请按任意键继续. . . 35 */
例11.获取父类和父接口

1 /* 2 类获取父类和父接口 3 */ 4 5 class ReflectTest12 6 { 7 public static void main(String[] args) throws Exception 8 { 9 Class c = Class.forName("java.lang.String"); 10 //获取父类 11 Class superclass = c.getSuperclass(); 12 System.out.println(superclass.getName()); 13 //获取父接口(多个) 14 Class [] ins = c.getInterfaces(); 15 for(Class in :ins){ 16 System.out.println(in.getName()); 17 } 18 } 19 /* 20 java.lang.Object 21 java.io.Serializable 22 java.lang.Comparable 23 java.lang.CharSequence 24 请按任意键继续. . . 25 26 */
。