Java之反射机制
java反射机制指的是在java运行过程中,对于任意的类都可以知道他的所有属性以及方法,对于任意一个对象都可以任意的调用他的属性和方法,这种动态获取对象信息和动态调用对象方法的功能称为java反射机制,但是反射使用不当会造成很高的成本。
反射获取类名称:
上下代码:
1 package com.learn.reflect; 2 /** 3 * 通过反射获取类名称 4 * @author Administrator 5 * 6 */ 7 public class Test1 { 8 @SuppressWarnings("unchecked") 9 public static void main(String[] args) { 10 // 获取类名称方法一 11 Class<Test1> c1 = Test1.class; 12 System.out.println(c1.getName()); 13 14 // 获取类名称方法二 15 Test1 t1=new Test1(); 16 Class<Test1> c2 = (Class<Test1>) t1.getClass(); 17 System.out.println(c2.getName()); 18 19 // 获取类名称方法三 20 try { 21 Class<Test1> c3 = (Class<Test1>) Class.forName("com.learn.reflect.Test1"); 22 System.out.println(c3.getName()); 23 24 } catch (ClassNotFoundException e) { 25 // TODO Auto-generated catch block 26 e.printStackTrace(); 27 } 28 // 以上的 c1,c2,c3是完全一样的,他们都有一个统一的名称:叫做Test1类的类类型。 29 } 30 }
运行结果:
com.learn.reflect.Test1
com.learn.reflect.Test1
com.learn.reflect.Test1
反射的用处---获取成员方法
上下代码:
1 package com.learn.reflect; 2 3 import java.lang.reflect.Method; 4 5 /** 6 * 反射的用处之获取成员方法 7 * @author Administrator 8 * 9 */ 10 public class Person1 { 11 private String name="eagle"; 12 private String msg; 13 14 public Person1(String name, String msg) { 15 this.setName(name); 16 this.setMsg(msg); 17 } 18 19 public Person1() { 20 super(); 21 // TODO Auto-generated constructor stub 22 } 23 24 public String getName() { 25 return name; 26 } 27 28 public void setName(String name) { 29 this.name = name; 30 } 31 32 public String getMsg() { 33 return msg; 34 } 35 36 public void setMsg(String msg) { 37 this.msg = msg; 38 } 39 40 public void say(String name,String msg){ 41 System.out.println(name+"的记录是"+msg); 42 } 43 44 public static void main(String[] args) { 45 46 try { 47 // 首先获取类类型 48 @SuppressWarnings("unchecked") 49 Class<Person1> c1=(Class<Person1>) Class.forName("com.learn.reflect.Person1"); 50 51 try { 52 // 通过newInstance()方法生成一个实例 53 Object o1=c1.newInstance(); 54 55 // 获取该类的say方法 56 Method m1=c1.getMethod("say",String.class,String.class); 57 58 // 通过invoke方法调用该方法 59 m1.invoke(o1,"zhangb","准备午休了"); 60 61 // 得到该类的所有方法,但是不包括父类的方法 62 Method[] methods=c1.getDeclaredMethods(); 63 System.out.println("getDeclaredMethods()方法返回值遍历:"); 64 for(Method m:methods){ 65 System.out.println(m.getName()); 66 } 67 System.out.println("------------------"); 68 69 // 获得该类的所有public方法,包括父类的 70 Method[] methodsu=c1.getMethods(); 71 System.out.println("getMethods()方法返回值遍历:"); 72 for(Method d:methodsu){ 73 System.out.println(d.getName()); 74 } 75 76 } catch (Exception e) { 77 // TODO Auto-generated catch block 78 e.printStackTrace(); 79 } 80 81 } catch (ClassNotFoundException e) { 82 // TODO Auto-generated catch block 83 e.printStackTrace(); 84 } 85 } 86 87 }
运行结果:
zhangb的记录是准备午休了
getDeclaredMethods()方法返回值遍历:
main
getName
setName
setMsg
getMsg
say
------------------
getMethods()方法返回值遍历:
main
getName
setName
setMsg
getMsg
say
wait
wait
wait
equals
toString
hashCode
getClass
notify
notifyAll
反射的用处---获取成员变量
上下代码:
1 package com.learn.reflect; 2 3 import java.lang.reflect.Field; 4 5 /** 6 * 反射的用处之获取成员变量 7 * @author Administrator 8 * 9 */ 10 public class Person2 { 11 private String name="eagle"; 12 private String msg; 13 14 public Person2(String name, String msg) { 15 this.setName(name); 16 this.setMsg(msg); 17 } 18 19 public Person2() { 20 super(); 21 // TODO Auto-generated constructor stub 22 } 23 24 public String getName() { 25 return name; 26 } 27 28 public void setName(String name) { 29 this.name = name; 30 } 31 32 public String getMsg() { 33 return msg; 34 } 35 36 public void setMsg(String msg) { 37 this.msg = msg; 38 } 39 40 public void say(String name,String msg){ 41 System.out.println(name+"的记录是"+msg); 42 } 43 44 public static void main(String[] args) { 45 46 try { 47 @SuppressWarnings("unchecked") 48 Class<Person2> c=(Class<Person2>) Class.forName("com.learn.reflect.Person2"); 49 try { 50 Field field = c.getDeclaredField("name"); 51 Object o1 = c.newInstance(); 52 /** 53 * 由于Person2类中的name变量是private修饰的, 54 * 所以需要手动开启允许访问,是public修饰的就不需要设置了 55 */ 56 boolean access = field.isAccessible(); 57 if(!access){ 58 field.setAccessible(true); 59 } 60 61 Object names=field.get(o1); 62 System.out.println(names); 63 64 // 通过方法getDeclaredFieds()方法来获取所有的成员变量,返回是是一个Field[]数组 65 Field[] fields = c.getDeclaredFields() ; 66 for(Field f :fields){ 67 System.out.println("成员变量名:"+f.getName()); 68 } 69 70 } catch (Exception e) { 71 // TODO Auto-generated catch block 72 e.printStackTrace(); 73 } 74 } catch (ClassNotFoundException e) { 75 // TODO Auto-generated catch block 76 e.printStackTrace(); 77 } 78 //Field field1 79 } 80 81 }
运行结果:
eagle
成员变量名:name
成员变量名:msg
反射的用处---获取构造方法
上下代码:
1 package com.learn.reflect; 2 3 import java.lang.reflect.Constructor; 4 /** 5 * 反射的用处之获取构造方法 6 * @author Administrator 7 * 8 */ 9 public class Person3 { 10 private String name="eagle"; 11 private String msg; 12 13 public Person3(String name, String msg) { 14 this.setName(name); 15 this.setMsg(msg); 16 System.out.println(name+"的描述是"+msg); 17 } 18 19 public Person3() { 20 super(); 21 // TODO Auto-generated constructor stub 22 System.out.println("调用了此构造方法"); 23 } 24 25 public String getName() { 26 return name; 27 } 28 29 public void setName(String name) { 30 this.name = name; 31 } 32 33 public String getMsg() { 34 return msg; 35 } 36 37 public void setMsg(String msg) { 38 this.msg = msg; 39 } 40 41 public void say(String name,String msg){ 42 System.out.println(name+"的记录是"+msg); 43 } 44 45 public static void main(String[] args) { 46 try { 47 @SuppressWarnings("unchecked") 48 Class<Person3> c=(Class<Person3>) Class.forName("com.learn.reflect.Person3"); 49 try { 50 Constructor<Person3> c1=(Constructor<Person3>)c.getDeclaredConstructor(String.class,String.class); 51 c1.setAccessible(true); 52 c1.newInstance("wang123","吃饭"); 53 54 } catch (Exception e) { 55 // TODO Auto-generated catch block 56 e.printStackTrace(); 57 } 58 } catch (ClassNotFoundException e) { 59 // TODO Auto-generated catch block 60 e.printStackTrace(); 61 } 62 63 } 64 65 }
运行结果:
wang123的描述是吃饭
泛型只是在编译期间起作用,在经过编译进入运行期间是不起作用的。就算是不是泛型要求的类型也是可以插入的。
反射知识点: