zoukankan      html  css  js  c++  java
  • 关于反射

    一、Class类

    • 在面对对象编程中,万事万物皆对象,但是类本身又是谁的对象呢? 他是java.lang.Class的对象
    • 获取类类型的3种方法
    1. 通过对象类的对象获取
    Foo foo = new Foo();
    Class class1 = foo.getClass();
    
    1. 通过类名获取
    Class class2 = Foo.class;
    
    1. 还是通过类名获取,但是要try catch, 并且要转换类型
    try {
    	Class class3 = (Class) Class.forName("Foo");
    } catch (ClassNotFoundException e) {
    	// TODO Auto-generated catch block
    	e.printStackTrace();
    }
    

    二、获取类的方法信息

    • 一个成员方法就是Method类的对象
    • getMethods()是获得该类的所有public方法,包括从父类继承来的方法
    Method[] methods1 = class1.getMethods();
    
    • getDeclaredMethods()是获取当前类自己声明的成员方法,不包含父类继承来的,但是不问访问权限
    Method[] methods2 = class1.getDeclaredMethods();
    
    • 得到返回值类型,先得到返回值类型的类类型,再获得名字
    Class returnType = methods1[i].getReturnType();
    String returnTypeName = returnType.getName();
    
    
    • 得到方法名
    for (int i = 0; i < methods1.length; i++) {
    	System.out.println(methods1[i].getName());
    }
    
    • 得到参数类型,因为参数可能有多个,所以先得到参数列表,再遍历它得到参数类型的名字
    Class[] paramTypes = methods1[i].getParameterTypes();
    	for (Class paramType : paramTypes) {
    		String paramTypeName = paramType.getName();
    }
    

    三、获取成员变量的信息

    • 成员变量是java.lang.reflect.Field类的对象
    • getFields()获得的是所有public的成员变量
    Field[] fields1 = class1.getFields();
    
    • getDeclaredFields()获得的是自己声明的所有的成员变量
    Field[] fields2 = class1.getDeclaredFields();
    
    • 获得成员变量类型的名称
    for (Field field : fields2) {
    	Class fieldType = field.getType();
    	String fieldTypeName = fieldType.getName();
    }
    
    • 获得成员变量名称
    String fieldName = field.getName();
    

    四、获取构造函数的信息

    • 构造函数是java.lang.reflect.Constructor的对象
    • 获得构造函数,方法基本同上
    Constructor[] constructors1 = class1.getConstructors();
    Constructor[] constructors2 = class1.getDeclaredConstructors();
    
    • 获得构造参数类型
    for (Constructor constructor : constructors2) {
    	Class[] paramTypes = constructor.getParameterTypes();
    	for (Class paramType : paramTypes) {
    		String paramTypeName = paramType.getName();
    	}
    }
    
    • 获得构造方法名称
    String csName = constructor.getName();
    

    五、 反射调用方法

    public 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());
    	}
    }
    
    • 获取方法对象,先获得类类型,再操作
    A a1 = new A();
    Class clazz = a1.getClass();
    // 这里第一个参数表示方法名,后面的是参数的类类型,如果没参数,就不传
    // 要唯一确定一个方法,就得确定他的方法名和参数类型
    Method m = clazz.getMethod("print", int.class, int.class);
    
    • 反射调用方法
    // 这里是方法对象调用invoke方法,第一个参数是对象,后面的是参数,没参数就不写
    //普通调用方法为:a1.print(10,20);
    m.invoke(a1, 10, 20);
    

    六、通过反射操作绕过编译,以集合泛型为例

    public class MethodDemo1 {
    	public static void main(String[] args) {
    		ArrayList list1 = new ArrayList();
    		ArrayList<String> list2 = new ArrayList<String>();
    		Class c1 = list1.getClass();
    		Class c2 = list2.getClass();
    		/**
    		 * 反射的操作都是在编译之后进行的
    		 * c1 == c2 返回ture 说明编译之后集合的泛型是去泛型话的
    		 * java种集合的泛型,是防止错误输入的,只再编译阶段有效,绕过编译就无效了
    		 */
    		// list2.add(29); 错误
    		System.out.println(c1 == c2); // true
    		
    		/**
    		 * 通过方法的反射操作来绕过编译
    		 * c1 == c2 所有下面用c1还是c2都一样
    		 */
    		try {
    			Method m = c2.getMethod("add", Object.class);
    			// 绕过编译操作就绕过了泛型
    			m.invoke(list2, 100);
    			System.out.println(list2);
    		} catch (Exception e) {
    			e.printStackTrace();
    		} 
    		
    	}
    }
  • 相关阅读:
    从零自学Hadoop(15):Hive表操作
    从零自学Hadoop(14):Hive介绍及安装
    从零自学Hadoop(13):Hadoop命令下
    从零自学Hadoop(12):Hadoop命令中
    angularjs不同页面间controller传参方式,使用service封装sessionStorage
    angularjs简单实现$http.post(CORS)跨域及$http.post传参方式模拟jQuery.post
    angularjs中的绑定策略“@”,“=”,“&”实例
    angularjs中ng-repeat-start与ng-repeat-end用法实例
    关于JavaScript对象的键和值
    angularjs中ng-attr的用法
  • 原文地址:https://www.cnblogs.com/xgzzzy16/p/9808965.html
Copyright © 2011-2022 走看看