【问题标题】:True java generics (templates)真正的 java 泛型(模板)
【发布时间】:2011-05-27 10:42:03
【问题描述】:

查看Java VM specification 后,我注意到不仅仅是ASCII 字母可以用来创建标识符。

首先,我想知道是否有任何额外的符号(除了$,可用于标识符)

您认为使用扩展字符集来编码标识符中的附加信息和自定义类加载器是否有可能实现真正的 Java 泛型?

当然,您必须绕过类型擦除,但这可以通过自定义解析器实现吗?

因此,您可以以如下格式存储通用名称:$g$GenericList$_Java_lang_String$

我在这里使用GenericList,因为我不打算修改原始实现!

使用类加载器加载它们,创建一个合适的GenericList<String> 版本并将其发回。

编辑:我计划将它用于我在 JVM 上构建的语言。由于它使用$'s 和_'s 作为特殊字符,这样的编码信息可能会起作用!

编辑 2: 我想更难的事情是泛型方法?有没有人知道如何实施这些信息?

编辑 3: 由于只有在类加载器消失时才能卸载类,所以我是否能够像在 .Net 中那样缓存和删除已解析的模板,还是像 C++ 那样做?

【问题讨论】:

  • +1,有趣的想法。请务必查看 .NET IL,它使用类似的概念来实现没有类型擦除的泛型(其中,字符 `(反引号)用于分隔标识符中的泛型参数)。
  • 其实我一直在研究Rotor (SSCIL),非常非常有趣。我的问题更多的是如何实现每个通用实例的缓存和生存时间

标签: java templates generics classloader


【解决方案1】:

JVM 允许类/字段/方法名称中的任何字符,除了具有特殊含义的/;。混淆器通常使用数字和其他字符来使反编译变得困难。

但是,您可以只使用 $_ 生成类/字段/方法。

注意:JDK 7 应该具有更好的泛型支持,Type 结合了 Class 和泛型。

编辑:

拥有适当的泛型类型的一种方法是始终使用

Set<String> set = new LinkedHashSet<String>() { }; 

{ } 的使用创建了一个匿名类,该类的父类型具有您想要的泛型。您可以通过反射获得此信息。

您可以通过拥有自己的类加载器来缓存和删除类,您可以根据需要处理这些加载器。最极端的情况是每个类都有一个 ClassLoader。

一旦你有了自己的泛型类型,你就可以在你的方法中使用它们,就像普通类型一样。

【讨论】:

  • 非常有趣...打开了很多可能性!不幸的是,我不能依赖拥有 Java 7 的客户端,所以我必须使用我现有的东西
  • { } 前面非常有趣!你知道是否可以在类加载器之间移动类吗?
  • 您可以同时使用来自多个类加载器的类。您可以将相同的类(名称和行为)加载到多个类加载器中,但是一旦类加载器加载了一个类,它就无法移动。但是,您可以让其他类加载器使用此类。
  • 类型检查由编译器完成。它会像现在一样工作。它唯一要添加的是在运行时获取泛型类型信息的能力。 (你不能这样做)
  • 因此,如果我想删除某些已解析的模板类,我可以创建一个新的类加载器。加载我想留下的那些,并取消引用前一个?
【解决方案2】:

由于您可以使用 Unicode,因此您基本上可以使用除上一个答案中提到的几个字母 (/,;) 之外的所有内容。 顺便说一句,没有像“真正的泛型”这样的东西......我知道你的意思;D,这就是所谓的“模板”。

【讨论】:

  • 我知道这很糟糕,但我在想也许可以做一个基本的解决方法!
【解决方案3】:

是的,您可以在 java 中使用任何 unicode 字符作为标识符名称。有关 java 中允许的标识符名称,请参见 here。但正如前面的回答中提到的,你的意思是“真正的泛型”的“模板”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-09
    相关资源
    最近更新 更多