java反射

来源:互联网 发布:时间煮雨抄袭 知乎 编辑:程序博客网 时间:2024/05/22 15:13

反射的作用,参考http://blog.csdn.net/ritterliu/article/details/7764849


下面介绍几个反射的用法:

1.Class的对象获取

package com.note;/* * 在java的世界里,万事万物皆是对象。两个不是:普通变量,和静态成员 *  * 一般类是java.lang.Class的对象:Class构造方法是私有的,所以不能new Class(); */public class ClassDemo {public static void main(String [] args) {Foo foo1 =new Foo(); //Class实例对象,3种表示方式;//1.第一种。实际告诉我们任何一个类都有一ig隐含的静态成员变量claasClass c1= Foo.class;//2.第二种。已知该类的对象 Class c2 =foo1.getClass();  //3.第三种:属于动态加载类型。编译时加载类就是静态,运行时加载是动态 //new都是静态加载类,全部正确且存在才能编译通过。而动态加载不需要  Class c3= null; try {c3= Class.forName("com.note.Foo");} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} //官网:c1,c2表示了Foo类的类类型  //结果均为true System.out.println(c1==c2); System.out.println(c3==c2);   //我们可以通过类 的类类型创建该类的对象实例-----》通过c1/c2/c3创建Foo的实例 //c1是什么类类型,就创建什么类的实例,需要强制转换,和抛出异常 try {Foo foo =(Foo)c1.newInstance();foo.print();} catch (InstantiationException | IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}//不能用public修饰class Foo{void print(){System.out.println("foo");}}


2.Class.forName(str)的区别

public class ClassDemo1 {public static void main(String[] args){try{//动态加载,编译能通过,运行时才加载类Class c = Class.forName("args[0]");//officeAble是一个接口,WORD和excel实现了这个接口,//所以不管c为word还是excel都能正确创建下面对象OfficeAble oa = (OfficeAble)c.newInstance();oa.print();}catch(Exception e){}}}

3.通过反射获取一个类的成员变量、方法、构造函数:

package com.note;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.lang.reflect.Parameter;//获取类的全部信息public class ClassUtil {String s1;int i1;public static void main(String[] args) {Class c0 = int.class;Class c2 = String.class;//就是void也是类 ,皆是类//Class c3 = void.class;////System.out.println(c0.getName());//System.out.println(c2.getName());////不含包名的名称//System.out.println(c2.getSimpleName());//System.out.println(c3.getName());////调用下面方法,打印类的成员函数String s="hello";ClassUtil.printClassMessage_Methods(new ClassUtil());ClassUtil.printClassMessage_Fields(new ClassUtil());ClassUtil.printClassMessage_Constructor(s);}/* * 打印类的信息,包括类的成员函数、成员变量 *   */public static void printClassMessage_Methods(Object obj){//1.首先获取类类型Class c = obj.getClass();//2.获取类的名称System.out.println("类的名称:"+c.getName());/* * Method类。方法对象 * 一个成员方法就是iyi个Method当对象 * getMethod()方法获取的是所有的public函数,包括父类继承的 * getDeclaredMethods()获取的是所有该类自己声明的方法,不问访问权限 */Method[] ms=c.getMethods();//c.getDeclaredMethods()for(int i=0;i<ms.length;i++){//得到方法的返回值类型的类类型Class returnType = ms[i].getReturnType();System.out.print(returnType.getName()+" ");//得到方法的名称System.out.print(ms[i].getName()+"(");//获取参数类型----》得到的参数列表的类型的类类型Class[] paramTypes = ms[i].getParameterTypes();for(Class class1:paramTypes){System.out.print(class1.getName()+",");}System.out.println(")");}}public static void printClassMessage_Fields(Object obj){/* * 成员变量也是对象.java.lang.reflect.Field * Field类封装了关于成员变量的操作 * getFileds()方法获取的是所有的public成员变量的信息 * getDeclaredFields()获取的是该类自己声明的成员变量的信息 */Class c = obj.getClass();Field[] fs= c.getDeclaredFields();for(Field field:fs){//得到成员变量的类类型Class fieldType = field.getType();System.out.print(fieldType.getName()+" ");//得到成员变量的名字System.out.println(field.getName());}}//获取对像的构造函数信息public  static void printClassMessage_Constructor(Object obj){Class c= obj.getClass();/* * 构造函数也是对象 * java.lang.Construtor中封装了构造函数的信息 * getConstruts()获取所有的public的构造函数 * getDeclaredConstruts的得到自己声明的构造函数 *  */Constructor[] cs = c.getDeclaredConstructors();for(Constructor constructor:cs){System.out.print(constructor.getName()+"(");//得到参数类型Class paramTypes[] = constructor.getParameterTypes();for(Class class1:paramTypes){System.out.print(class1.getName()+",");}System.out.println(")");}}}


4.方法的反射:

package com.note;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;/* * 方法的反射: *  * 1.获取方法 *  2.通过方法反射 */public class ClassInvoke {public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {//要获取print(int,int)方法A a1 = new A();//获取方法 名称和参数列表来决定c.getMethod(name,Class... parameters)Class c = a1.getClass();//此处会抛出异常,方法不存在或者try {//Method m = c.getMethod("print",int.class,int.class);也可以Method m = c.getMethod("print",new Class[]{int.class,int.class});//方法的反射操作//a1.print(10,20);方法的反射操作是用m对象来进行方法调用和a1.print调用的效果//方法有返回值返回返回值,没有返回值返回voidObject o=m.invoke(a1, new Object[]{10,20});//(a1, 10,20);System.out.println("============");A a2= new A();Class c1 =a2.getClass();Method m1 = c1.getMethod("print",String.class,String.class);m1.invoke(a2,"ss","BBB");} catch (NoSuchMethodException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (SecurityException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}class A{public void print(int a ,int b){System.out.println(a+b);}public void print(String a ,String b){System.out.println(a.toUpperCase()+","+b.toLowerCase());}}

5.反射绕过编译。都是在编译之后

package com.note;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.ArrayList;//泛型问题。ArrayList<String>为泛型public class ClassMethod {public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException{ArrayList  list1 = new ArrayList ();ArrayList<String> list2 = new ArrayList<String>();Class c1 = list1.getClass();Class c2= list2.getClass();//结果为TRUESystem.out.println(c1==c2);/* * 集合的泛型是防止错误输入的,只在编译阶段有效,即不能在list2中插入部位String类型的 *反射是的操作都是编译之后的操作 *c1=c2,表明集合的泛型都是在编译阶段有效 *我们可以通过方法的反射绕过编译 */try {Method m = c2.getMethod("add",Object.class);m.invoke(list1,20);System.out.println(list1);} catch (NoSuchMethodException | SecurityException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}




0 0