Java:编译时Object的隐式转换不起作用,但可以使用反射
发布时间:2020-12-15 04:22:08 所属栏目:Java 来源:网络整理
导读:给出以下代码: import java.lang.reflect.Array;import java.lang.reflect.Method;public class Test { public static void test_function(int[] values) { System.out.println("Class of values : " + values.getClass()); System.out.println(values[0]);
给出以下代码:
import java.lang.reflect.Array; import java.lang.reflect.Method; public class Test { public static void test_function(int[] values) { System.out.println("Class of values : " + values.getClass()); System.out.println(values[0]); } public static void main(String[] args) { Object a = Array.newInstance(int.class,3); Array.set(a,5); Class a_class = a.getClass(); Class int_array_class = int[].class; System.out.println("Class of int[] : " + int[].class); System.out.println("Class of a : " + a.getClass()); System.out.println("int_array_class : " + int_array_class); System.out.println("a_class : " + a_class); // These instructions will provoke a compile-time error // test_function(a); // test_function(a_class.cast(a)); // test_function(int_array_class.cast(a)); // The following call won't cause any problem test_function((int[]) a); Method testf = null; try { testf = Test.class.getMethod("test_function",int[].class); testf.invoke(null,a); // Does not provoke exception at run-time either testf.invoke(null,a_class.cast(a)); testf.invoke(null,int_array_class.cast(a)); } catch(Exception e) { e.printStackTrace(); } } } 我注意到显式地将Object传递给方法不起作用.如果取消注释,三条注释说明将引发以下错误: Test.java:25: error: method test_function in class Test cannot be applied to given types; test_function(a); ^ required: int[] found: Object reason: actual argument Object cannot be converted to int[] by method invocation conversion Test.java:26: error: method test_function in class Test cannot be applied to given types; test_function(a_class.cast(a)); ^ required: int[] found: Object reason: actual argument Object cannot be converted to int[] by method invocation conversion Test.java:27: error: method test_function in class Test cannot be applied to given types; test_function(int_array_class.cast(a)); ^ required: int[] found: Object reason: actual argument Object cannot be converted to int[] by method invocation conversion 3 errors 但是,通过反射传递对象可以正常工作并产生预期的结果. Class of int[] : class [I Class of a : class [I int_array_class : class [I a_class : class [I Class of values : class [I 5 Class of values : class [I 5 Class of values : class [I 5 Class of values : class [I 5 所以问题是:为什么编译器拒绝编译在运行时工作正常的三个命令指令? 解决方法
反射访问能够在运行时确定对象的实际类型.另一方面,编译器只知道声明的类型.它没有任何其他检查实际类型参数的可能性.
您的变量a声明为Object.因此 test_function(a); 您尝试使用签名void test_function(Object)调用一个根本不存在的方法.一个简单的演员 – 就??像你和程序员一样知道正确的类型 – 会在这里有所帮助: test_function((int[]) a); // works fine (even at runtime) 另外两个方法调用是相同的,但有点不同.您使用类型Class声明了a_class和int_array_class.这是一个原始类型,因此编译器不知道这些变量可以引用哪种类型.编译器必须推断类型Object.这导致了与以前相同的问题(和解决方案). 但是,Class是泛型类型,可以参数化.通过以下更改,最后一个方法调用无需显式转换: Class<int[]> int_array_class = int[].class; test_function(int_array_class.cast(a)); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |