一个类有多个组成部分,例如:成员变量,方法,构造方法等。反射就是加载类,并解剖出类的各个组成部分。
编程时什么情况下才需要加载类,并解剖出累的各个组成部分呢?
反射是用来做框架的。
从配置文件中解读类的方法等。
Java中有一个Class类用于代表某一个类的字节码。
Class类既然代表某个类的字节码,它当然就要提供加载某个类自己吗的方法:forName(). forName方法用于加载某个类的字节码到内存中,并使用class对象进行封装。
另外两种得到class对象的方式
类名.class
对象.getClass()
下面看三种类的加载方法
1 package cn.itcast.reflect; 2 3 public class Demo1 { 4 5 public static void main(String[] args) throws Exception { 6 // TODO Auto-generated method stub 7 //加载类的字节码1,常用 8 Class clazz1 = Class.forName("cn.itcast.reflect.Person"); 9 10 //加载类的字节码2 11 Class clazz2 = Person.class; 12 13 //加载类的字节码3 14 Class clazz3 = new Person().getClass(); 15 16 } 17 18 }
Class对象提供了如下常用方法:
1 public Constructor getConstructor(Class<?>... parameterTypes) 2 public Method getMethod(String name,Class<?>... parameterTypes) 3 public Field getField(String name) 4 5 public Constructor getDeclaredConstructor(Class<?>... parameterTypes) 6 public Method getDeclaredMethod(String name,Class<?>... parameterTypes) 7 public Field getDeclaredField(String name)
这些方法分别用于从类中解剖出构造函数、方法和成员变量(属性)。解剖出的成员分别使用Constructor,Method,Field对象表示。
思考:假设你是一个框架的设计者,出这些成员后你会干什么?
先看反射类的构造方法。
1 //Demo1.java 2 package cn.itcast.reflect; 3 import java.lang.reflect.Constructor; 4 import org.junit.Test; 5 public class Demo1 { 6 7 public static void main(String[] args) throws Exception { 8 // TODO Auto-generated method stub 9 //加载类的字节码1,常用 10 Class clazz = Class.forName("cn.itcast.reflect.Person"); 11 Constructor c = clazz.getConstructor(null); 12 13 Object obj = c.newInstance(null); 14 15 System.out.println(obj); 16 17 18 } 19 20 //反射无参的构造函数 21 @Test 22 public void test1() throws Exception{ 23 Class clazz = Class.forName("cn.itcast.reflect.Person"); 24 Constructor c = clazz.getConstructor(null); 25 26 Object obj = c.newInstance(null); 27 28 System.out.println(obj); 29 } 30 31 32 //反射有参的构造函数 33 @Test 34 public void test2() throws Exception{ 35 Class clazz = Class.forName("cn.itcast.reflect.Person"); 36 Constructor c = clazz.getConstructor(String.class); 37 38 Person p = (Person) c.newInstance("fix"); 39 System.out.println(p); 40 } 41 42 //反射私有的,有参的构造函数 43 @Test 44 public void test3() throws Exception{ 45 Class clazz = Class.forName("cn.itcast.reflect.Person"); 46 Constructor c = clazz.getDeclaredConstructor(int.class); 47 c.setAccessible(true);//暴力反射 48 Person p = (Person) c.newInstance(1); 49 System.out.println(p); 50 } 51 }
下面看反射类的方法
1 package cn.itcast.reflect; 2 3 import java.lang.reflect.Method; 4 5 import org.junit.Test; 6 7 public class Demo2 { 8 //反射方法 9 10 //反射不带参数的方法 11 @Test 12 public void test1() throws Exception{ 13 Class clazz = Class.forName("cn.itcast.reflect.Person"); 14 15 Method method = clazz.getMethod("eat", null); 16 17 method.invoke(clazz.newInstance(), null); 18 } 19 20 //反射带参数的方法 21 @Test 22 public void test2() throws Exception{ 23 Class clazz = Class.forName("cn.itcast.reflect.Person"); 24 25 Method method = clazz.getMethod("run", String.class); 26 27 method.invoke(clazz.newInstance(), "上海"); 28 } 29 30 //反射带多个参数的方法 31 @Test 32 public void test3() throws Exception{ 33 Class clazz = Class.forName("cn.itcast.reflect.Person"); 34 35 Method method = clazz.getMethod("run", String.class,int[].class,String[].class); 36 37 method.invoke(clazz.newInstance(), "上海",new int[]{1,2,3},new String[]{"a","b","c"}); 38 } 39 40 41 //反射带返回值的方法 42 @Test 43 public void test4() throws Exception{ 44 Class clazz = Class.forName("cn.itcast.reflect.Person"); 45 46 Method method = clazz.getMethod("test", String.class); 47 48 String result = (String) method.invoke(clazz.newInstance(), "上海"); 49 System.out.println(result); 50 } 51 52 53 //反射私有方法 54 @Test 55 public void test5() throws Exception{ 56 Class clazz = Class.forName("cn.itcast.reflect.Person"); 57 58 Method method = clazz.getDeclaredMethod("test2", String.class); 59 method.setAccessible(true);//暴力反射 60 String result = (String) method.invoke(clazz.newInstance(), "上海"); 61 System.out.println(result); 62 } 63 64 65 //反射静态方法 66 @Test 67 public void test6() throws Exception{ 68 Class clazz = Class.forName("cn.itcast.reflect.Person"); 69 70 Method method = clazz.getMethod("test3", String.class); 71 String result = (String) method.invoke(null, "上海"); 72 System.out.println(result); 73 } 74 75 //反射main方法 76 //通过反射调用带数组的方法,要注意处理 77 @Test 78 public void test7() throws Exception{ 79 Class clazz = Class.forName("cn.itcast.reflect.Person"); 80 81 Method method = clazz.getMethod("main", String[].class); 82 //method.invoke(null, (Object)new String[]{"1","2"}); 83 method.invoke(null, new Object[]{new String[]{"1","2"}}); 84 } 85 }
利用Field访问属性
Field对象提供了如下方法,用于设置、获取对象属性的值:
public void set(Object obj,Object value)
public Object get(Object obj)
1 package cn.itcast.reflect; 2 3 import java.lang.reflect.Field; 4 5 import org.junit.Test; 6 7 public class Demo3 { 8 9 /** 10 * 反射类的字段 11 * @throws Exception 12 */ 13 //反射公有成员变量 14 @Test 15 public void test1() throws Exception{ 16 17 Person p = new Person(); 18 Class clazz = Class.forName("cn.itcast.reflect.Person"); 19 20 Field f = clazz.getField("name"); 21 22 f.set(p, "flx"); 23 System.out.println(p.getName()); 24 25 } 26 27 28 //反射公有成员变量 29 @Test 30 public void test2() throws Exception{ 31 32 Person p = new Person(); 33 p.setName("xxx"); 34 Class clazz = Class.forName("cn.itcast.reflect.Person"); 35 Field f = clazz.getField("name"); 36 String result = (String)f.get(p); 37 System.out.println(result); 38 39 } 40 41 //反射final成员变量 42 @Test 43 public void test3() throws Exception{ 44 45 Person p = new Person(); 46 Class clazz = Class.forName("cn.itcast.reflect.Person"); 47 Field f = clazz.getField("password"); 48 String result = (String)f.get(p); 49 System.out.println(result); 50 51 } 52 53 //反射私有成员变量 54 @Test 55 public void test4() throws Exception{ 56 Person p = new Person(); 57 Class clazz = Class.forName("cn.itcast.reflect.Person"); 58 Field f = clazz.getDeclaredField("age"); 59 f.setAccessible(true); 60 f.set(p, 123); 61 int result = (Integer)f.getInt(p); 62 System.out.println(result); 63 } 64 }
Person类如下:
1 package cn.itcast.reflect; 2 3 public class Person { 4 5 public String name;//字段或成员变量 6 private int age; 7 8 public final String password="123"; 9 10 11 public String getName() { 12 return name; 13 } 14 15 public void setName(String name) { 16 this.name = name; 17 } 18 19 public int getAge() { 20 return age; 21 } 22 23 public void setAge(int age) { 24 this.age = age; 25 } 26 27 public Person(){ 28 System.out.println("person"); 29 } 30 31 public Person(String name){ 32 System.out.println(name); 33 } 34 35 private Person(int name){ 36 System.out.println(name); 37 } 38 39 public void eat(){ 40 System.out.println("eat!!!"); 41 } 42 43 public void run(String address){ 44 System.out.println("跑到"+address); 45 } 46 47 public void run(String address,int num[],String ss[]){ 48 System.out.println("跑到"+address+"," +num); 49 } 50 51 public String test(String str){ 52 return str+"aaaaaa"; 53 } 54 55 private String test2(String str){ 56 return str+"aaaaaa"; 57 } 58 59 public static String test3(String str){ 60 return str+"aaaa"; 61 } 62 63 64 public static void main(String[] args) { 65 System.out.println(args[0]); 66 } 67 68 }
如上就是反射所有常用的一些方法。
原文:http://www.cnblogs.com/LoganChen/p/6362820.html