BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / java / #54396同步于 2016/12/22
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖

[已解决]关于运行时获取范型的class

ytinrete
2016/12/22镜像同步8 回复
已经决定改成这样了 ```java class Foo<T>{ private final Class<T> mClazz; public Foo(Class<T> clz){ mClass = clz;//需要的时候直接拿就好 } public void doSth(){ T t; //这里我需要拿到t的class该怎么做呢-> mClazz } } ``` -------------------------------------------------------------- ```java class Foo<T>{ public void doSth(){ T t; //这里我需要拿到t的class该怎么做呢? } } ``` 参考了http://stackoverflow.com/questions/3437897/how-to-get-a-class-instance-of-generics-type-t这个 的确可以在构造的时候把类型传进来,但是我觉得 Foo<Bar> foo = new Foo<Bar>(Bar.class); 这样写很蠢。。。 还有用这种方法能拿到的: entityBeanType = ((Class) ((ParameterizedType) getClass() .getGenericSuperclass()).getActualTypeArguments()[0]); 不过这种办法似乎不科学(至于为什么我还是没搞明白) https://www.oschina.net/code/snippet_155593_50917 为什么会这样呢?明明是有了范型,为什么连一个运行时class都拿得不熟练啊。 有没有人遇到类似问题的,求助一下。嗯嗯。
订阅后,新回复会通过你的通知中心匿名送达。
8 条回复
ml3615556机器人#1 · 2016/12/22
```java public class SimpleTest { public static class Tee<T>{ public void doths(T a){ System.out.println(a.getClass()); } } @Test public void test(){ Tee<Number> a = new Tee<Number>(); a.doths(1); Tee<String> b = new Tee<>(); System.out.println(new TypeToken<Tee<String>>() {}.getType()); } } ``` 你这个路子也太野了吧。。 T t;没有办法实例化的,怎么拿类型? 【 在 ytinrete 的大作中提到: 】 : [md] : : ```java : ...................
nuanyangyang机器人#2 · 2016/12/22
10年前,Java开发人员设计Java1.5,加入泛型时候,面对了两种选择: 1. 重新设计JVM,将泛型作为JVM的特性,但会牺牲向前兼容性。 2. 将Java的泛型作为Java语言级的特性,但翻译到JVM bytecode时把泛型参数都擦除(type erasure),这样JVM不会知道泛型的存在,但可以保持兼容Java1.4的bytecode。 在两种选择之间,它们选择了2。于是,Java语言级的“泛型”参数,到了JVM里就都擦掉了,所以Foo<T>和Foo<Object>在编译成JVM bytecode时都是一样的,那个参数在运行时也就拿不到了。 默哀。 【 在 ytinrete 的大作中提到: 】 : [md] : : ```java : ................... 附件(4.7MB)
mh250303135机器人#3 · 2016/12/22
你最好把你的需求说一下,不然并不知道你想要做什么
nuanyangyang机器人#4 · 2016/12/22
顺便来炫耀一下Scala。Scala有一种特殊语法: class Foo[T: ClassTag] 其中方括号部分是泛型参数。但是,这里,T: ClassTag的意思是,要想生成一个Foo[T]实例,当前作用域里必须有一个类型是ClassTag[T]的对象。这个ClassTag[T]对象编译器会自动生成,其实就是Class[T]的封装。 看下面的例子: package cn.byr.nuanyangyang.classtagtest import java.io.{InputStreamReader, Reader} import scala.reflect.ClassTag object ClassTagTest { class Foo[T: ClassTag] { private def ctag = implicitly[ClassTag[T]] def testInstance(obj: AnyRef): Boolean = ctag.runtimeClass.isInstance(obj) def getClassOfT(): Class[T] = ctag.runtimeClass.asInstanceOf[Class[T]] } def main(args: Array[String]): Unit = { val fooStr = new Foo[String]() val fooReader = new Foo[Reader]() val x = "Hello world" val y = new InputStreamReader(System.in) println(fooStr.testInstance(x)) println(fooStr.testInstance(y)) println(fooReader.testInstance(x)) println(fooReader.testInstance(y)) println(fooStr.getClassOfT().getCanonicalName()) println(fooReader.getClassOfT().getCanonicalName()) } } Foo有一个带ClassTag的泛型参数T。main创建Foo的时候,会隐含地把那个ClassTag[T]对象传给构造函数,本质上还是把T.class传给Foo了。这样,在类里面,可以用implicitly[ClassTag[T]]得到这个隐藏的ClassTag[T]对象。ClassTag[T]的runtimeClass方法得到Java层面的Class[T]对象,这样就能在运行时得到T的类型信息了。 其实Scala在JVM上实现,本质上和Java里传T.class是一样的,但语法漂亮得多。 当然,上述程序的运行结果: true false false true java.lang.String java.io.Reader
ytinrete机器人#5 · 2016/12/22
【 在 ml3615556 的大作中提到: 】 : [md] : ```java : public class SimpleTest { : ................... 的确哦,不过那个应用场景并不需要实例化,只是需要拿那个class而已, 不过范型的话的确没什么可靠的办法了呢,运行时作为Object,我怎么知道我自己是谁啊,还是老老实实给它传吧。
ytinrete机器人#6 · 2016/12/22
【 在 nuanyangyang 的大作中提到: 】 : 10年前,Java开发人员设计Java1.5,加入泛型时候,面对了两种选择: : 1. 重新设计JVM,将泛型作为JVM的特性,但会牺牲向前兼容性。 : 2. 将Java的泛型作为Java语言级的特性,但翻译到JVM bytecode时把泛型参数都擦除(type erasure),这样JVM不会知道泛型的存在,但可以保持兼容Java1.4的bytecode。 : ................... 啊,原来如此被擦掉了呢,它自己都不认识自己那就没办法了。 这张图是暖神自己弄的吧,槽点略多啊,不怕被跨省,不,是跨国么233 另外Duke很萌的,请不要黑他。还有哀乐听着很带感呢而且我竟然听完了。
ytinrete机器人#7 · 2016/12/22
【 在 mh250303135 的大作中提到: 】 : 你最好把你的需求说一下,不然并不知道你想要做什么 就是“运行时想拿一个范型的具体类”这个代码该怎么写 诶,这个并不是解决不了问题了啦,我把类构造方法改一下主动把类传进来就好了, 只是 Foo<Bar> foo = new Foo<Bar>(Bar.class); 这样写很蠢。。。明明前面都写过一次,然后还得写一次感觉太笨了。 想想是不是有什么更优雅的办法。嘛,如果不行就算了,反正我也很蠢,很多时候2333
ytinrete机器人#8 · 2016/12/22
【 在 nuanyangyang 的大作中提到: 】 : 顺便来炫耀一下Scala。Scala有一种特殊语法: : [code=scala] : class Foo[T: ClassTag] : ................... Scala完全不懂哎,听起来很强的样子,大概的意思就是说Scala的范型会隐含的把自己的类的信息带进去(相当于语法层面帮程序员这么做了?)所以运行时就有办法把这些信息拿出来。这种感觉?(歪头~