类加载方法:
所有类的对象都是Class的实例。
类加载时会先加载static静态部分,并且从父类的static到子类static依次加载。
final语句块会作为宏定义被加载到特殊位置。
Person类:
1 public class Person { 2 private String name; 3 private int age; 4 5 public Person() { 6 // TODO Auto-generated constructor stub 7 } 8 9 public Person(String name, int age) { 10 this.name = name; 11 this.age = age; 12 } 13 14 public String getName() { 15 return name; 16 } 17 18 public void setName(String name) { 19 this.name = name; 20 } 21 22 public int getAge() { 23 return age; 24 } 25 26 public void setAge(int age) { 27 this.age = age; 28 } 29 30 public void foo(String s) { 31 System.out.println("superman is batman's!!" + " s"); 32 } 33 34 public void foo(String s, int i) { 35 System.out.println("superman is batman's!!" + " s" + i); 36 } 37 38 }
Demo主函数类:
1 public class ReflectionDemo { 2 3 public static void main(String[] args) { 4 // TODO Auto-generated method stub 5 Person person = new Person(); 6 Class demo1=null; 7 Class demo2=null; 8 Class demo3=null; 9 try { 10 // 通过包名加载类 11 demo1 = Class.forName("reflection.Person"); 12 } catch (ClassNotFoundException e) { 13 // TODO Auto-generated catch block 14 e.printStackTrace(); 15 } 16 // 使用类实例反推类 17 demo2 = person.getClass(); 18 // 使用 “类名.class”加载类 19 demo3 = Person.class; 20 System.out.println(demo1.getName()); 21 System.out.println(demo2.getName()); 22 System.out.println(demo3.getName()); 23 } 24 25 }
输出结果:
reflection.Person
reflection.Person
reflection.Person
使用Class实例化其他类对象:
1 public static void main(String[] args) throws Exception { 2 // 异常未处理 3 Class c = null; 4 c = Class.forName("reflection.Person"); 5 Person person = (Person) c.newInstance(); 6 person.setName("naruto"); 7 System.out.println("Person.name :" + person.getName()); 8 }
输出:
Person.name :naruto
这其实是调用Person#Person()默认构造方法,当Person()声明为private私有时,Class.forName()方法会报错。因此在一个类中最好有一个无参构造方法。
通过构造器操作类的有参函数及无参函数:
1 public static void main(String[] args) { 2 Class c = null; 3 Person p1; 4 Constructor[] cons; // 声明一个构造器数组 5 try { 6 // 加载Person类 7 c = Class.forName("reflection.Person"); 8 // 通过Class实例化其他对象 9 p1 = (Person) c.newInstance(); 10 p1.setName("naruto"); 11 System.out.println("p1.name :" + p1.getName()); 12 // 获取全部构造函数 13 cons = c.getConstructors(); 14 // 构造Person实例,cons数组中的索引值与Person中构造函数声明时的位置有关,如果位置不对应会报错 15 Person p2 = (Person) cons[1].newInstance("tom", 21); 16 System.out.println("p2.name :" + p2.getName() + "p2.age :" 17 + p2.getAge()); 18 } catch (Exception e) { 19 e.printStackTrace(); 20 } 21 22 }
输出:
p1.name :naruto
p2.name :tomp2.age :21
获取类实现的所有接口:
1 public static void main(String[] args) { 2 try { 3 Class<?> c1 = Class.forName("reflection.Person"); 4 Class<?>[] inters = c1.getInterfaces(); 5 for (int i = 0; i < inters.length; i++) { 6 System.out.println(inters[i].getName()); 7 } 8 } catch (Exception e) { 9 // TODO Auto-generated catch block 10 e.printStackTrace(); 11 } 12 13 }
输出:
reflection.InterfaceDemo
通过反射获取类信息:
1 public static void main(String[] args) { 2 try { 3 Class<?> class1 = Class.forName("reflection.Person"); 4 // 获取Person类的父类 5 Class<?> class2 = class1.getSuperclass(); 6 // System.out.println("父类:" + class2.getName()); 7 // 获取全部构造方法 8 Constructor[] cons = class1.getConstructors(); 9 for (Constructor constructor : cons) { 10 System.out.println("构造方法名:" + constructor.getName()); 11 // 获取构造方法的访问权限 12 int no = constructor.getModifiers(); 13 System.out.println("访问权限:" + Modifier.toString(no)); 14 // 每个构造方法的参数 15 Class p[] = constructor.getParameterTypes(); 16 for (int i = 0; i < p.length; i++) { 17 System.out.print(p[i].getName() + " "); 18 } 19 System.out.println(); 20 } 21 // 获取类全部方法信息 22 Method[] methods = class1.getMethods(); 23 for (int i = 0; i < methods.length; i++) { 24 // 获取该方法返回值类型 25 Class<?> retuTypes = methods[i].getReturnType(); 26 // 获取该方法参数类型 27 Class<?>[] paraTypes = methods[i].getParameterTypes(); 28 // 获取该方法抛出的异常 29 Class<?>[] exce = methods[i].getExceptionTypes(); 30 System.out.println(); 31 } 32 // 获取该类全部非私有的属性信息 33 Field[] fields = class1.getFields(); 34 // 获取该类全部属性信息,包括私有属性 35 Field[] fields1 = class1.getDeclaredFields(); 36 } catch (Exception e) { 37 // TODO Auto-generated catch block 38 e.printStackTrace(); 39 } 40 41 }
调用其他类的方法:
1 public static void main(String[] args) { 2 try { 3 Class<?> demo = Class.forName("reflection.Person"); 4 Method method = demo.getMethod("foo",String.class,int.class); 5 method.invoke(demo.newInstance(),"haha",32); 6 } catch (Exception e) { 7 // TODO Auto-generated catch block 8 e.printStackTrace(); 9 } 10 11 }
如果方法访问修饰符为private需要修改访问权限
1 public static void main(String[] args) { 2 try { 3 Class<?> demo = Class.forName("reflection.Person"); 4 //getDeclaredMethod()可以访问所有方法,不管方法的访问修饰符是什么 5 Method method=demo.getDeclaredMethod("fun"); 6 //如果方法访问修饰符为private需要修改访问权限 7 method.setAccessible(true); 8 method.invoke(demo.newInstance()); 9 } catch (Exception e) { 10 // TODO Auto-generated catch block 11 e.printStackTrace(); 12 } 13 14 }
访问用private修饰的字段也需要修改访问权限:
1 public static void main(String[] args) { 2 try { 3 Class<?> demo = Class.forName("reflection.Person"); 4 Field field=demo.getDeclaredField("name"); 5 field.setAccessible(true); 6 Person p=(Person) demo.newInstance(); 7 field.set(p, "pepelu"); 8 System.out.println(field.get(p)); 9 } catch (Exception e) { 10 // TODO Auto-generated catch block 11 e.printStackTrace(); 12 } 13 }