当前位置: 首页 > 工具软件 > ASMSupport > 使用案例 >

AsmSupport缺陷还真多

邰伟彦
2023-12-01

AsmSupport缺陷还真多,本来打算用于TalkingBird的直接本地代码执行引擎的开发,没想到AsmSupport存在动态绑定的缺陷,通过修正AsmSupport底层实现解决动态绑定,结果又出现栈溢出。甚是让人奔溃。

怎么解决动态绑定的问题呢?

首先我们要搞清楚如下代码是否是合理的:


import java.io.Serializable;

import org.junit.Test;

public class Test1 {
	@Test
	public void test1(){
		byte b = 1;
		fun(b);
	}
	public void fun(byte i){//①
		System.out.println("byte");
	}
	public void fun(short i){//②
		System.out.println("short");
	}
	public void fun(int i){//③
		System.out.println("int");
	}
	public void fun(long i){//④
		System.out.println("long");
	}
	public void fun(float i){//⑤
		System.out.println("float");
	}
	public void fun(double i){//⑥
		System.out.println("double");
	}
	public void fun(Byte i){//⑦
		System.out.println("Byte");
	}
	public void fun(Serializable i){//⑧
		System.out.println("Serializable");
	}
	public void fun(Object i){//⑨
		System.out.println("Object");
	}
}


相信大家都知道运行结果输出byte.

那么这样呢,注掉①的函数重载。

结果是short,结果还是可以理解,Java自动对原生类型进行拓展。


那么注掉从①——⑥,结果都是能够理解的。但是注掉⑦后,结果就费解了,结果居然是Serializable,却不是我们熟知的Object。原来是因为包装类实现了序列化接口,直到最后才是Object。

其他基本数据类型依次逻辑递推,注意short之后是int,不是char。

char的拓展类型是int,特别注意,short不能拓展到char。


对于拆箱呢。

则依据如下顺序,包装类->Serializable->Object->对应原生数据类型。

要解决AsmSupport的缺陷,必须重写cn.wensiqun.asmsupport.utils.AClassUtils#GetDirectSuperType()方法在获取父类的逻辑。

/**
	 * 获取一个给定的类的超类<br>
	 * boolean:boolean->Boolean->Serializable->Object<br>
	 * byte:byte->short->int->long->float->double->Byte->Serializable->Object<br>
	 * short:short->int->long->float->double->Short->Serializable->Object<br>
	 * char:char->int->long->float->double->Character->Serializable->Object<br>
	 * int:int->long->float->double->Integer->Serializable->Object<br>
	 * long:long->float->double->Long->Serializable->Object<br>
	 * float:float->double->Float->Serializable->Object<br>
	 * double:double->Double->Serializable->Object<br>
	 * Serializable:Serializable->Object<br>
	 * 拆箱发生在最后<br>
	 * Boolean:Boolean->Serializable->Object->boolean<br>
	 * Byte:Byte->Serializable->Object->byte<br>
	 * Short:Short->Serializable->Object->short<br>
	 * Character:Character->Serializable->Object->char<br>
	 * Integer:Integer->Serializable->Object->int<br>
	 * Long:Long->Serializable->Object->long<br>
	 * Float:Float->Serializable->Object->float<br>
	 * Double:Double->Serializable->Object->double<br>
	 * 如果是object无父类<br>
	 * 如果是接口获取所有父接口<br>
	 * 如果是是数组:<br>
	 * int[]: int[] -> Serializable ->Cloneable->Object 如果有超类,延继承链获取所有超类和接口<br>
	 * 
	 * @param aclass
	 *            传入的类
	 * @param autoWrapper
	 *            是否允许自动装箱
	 * @return
	 */
	public static AClass[] getDirectSuperType(AClass as) {
		AClass[] a = null;
		// 如果是原生数据类型
		if (as.isPrimitive()) {
			if (as.equals(AClass.BOOLEAN_ACLASS)) {
				a = new AClass[] { AClass.BOOLEAN_WRAP_ACLASS, AClass.SERIALIZABLE_ACLASS, AClass.OBJECT_ACLASS };
			} else if (as.equals(AClass.BYTE_ACLASS)) {
				a = new AClass[] { AClass.SHORT_ACLASS, AClass.INT_ACLASS, AClass.LONG_ACLASS, AClass.FLOAT_ACLASS, AClass.DOUBLE_ACLASS, AClass.BYTE_WRAP_ACLASS, AClass.SERIALIZABLE_ACLASS, AClass.OBJECT_ACLASS };

			} else if (as.equals(AClass.SHORT_ACLASS)) {
				a = new AClass[] { AClass.INT_ACLASS, AClass.LONG_ACLASS, AClass.FLOAT_ACLASS, AClass.DOUBLE_ACLASS, AClass.SHORT_WRAP_ACLASS, AClass.SERIALIZABLE_ACLASS, AClass.OBJECT_ACLASS };

			} else if (as.equals(AClass.CHAR_ACLASS)) {
				a = new AClass[] { AClass.INT_ACLASS, AClass.LONG_ACLASS, AClass.FLOAT_ACLASS, AClass.DOUBLE_ACLASS, AClass.CHARACTER_WRAP_ACLASS, AClass.SERIALIZABLE_ACLASS, AClass.OBJECT_ACLASS };

			} else if (as.equals(AClass.INT_ACLASS)) {
				a = new AClass[] { AClass.LONG_ACLASS, AClass.FLOAT_ACLASS, AClass.DOUBLE_ACLASS, AClass.INTEGER_WRAP_ACLASS, AClass.SERIALIZABLE_ACLASS, AClass.OBJECT_ACLASS };

			} else if (as.equals(AClass.LONG_ACLASS)) {
				a = new AClass[] { AClass.FLOAT_ACLASS, AClass.DOUBLE_ACLASS, AClass.LONG_WRAP_ACLASS, AClass.SERIALIZABLE_ACLASS, AClass.OBJECT_ACLASS };

			} else if (as.equals(AClass.FLOAT_ACLASS)) {
				a = new AClass[] { AClass.DOUBLE_ACLASS, AClass.FLOAT_WRAP_ACLASS, AClass.SERIALIZABLE_ACLASS, AClass.OBJECT_ACLASS };

			} else if (as.equals(AClass.DOUBLE_ACLASS)) {
				a = new AClass[] { AClass.DOUBLE_WRAP_ACLASS, AClass.SERIALIZABLE_ACLASS, AClass.OBJECT_ACLASS };
			}
			return a;
		} else if (as.equals(AClass.BOOLEAN_WRAP_ACLASS)) {
			a = new AClass[] { AClass.SERIALIZABLE_ACLASS, AClass.OBJECT_ACLASS, AClass.BOOLEAN_ACLASS };
			return a;
		} else if (as.equals(AClass.BYTE_WRAP_ACLASS)) {
			a = new AClass[] { AClass.SERIALIZABLE_ACLASS, AClass.OBJECT_ACLASS, AClass.BYTE_ACLASS };
			return a;
		} else if (as.equals(AClass.SHORT_WRAP_ACLASS)) {
			a = new AClass[] { AClass.SERIALIZABLE_ACLASS, AClass.OBJECT_ACLASS, AClass.SHORT_ACLASS };
			return a;
		} else if (as.equals(AClass.CHARACTER_WRAP_ACLASS)) {
			a = new AClass[] { AClass.SERIALIZABLE_ACLASS, AClass.OBJECT_ACLASS, AClass.CHAR_ACLASS };
			return a;
		} else if (as.equals(AClass.INTEGER_WRAP_ACLASS)) {
			a = new AClass[] { AClass.SERIALIZABLE_ACLASS, AClass.OBJECT_ACLASS, AClass.INT_ACLASS };
			return a;
		} else if (as.equals(AClass.LONG_WRAP_ACLASS)) {
			a = new AClass[] { AClass.SERIALIZABLE_ACLASS, AClass.OBJECT_ACLASS, AClass.LONG_ACLASS };
			return a;
		} else if (as.equals(AClass.FLOAT_WRAP_ACLASS)) {
			a = new AClass[] { AClass.SERIALIZABLE_ACLASS, AClass.OBJECT_ACLASS, AClass.FLOAT_ACLASS };
			return a;
		} else if (as.equals(AClass.DOUBLE_WRAP_ACLASS)) {
			a = new AClass[] { AClass.SERIALIZABLE_ACLASS, AClass.OBJECT_ACLASS, AClass.DOUBLE_ACLASS };
			return a;
		} else if (as.equals(AClass.SERIALIZABLE_ACLASS)) {// 如果传入的是序列化接口,则有父类Object
			a = new AClass[] { AClass.OBJECT_ACLASS };
			return a;
		} else if (as.equals(AClass.OBJECT_ACLASS)) {// 如果传入的是Object,则没有父类
			a = new AClass[0];
			return a;
		} else if (as.isInterface()) {// 如果是接口
			Class<?>[] intfacs = as.getInterfaces();
			if (intfacs != null && intfacs.length > 0) {
				AClass[] interfaceAClassArr = new AClass[intfacs.length];
				List<AClass> list = new ArrayList<AClass>();
				for (int i = 0; i < intfacs.length; i++) {
					interfaceAClassArr[i] = AClassFactory.getProductClass(intfacs[i]);
					list.add(interfaceAClassArr[i]);
				}
				// 因为Java规范不支持平行接口的重载
				// for (AClass interAClass: interfaceAClassArr) {
				// AClass[] aclassArr = getDirectSuperType(interAClass, true);
				// for (AClass aClass : aclassArr) {
				// list.add(aClass);
				// }
				// }

				list.add(AClass.OBJECT_ACLASS);
				a = list.toArray(new AClass[list.size()]);
			} else {
				a = new AClass[] { AClass.OBJECT_ACLASS };
			}
			return a;
		} else if (as.isArray()) {// 如果是数组,当组件为原生数据类型则获取克隆接口和序列化接口;否则获取组件的所有父类
			ArrayClass ac = (ArrayClass) as;
			AClass rootType = ac.getRootComponentClass();

			if (rootType.isPrimitive()) {
				a = new AClass[3];
				a[0] = AClass.SERIALIZABLE_ACLASS;
				a[1] = AClass.CLONEABLE_ACLASS;
				a[2] = AClass.OBJECT_ACLASS;
				return a;
			} else {
				AClass[] rootSupers = getDirectSuperType(rootType);// 获取组件的超类,构建数组的超类数组
				if (rootSupers != null) {// 如果组件存在超类
					a = new AClass[rootSupers.length];
					for (int i = 0; i < a.length; i++) {
						a[i] = AClassFactory.getArrayClass(rootSupers[i], ac.getDimension());
					}
					return a;
				} else {// 如果组件不存在超类,则使用克隆接口和序列化接口
					a = new AClass[3];
					a[0] = AClass.SERIALIZABLE_ACLASS;
					a[1] = AClass.CLONEABLE_ACLASS;
					a[2] = AClass.OBJECT_ACLASS;
					return a;
				}
			}
		} else {// 如果都不是,则开始延继承链寻找
			Class<?> sup = as.getSuperClass();

			Class<?>[] intefaces = as.getInterfaces();
			List<AClass> list = new ArrayList<AClass>();
			AClass supAClass = null;
			// 只有当父类不是Object才增加
			if (sup != Object.class) {
				supAClass = AClassFactory.getProductClass(sup);
				list.add(supAClass);
			}
			for (Class clazz : intefaces) {
				if (clazz != Object.class) {
					AClass interfaceAClass = AClassFactory.getProductClass(clazz);
					list.add(interfaceAClass);
				}
			}
			//有除了Object的父类
			if (supAClass != null) {
				AClass[] superAClassArr = getDirectSuperType(supAClass);
				// 任何类都有Object这个父类
				for (AClass aClass : superAClassArr) {
					if (aClass.equals(AClass.OBJECT_ACLASS)) {
						continue;
					} else {
						if (!list.contains(aClass)) {
							list.add(aClass);
						}
					}
				}
			}
			list.add(AClass.OBJECT_ACLASS);
			a = list.toArray(new AClass[list.size()]);
			return a;
		}

	}



通过以上修改可以正确找出对应的动态绑定方法。

转载于:https://my.oschina.net/woate/blog/379532

 类似资料: