大老赖不赖
大老赖不赖
发布于 2023-06-07 / 25 阅读 / 0 评论 / 0 点赞

反射坑

实例化一个Void

代码

public final class Main {
	public static void main(final String[] args) throws
			NoSuchMethodException,
			InvocationTargetException,
			InstantiationException,
			IllegalAccessException {
		final Constructor<Void> constructor = Void.class.getDeclaredConstructor();
		constructor.setAccessible(true);
		final Void x = constructor.newInstance();
		System.out.println(x);
	}
}

运行结果:

Unable to make private java.lang.Void() accessible: module java.base does not "opens java.lang" to unnamed module @15aeb7ab

这个是因为Java9中对反射的安全性做了限制

解决办法

添加JVM参数即可

--add-opens java.base/java.lang=ALL-UNNAMED

Java中的泛型

此处使用openJDK20进行实验

时间:2023-06-07

泛型擦除

public final class Main {
	public static void main(final String[] args) throws
			NoSuchMethodException,
			InvocationTargetException,
			IllegalAccessException {
		final Value<Integer> v = new Value<>();
		//调用set方法
		final Method setter = v.getClass().getMethod("setV", Object.class);
		setter.invoke(v, "Java压根就没有泛型");
		/*这个会报错,因为无法从String->Integer
		也就是((Integer)v.getV()).getClass()
		System.out.println(v.getV().getClass());*/
		print(v.getV());
	}

	private static void print(final Object o) {
		System.out.println(o.getClass().getSimpleName());
		System.out.println(o);
	}
}

class Value<T> {
	private T v;

	public T getV() {
		return v;
	}

	public void setV(final T v) {
		this.v = v;
	}
}

输出结果

String
Java压根就没有泛型

泛型被擦除了

原理

Java中的泛型检查仅限编译前,运行时所有的泛型都会变成Object

参考:

解决JDK9以上的非法反射访问警告_--illegal-access_氷泠的博客

Java的非法反射警告illegal reflective access operation


评论