反射(Reflection)是Java 程序开发语言的特征之一,它允许运行中的 Java 程序获取自身的信息,并且可以操作类或对象的内部属性
与反射有关的类包.
java.lang.reflect.*;
java.lang.Class;
下面来看反射到底能做什么:
- 获取Class对象
1).Object.getCalss(); 2).Class.forName(String) (String的写法:包名.类名.就会创建包名.类名对应的那个对象) ( 注:1.2只适用于引用类型) 3).封装类.TYPE 返回对应的基本类型的Class对象. Integer.TYPE对应的是int的Class对象 注:3只适用于基本类型 4).类型.Class。 注:4是通用的 上面的4种方法,只有方法2是动态的,只要换一个包就可以了.它具有动态潜质.所以真正意义的想体现动态编程只能使用方法2. eg:
1 package com.company; 2 3 public class Main { 4 public static void main(String[] args) throws Exception { 5 Person person = new Person("batty"); 6 /* clazz 是储存Person类内容(constructor、field、method等)的类 7 也就是说,Class是储存类信息的类 8 */ 9 Class clazz = Class.forName("com.company.Person"); 10 System.out.println("person.getClass(): " + person.getClass()); // class com.company.Person 11 System.out.println("clazz.getClass(): " + clazz.getClass()); // class java.lang.Class 12 System.out.println("clazz.getName(): " + clazz.getName()); // com.company.Person 13 System.out.println("clazz.getClass().getName(): " + clazz.getClass().getName()); // java.lang.Class 14 System.out.println("person.getClass(): "+ person.getClass()); // class com.company.Person 15 System.out.println("Class.forName("Person"): " + Class.forName("com.company.Person")); // class com.company.Person 16 System.out.println("String.TYPE " + Integer.TYPE); // int 17 System.out.println("person.class: " + Person.class); // class com.company.Person 18 } 19 } 20 class Person{ 21 String name; 22 Person(String name) { 23 this.name = name; 24 } 25 }
- 获取类中的构造函数
[获取构造<根据参数类型>](使用时一般用不带declared的,即蓝色字体) Constructor<T> getConstructor(Class<?>... parameterTypes) 返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。 Constructor<?>[] getConstructors() 返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法。 Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法。 Constructor<?>[] getDeclaredConstructors() 返回 Constructor 对象的一个数组,这些对象反映此 Class 对象表示的类声明的所有构造方法。
具体使用例子:利用反射调用构造函数
1 package Reflect; 2 import java.lang.reflect.Constructor; 3 class Demo() { 4 String name; 5 Demo() {} 6 Demo(String name) { 7 this.name = name; 8 } 9 @Override 10 String toString(){ 11 return "["+this.name+"]"; 12 } 13 } 14 public class test() { 15 public static void main(String[] args) { 16 Class<?> test = null; 17 try { 18 test = Class.forName(Reflect.Demo); 19 } catch (Exception e) { 20 e.printStackTrace(); 21 } 22 Demo d1 = null; 23 Demo d2 = null; 24 Constructor<?> cons[]=test.getConstructors(); 25 try { 26 d1=(Demo)cons[0].newInstance(); 27 d2=(Demo)cons[1].newInstance("TestDemo"); 28 } catch(Exception e){ 29 e.printStackTrace(); 30 } 31 System.out.println(d1); 32 System.out.println(d2); 33 } 34 }
- 获取类中的成员函数(method)
[获取方法<方法名加上参数类型>](使用时一般用不带declared的,即蓝色字体) Method getMethod(String name, Class<?>... parameterTypes) 返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。 Method[] getMethods() 返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法。 Method getDeclaredMethod(String name, Class<?>... parameterTypes) 返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。 Method[] getDeclaredMethods() 返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。
具体使用例子:利用反射调用方法1 package Reflect; 2 import java.lang.reflect.Constructor; 3 class Demo() { 4 String name; 5 Demo() {} 6 Demo(String name) { 7 this.name = name; 8 } 9 void demoTest(String name) { 10 System.out.println(this.name); 11 } 12 @Override 13 String toString(){ 14 return "["+this.name+"]"; 15 } 16 } 17 public class test() { 18 public static void main(String[] args) { 19 Class<?> test = null; 20 try { 21 test = Class.forName(Reflect.Demo); 22 } catch (Exception e) { 23 e.printStackTrace(); 24 } 25 try{ 26 //调用Person类中的sayChina方法 27 Method method = test.getMethod("demoTest"); 28 method.invoke(test.newInstance()); 29 }catch (Exception e) { 30 e.printStackTrace(); 31 } 32 } 33 }
- 获取类中的成员变量(field)
[获取属性<根据属性名>](使用时一般用是带declared的,即蓝色字体,因为属性一般都是私有的) Field getField(String name) 返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段。 Field[] getFields() 返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段。 Field getDeclaredField(String name) 返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。 Field[] getDeclaredFields() 返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段。
•有declared的方法是支持私有,但是不支持继承,无declared的方法支持继承,不支持私有,且只能取出public的东西。
•因此取属性的时候一般来说是带declared的,因为属性一般都是私有的,取方法时一般是不带declared的,取构造时一般也是不带declared的.
具体使用例子:利用反射获取字段field
1 package Reflect; 2 import java.lang.reflect.Constructor; 3 class Demo() { 4 String name; 5 Demo() {} 6 Demo(String name) { 7 this.name = name; 8 } 9 @Override 10 String toString(){ 11 return "["+this.name+"]"; 12 } 13 } 14 public class test() { 15 public static void main(String[] args) { 16 Class<?> test = null; 17 try { 18 test = Class.forName(Reflect.Demo); 19 } catch (Exception e) { 20 e.printStackTrace(); 21 } 22 // 取得本类的全部属性 23 Field[] field = test.getDeclaredFields(); 24 for (int i = 0; i < field.length; i++) { 25 // 权限修饰符 26 int mo = field[i].getModifiers(); 27 String priv = Modifier.toString(mo); 28 // 属性类型 29 Class<?> type = field[i].getType(); 30 System.out.println(priv + " " + type.getName() + " " 31 + field[i].getName() + ";"); 32 } 33 } 34 }
写个博客写了大半个月了,现在才想起把这篇写完发布出去,我的第一篇博客就这样诞生了。。。。。。。。。。。。。。。。。。