我正在开发一个开源项目,该项目基本上是将大型 C++ 库转换为 Java。 C++ 中原始生物的对象模型有时可能非常复杂。我想说的是……这或多或少是 Java 设计者的座右铭……嗯……这是另一个主题。
重点是我写了一篇文章,展示了如何在 Java 中规避类型擦除。这篇文章很好地解释了它是如何完成的,并最终解释了你的源代码如何最终可以非常接近 C++。
http://www.jquantlib.org/index.php/Using_TypeTokens_to_retrieve_generic_parameters
我所做的研究的一个直接含义是,可以在您的应用程序中实现虚拟基类,我的意思是:不是在 Java 中,不是在语言中,而是在您的应用程序中,通过一些技巧,或者很多技巧要更精确。
如果您确实对这种黑魔法感兴趣,以下几行可能对您有所帮助。否则肯定不会。
好的。让我们继续吧。
Java 有几个难点:
1.类型擦除(文章中解决)
2. javac 不是为了理解什么是虚拟基类而设计的;
3. 即使使用技巧也无法绕过难度#2,因为这个难度出现在编译时。
如果您想使用虚拟基类,您可以使用 Scala,它通过创建另一个完全理解一些更复杂的对象模型的编译器基本上解决了困难 #2,我想说。
如果您想浏览我的文章并尝试在纯 Java(不是 Scala)中“规避”虚拟基类,您可以执行我在下面解释的操作:
假设你在 C++ 中有这样的东西:
template<Base>
public class Extended : Base { ... }
它可以在 Java 中被翻译成这样的东西:
public interface Virtual<T> { ... }
public class Extended<B> implements Virtual<B> { ... }
好的。当您像下面这样实例化 Extended 时会发生什么?
Extended extended = new Extended<Base>() { /* required anonymous block here */ }
嗯..基本上你将能够摆脱类型擦除,并且能够在你的扩展类中获取 Base 的类型信息。有关黑魔法的全面解释,请参阅我的文章。
好的。一旦在 Extended 中拥有 Base 类型,就可以实例化 Virtual 的具体实现。
请注意,在编译时,javac 可以为您验证类型,如下例所示:
public interface Virtual<Base> {
public List<Base> getList();
}
public class Extended<Base> implements Virtual<Base> {
@Override
public List<Base> getList() {
// TODO Auto-generated method stub
return null;
}
}
嗯...尽管努力实现它,但最终我们做得很糟糕,像 scalac 这样的优秀编译器比我们做得更好,特别是它在编译时完成了它的工作。
希望对您有所帮助...如果您还没有感到困惑!