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

    Class 类:类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。一个Class对象表示表示的是一种类型,但这个类型未必是一种类,比如int.class是一个Class对象,而int不是类。

    Field 类:提供有关类或接口的属性的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)属性或实例属性,简单的理解可以把它看成一个封装反射类的属性的类。

    Constructor 类:提供关于类的单个构造方法的信息以及对它的访问权限。这个类和 Field 类不同,Field 类封装了反射类的属性,而 Constructor 类则封装了反射类的构造方法。

    Method 类:提供关于类或接口上单独某个方法的信息。所反映的方法可能是类方法或实例方法。这个类不难理解,它是用来封装反射类方法的一个类。

    如何获得字节码?
    Class cls = Xxx.class;
    Class cls = xx.getClass();
    Class.forname(类名);  // 返回字节码:若内存中有加载该类,则他找到该类的字节码并返回,若无,则找到该类的路径,加载后返回。

    要区别一个概念,这里获得的是类的字节码,与具体的对象无关。

    如何获得实例?
    Test t1=new Test();
    Object t2 =t1.getClass().newInstance();
    Object t3 =Class.forName("Test").newInstance();
    newInstance方法调用没有参数的构造器,如果带参数就需要使用Constructor类。

    Class类中的getFields、getMethods、getConstructors将返回类支持的public域、方法、和构造器数组,包括超类的公有成员。

    Class类中的getDeclareFields、getDeclareMethods、getDeclareConstructors将返回类中声明的全部域、方法、和构造器数组,其中包括私有的和保护的,但不包括超类的成员。

    Field、Method、Constructor都有一个getModifiers方法,可以使用其枚举值判断修饰符,或者Modifier.toString方法等解析。

    AccessibleObjecte是Field、Method、Constructor公共超类,调用setAccessible(true)方法后可以对实例的保护和私有成员设置新值。这个特性是为调试、持久存储相似机制提供的。

    使用Method类型作为函数参数可以实现c#中的委托,使用接口回调执行快些。
    import java.lang.reflect.AccessibleObject;
    import java.lang.reflect.Array;
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import java.lang.reflect.Modifier;
    
    import javax.accessibility.AccessibleRole;
    
    public class ReflectTest {
    
    	public static int a = 47;
    
    	private String str = "hello";
    
    	public ReflectTest() {
    	}
    
    	public ReflectTest(String str) {
    		this.str = str;
    	}
    
    	public String getStr(String str) {
    		return this.str + "," + str;
    	}
    
    	public String getStr() {
    		return str;
    	}
    
    	public static void MethodTest(Object object) {
    
    	};
    
    	public static void main(String[] args) throws Exception {
    
    		ReflectTest instance = new ReflectTest();
    		// 获取字节码
    		Class clazz = Class.forName("ReflectTest");
    
    	    // 获取字段信息
    		Field fieldA = clazz.getField("a");
    		fieldA.getName();
    		fieldA.getType();
    		Modifier.toString(fieldA.getModifiers());
    		fieldA.getInt(instance);
    		fieldA.get(instance);
    
    		//设置私有成员
    		Field fieldStr = clazz.getDeclaredField("str");
    		fieldStr.setAccessible(true);
    		// AccessibleObject.setAccessible(array, flag)
    		fieldStr.set(instance, "abc");
    
    		// 根据字节码构造实例
    		Constructor<ReflectTest> constructor = clazz.getConstructor();
    		instance = constructor.newInstance();// 无参
    		instance = (ReflectTest) clazz.newInstance(); // 无参
    		constructor = clazz.getConstructor(String.class);// 有参
    		instance = constructor.newInstance("world");
    
    		// 调用指针函数
    		Method method1 = instance.getClass().getMethod("getStr");
    		method1.invoke(instance);//无参
    		method1 = instance.getClass().getMethod("getStr", String.class);
    		method1.invoke(instance, "String str");// 有参
    		method1 = instance.getClass().getMethod("MethodTest", Object.class);
    		method1.invoke(null, "object");// 静态
    
    	}
    
    	// 使用反射编写通用的数组代码
    	static Object GoodArryGrow(Object src) {
    		Class cl = src.getClass();
    		if (!cl.isArray())
    			return null;
    		Class componentType = cl.getComponentType();
    		int length = Array.getLength(src);
    		int newLength = length * 11 / 10 + 10;
    
    		Object dest = Array.newInstance(componentType, newLength);
    		System.arraycopy(src, 0, dest, 0, newLength);
    		return dest;
    	}
    }
    
  • 相关阅读:
    数组排序 -- 冒泡排序
    数组自带的函数(方法)
    京东官网轮播图的实现
    鼠标单击元素输出对应元素的索引号
    JavaScript中获取HTML元素的方式
    JavaScript数组的2种定义方式
    this关键字
    JavaScript中对象的3种定义方式
    Hadoop完整搭建过程(三):完全分布模式(虚拟机)
    Hadoop完整搭建过程(二):伪分布模式
  • 原文地址:https://www.cnblogs.com/jinc/p/2089375.html
Copyright © 2011-2022 走看看