锁定老帖子 主题:【解惑】JVM如何理解Java泛型类
该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2009-12-17
public class TestFan { /** * @param args * * User是一个空class */ public static void main(String[] args) { int i = 0; test(null); } // //不添加此方法.编译,运行没问题.输出显示调用的user //添加此方法时候.编译期出错The method test(String) is ambiguous for the type TestFan public static void test(String str) { System.out.println("string"); } public static void test(User users) { System.out.println("user"); } public static void test(Object users) { System.out.println("object"); } } 请教下: 1.没添加那个方法时候.为什么调用的会是user的那个方法? 2.添加后为什么出错了 |
|
返回顶楼 | |
发表时间:2009-12-17
Heart.X.Raid 写道 class CM<MediaBean>有问题: 首先你要搞清楚你想要定义的类型是泛型类还是普通类。 如果是普通类,class CM implements ConvertMachine<MediaBean>就可以了。 如果是泛型类,正如你定义的一样CM<MediaBean>,编译器会把MediaBean理解为类型变量,相当于常用的T,S,K,V之类的符号。 既然编译器已经认定你定义的class CM<MediaBean>是一个泛型类,而且MediaBean是泛型变量的话。那么编译器理解MediaBean bean 也就认为相当于T bean。试问MediaBean(也就是T)在编译阶段不能够确定具体类型的情况下,MediaBean.getOffset()方法在哪里(也就相当于T.getOffset()方法)。 因此,编译器报错:The method getOffset() is undefined for the type MediaBean 注意,你定义的时候MediaBean已经是CM泛型类的类型变量了,再也不是你认为的某一个类了。一定要保持清醒。 我大概明白了,但是如果是这样的那具体的实现类都不能用泛型来检验编译时错误,只定义接口范围的泛型没什么意义啊。 实际上针对这种情况 public class A<T> extends B<T>{ void method(T param){ //do somthing } } T param 等同于 final T param 局限性很大啊 |
|
返回顶楼 | |
发表时间:2009-12-17
msnvip 写道 public class TestFan { /** * @param args * * User是一个空class */ public static void main(String[] args) { int i = 0; test(null); } // //不添加此方法.编译,运行没问题.输出显示调用的user //添加此方法时候.编译期出错The method test(String) is ambiguous for the type TestFan public static void test(String str) { System.out.println("string"); } public static void test(User users) { System.out.println("user"); } public static void test(Object users) { System.out.println("object"); } } 请教下: 1.没添加那个方法时候.为什么调用的会是user的那个方法? 2.添加后为什么出错了 我觉得这可能是编译器的默认行为吧 默认 Object , ? extends Object 类似多态? 2个子类,编译器识别不了了。。。 |
|
返回顶楼 | |
发表时间:2009-12-18
我就想知道你是如何看到的JVM的源代码,可以和je分享一下么?谢谢
|
|
返回顶楼 | |
发表时间:2009-12-18
mali0330 写道 我就想知道你是如何看到的JVM的源代码,可以和je分享一下么?谢谢
JDK 工具包里面都有一个src文件,里面是source code,但native方法,与虚拟机相关的部分没有公开。 |
|
返回顶楼 | |
发表时间:2009-12-18
Heart.X.Raid 写道 mali0330 写道 我就想知道你是如何看到的JVM的源代码,可以和je分享一下么?谢谢
JDK 工具包里面都有一个src文件,里面是source code,但native方法,与虚拟机相关的部分没有公开。 你知道怎么看Object中的clone方法的vative代码吗?我很想看,一直找不到在哪。。。。。。。。 |
|
返回顶楼 | |
发表时间:2010-01-14
楼上的大大要看这个?
JVM_ENTRY(jobject, JVM_Clone(JNIEnv* env, jobject handle)) JVMWrapper("JVM_Clone"); Handle obj(THREAD, JNIHandles::resolve_non_null(handle)); const KlassHandle klass (THREAD, obj->klass()); JvmtiVMObjectAllocEventCollector oam; #ifdef ASSERT // Just checking that the cloneable flag is set correct if (obj->is_javaArray()) { guarantee(klass->is_cloneable(), "all arrays are cloneable"); } else { guarantee(obj->is_instance(), "should be instanceOop"); bool cloneable = klass->is_subtype_of(SystemDictionary::cloneable_klass()); guarantee(cloneable == klass->is_cloneable(), "incorrect cloneable flag"); } #endif // Check if class of obj supports the Cloneable interface. // All arrays are considered to be cloneable (See JLS 20.1.5) if (!klass->is_cloneable()) { ResourceMark rm(THREAD); THROW_MSG_0(vmSymbols::java_lang_CloneNotSupportedException(), klass->external_name()); } // Make shallow object copy const int size = obj->size(); oop new_obj = NULL; if (obj->is_javaArray()) { const int length = ((arrayOop)obj())->length(); new_obj = CollectedHeap::array_allocate(klass, size, length, CHECK_NULL); } else { new_obj = CollectedHeap::obj_allocate(klass, size, CHECK_NULL); } // 4839641 (4840070): We must do an oop-atomic copy, because if another thread // is modifying a reference field in the clonee, a non-oop-atomic copy might // be suspended in the middle of copying the pointer and end up with parts // of two different pointers in the field. Subsequent dereferences will crash. // 4846409: an oop-copy of objects with long or double fields or arrays of same // won't copy the longs/doubles atomically in 32-bit vm's, so we copy jlongs instead // of oops. We know objects are aligned on a minimum of an jlong boundary. // The same is true of StubRoutines::object_copy and the various oop_copy // variants, and of the code generated by the inline_native_clone intrinsic. assert(MinObjAlignmentInBytes >= BytesPerLong, "objects misaligned"); Copy::conjoint_jlongs_atomic((jlong*)obj(), (jlong*)new_obj, (size_t)align_object_size(size) / HeapWordsPerLong); // Clear the header new_obj->init_mark(); // Store check (mark entire object and let gc sort it out) BarrierSet* bs = Universe::heap()->barrier_set(); assert(bs->has_write_region_opt(), "Barrier set does not have write_region"); bs->write_region(MemRegion((HeapWord*)new_obj, size)); // Caution: this involves a java upcall, so the clone should be // "gc-robust" by this stage. if (klass->has_finalizer()) { assert(obj->is_instance(), "should be instanceOop"); new_obj = instanceKlass::register_finalizer(instanceOop(new_obj), CHECK_NULL); } return JNIHandles::make_local(env, oop(new_obj)); JVM_END |
|
返回顶楼 | |
发表时间:2010-01-19
prowl 写道 msnvip 写道 public class TestFan { /** * @param args * * User是一个空class */ public static void main(String[] args) { int i = 0; test(null); } // //不添加此方法.编译,运行没问题.输出显示调用的user //添加此方法时候.编译期出错The method test(String) is ambiguous for the type TestFan public static void test(String str) { System.out.println("string"); } public static void test(User users) { System.out.println("user"); } public static void test(Object users) { System.out.println("object"); } } 请教下: 1.没添加那个方法时候.为什么调用的会是user的那个方法? 2.添加后为什么出错了 我觉得这可能是编译器的默认行为吧 默认 Object , ? extends Object 类似多态? 2个子类,编译器识别不了了。。。 public class Test { class A { } class B extends A { } public static void main(String[] args) { test(null); } public static void test(A a) { System.out.println("A"); } public static void test(B b) { System.out.println("B"); } } 结果,编译通过,输出B。 public class Test { class A { } class B { } public static void main(String[] args) { test((B) null); } public static void test(A a) { System.out.println("A"); } public static void test(B b) { System.out.println("B"); } } 类A与B没有继承关系时,须将null强制转换。 因此,如果有继承关系的方法重载,会尽可能调用子类那个方法。 |
|
返回顶楼 | |