[java] java 中的反射
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;
对于任意一个对象,都能够调用它的任意一个方法和属性;
这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
一、一个简单例子获取类的包名和类名:
package com.wa.java.book.kernel.reflect; /** * Created by Administrator on 2015/2/7. */ public class Hello { public static void main(String[] args){ Baby baby = new Baby(); String pack = baby.getClass().getName();//获取完成的类名(包含包名) String simpleName = baby.getClass().getSimpleName();//获取类名 String canonical = baby.getClass().getCanonicalName(); System.out.println(pack);//com.wa.java.book.kernel.reflect.Baby System.out.println(simpleName);//Baby System.out.print(canonical);//com.wa.java.book.kernel.reflect.Baby /*看源码getName()和getSimpleName()和getCanonicalName()的区别是类是否是数组*/ String[] ary ={"JAVA","SPRING","HIBERNATE"}; System.out.println(ary.getClass().getName());//com.wa.java.book.kernel.reflect.Baby[Ljava.lang.String; System.out.println(ary.getClass().getSimpleName());//String[] System.out.println(ary.getClass().getCanonicalName());//java.lang.String[] } } class Baby{ }
另外附上以上方法的源码:
public String getName() { if (name == null) name = getName0(); return name; } // cache the name to reduce the number of calls into the VM private transient String name; private native String getName0(); public String getSimpleName() { if (isArray()) return getComponentType().getSimpleName()+"[]"; String simpleName = getSimpleBinaryName(); if (simpleName == null) { // top level class simpleName = getName(); return simpleName.substring(simpleName.lastIndexOf(".")+1); // strip the package name } public String getCanonicalName() { if (isArray()) { String canonicalName = getComponentType().getCanonicalName(); if (canonicalName != null) return canonicalName + "[]"; else return null; } if (isLocalOrAnonymousClass()) return null; Class<?> enclosingClass = getEnclosingClass(); if (enclosingClass == null) { // top level class return getName(); } else { String enclosingName = enclosingClass.getCanonicalName(); if (enclosingName == null) return null; return enclosingName + "." + getSimpleName(); } }
二、实例化class:
/*实例化class对象*/ @Test public void test1(){ Date date = new Date(); Class dateClass = date.getClass(); System.out.println(dateClass.getName());//java.util.Date System.out.println(new Integer(1).getClass().getName());//java.lang.Integer System.out.println(Calendar.class.getName());//java.util.Calendar //获取父类 System.out.println(Integer.class.getSuperclass().getName());//java.lang.Number /* 类名写错出现java.lang.ClassNotFoundException: java.utl.Date * 通过类加载器加载类的完整包名 * */ String str = "java.util.Date"; Class<Date> clazz= null; try { clazz = (Class<Date>) Class.forName(str); System.out.println(clazz.getCanonicalName()); } catch (ClassNotFoundException e) { e.printStackTrace(); } }
运行结果:
java.util.Date
java.lang.Integer
java.util.Calendar
java.lang.Number
java.util.Date
三、通过反射实例化对象:
package com.wa.java.book.kernel.reflect; import java.util.Date; import java.util.List; /** * Created by Administrator on 2015/2/7. */ public class Father { private String name ; private Date birthday; private String address; private Integer age ; private Boolean isLoveYou; public Father(){} public Father(String name){ this.name=name; } //省略getter和setter方法 @Override public String toString() { return "Father{" + "name='" + name + '\'' + ", birthday=" + birthday + ", address='" + address + '\'' + ", age=" + age + ", isLoveYou=" + isLoveYou + '}'; } }
/*通过反射实例化对象*/ @Test public void test2(){ String str ="com.wa.java.book.kernel.reflect.Father"; try { Class<?> clazz = Class.forName(str); //通过默认构造器实例化对象 /** * 如果没有默认构造器抛出异常: * java.lang.InstantiationException: com.wa.java.book.kernel.reflect.Father */ Father f= (Father) clazz.newInstance(); f.setName("老爸"); f.setAddress("家乡"); f.setAge(60); f.setBirthday(new SimpleDateFormat("yyyy-MM-dd").parse("1960-01-10")); f.setIsLoveYou(true); System.out.println(f); //Father{name='老爸', birthday=Sun Jan 10 00:00:00 CST 1960, address='家乡', age=60, isLoveYou=true} } catch (Exception e) { e.printStackTrace(); } }
实例化的类必须包含默认构造器,否则抛出以下异常:
java.lang.InstantiationException: com.wa.java.book.kernel.reflect.Father at java.lang.Class.newInstance0(Class.java:340) at java.lang.Class.newInstance(Class.java:308) at com.wa.java.book.kernel.reflect.TestReflect.test2(TestReflect.java:56) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222) at org.junit.runners.ParentRunner.run(ParentRunner.java:300) at org.junit.runner.JUnitCore.run(JUnitCore.java:157) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74) at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
四、获取构造器,属性,方法
/*获取构造器,属性和方法*/ @Test public void test3(){ Constructor<?>[] cons= Father.class.getDeclaredConstructors(); for(int i=0;i<cons.length;i++){ /* 获取所有的构造器 public com.wa.java.book.kernel.reflect.Father(java.lang.String) public com.wa.java.book.kernel.reflect.Father()*/ System.out.println(cons[i]); } /** * 获取类的所有属性 * private java.util.Date com.wa.java.book.kernel.reflect.Father.birthday private java.lang.String com.wa.java.book.kernel.reflect.Father.address private java.lang.Integer com.wa.java.book.kernel.reflect.Father.age private java.lang.Boolean com.wa.java.book.kernel.reflect.Father.isLoveYou */ Field[] fields = Father.class.getDeclaredFields(); Method[] methods=Father.class.getDeclaredMethods(); for(int i=0;i<fields.length;i++){ System.out.println(fields[i]); } /*只获取l类的属性名*/ String name = fields[0].getName(); System.out.println(name); /*获取所有的方法 * public void com.wa.java.book.kernel.reflect.Father.setAge(java.lang.Integer) public void com.wa.java.book.kernel.reflect.Father.setBirthday(java.util.Date) public void com.wa.java.book.kernel.reflect.Father.setIsLoveYou(java.lang.Boolean) public java.util.Date com.wa.java.book.kernel.reflect.Father.getBirthday() public java.lang.Integer com.wa.java.book.kernel.reflect.Father.getAge() public java.lang.Boolean com.wa.java.book.kernel.reflect.Father.getIsLoveYou() public java.lang.String com.wa.java.book.kernel.reflect.Father.getAddress() public java.lang.String com.wa.java.book.kernel.reflect.Father.toString() public java.lang.String com.wa.java.book.kernel.reflect.Father.getName() public void com.wa.java.book.kernel.reflect.Father.setName(java.lang.String) public void com.wa.java.book.kernel.reflect.Father.setAddress(java.lang.String) * */ for (int j=0;j<methods.length;j++){ System.out.println(methods[j]); } }
五、通过反射为对象的某个属性赋值:
/*通过构造器实例化对象并赋值*/ @Test public void test4() throws Exception{ Field[] fields =Father.class.getDeclaredFields(); Father father = new Father(); Object[] values = {"团聚了..",new SimpleDateFormat("yyyy-MM-dd").parse("1943-12-43"), "老家",54,true}; String[] clazz ={"String","Date","String","Integer","Boolean"}; for(int i=0;i<fields.length;i++){ //获取指定的set方法 String setMethods ="set"+Character.toUpperCase(fields[i].getName().charAt(0))+fields[i].getName().substring(1); //指定方法名和参数类型 Method method = Father.class.getDeclaredMethod(setMethods,fields[i].getType()); //为指定的方法赋值 method.invoke(father,values[i]); } //Father{name='团聚了..', birthday=Wed Jan 12 00:00:00 CST 1944, address='老家', age=54, isLoveYou=true} System.out.println(father); }
参考资料:
http://www.cnblogs.com/rollenholt/archive/2011/09/02/2163758.html
 
                    
                
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号