C ++中的typedef关键字是否有Java等价物或方法?

时间:2009-07-28 16:23:22

标签: java c++ c design-patterns typedef

来自C和C ++背景,我明智地使用 typedef 非常有帮助。您是否了解在Java中实现类似功能的方法,无论是Java机制,模式还是您使用过的其他有效方式?

12 个答案:

答案 0 :(得分:107)

Java有原始类型,对象和数组,就是这样。没有typedef。

答案 1 :(得分:93)

如果这是你的意思,你可以简单地扩展你想要输入的类,例如:

public class MyMap extends HashMap<String, String> {}

答案 2 :(得分:14)

从1.6开始,java中没有typedef,你可以做的是为你想要的东西创建一个包装类,因为你不能继承最终类(Integer,Double等)

答案 3 :(得分:6)

正如其他人之前提到的,
Java中没有typedef机制。
我也不支持&#34;假班&#34;总的来说,这里不应该有一般严格的经验法则:
如果您的代码例如使用一遍又一遍的基于通用的类型&#34;例如:

Map<String, List<Integer>> 

你一定要考虑为此目的设一个子类。
可以考虑的另一种方法是,例如在代码中包含减速:

//@Alias Map<String, List<Integer>>  NameToNumbers;

然后在你的代码NameToNumbers中使用并有一个预编译器任务(ANT / Gradle / Maven)来处理和生成相关的java代码。
我知道对于这个答案的一些读者来说,这可能听起来很奇怪,但这是实施了多少框架&#34;注释&#34;在JDK 5之前,这是项目lombok正在做的事情和其他框架。

答案 4 :(得分:3)

实际上,继承到Javaland的typedef的唯一用途是别名 - 也就是说,为同一个类赋予多个名称。也就是说,你有一个“A”类,你想要“B”来指代同一个东西。在C ++中,你将做“typedef B A;”

不幸的是,他们只是不支持它。但是,如果您控制所涉及的所有类型,您可以在库级别引入令人讨厌的黑客攻击 - 您要么从A扩展B,要么让B实现A。

答案 5 :(得分:2)

也许这可能是另一种可能的替代品:

@Data
public class MyMap {
    @Delegate //lombok
    private HashMap<String, String> value;
}

答案 6 :(得分:2)

如其他答案中所述,您应该避免使用pseudo-typedef antipattern。但是,即使不是实现它们的方法,typedef仍然有用。您希望区分具有相同Java表示的不同抽象类型。您不希望将密码字符串与街道地址字符串混淆,或者将表示偏移量的整数与表示绝对值的字符串混合在一起。

Checker Framework使您能够以向后兼容的方式定义typedef。我甚至为int等原始类和String等最终类工作。它没有运行时开销,也没有破坏相等测试。

Checker Framework手册中的Type aliases and typedefs部分介绍了根据需要创建typedef的几种方法。

答案 7 :(得分:1)

Kotlin支持类型别名https://kotlinlang.org/docs/reference/type-aliases.html。您可以重命名类型和函数类型。

答案 8 :(得分:-1)

在某些情况下,绑定注释可能就是您正在寻找的内容:

https://github.com/google/guice/wiki/BindingAnnotations

或者如果您不想依赖Guice,只需要定期注释即可。

答案 9 :(得分:-6)

你可以使用Enum,虽然它在语义上与typedef有点不同,因为它只允许一组有限的值。另一种可能的解决方案是命名包装类,例如

public class Apple {
      public Apple(Integer i){this.i=i; }
}

但这似乎更笨重,特别是考虑到代码中不清楚该类没有其他功能而不是别名。

答案 10 :(得分:-7)

Typedef允许将项隐式分配给它们不是的类型。有些人试图通过扩展来解决这个问题; read here at IBM for an explanation of why this is a bad idea.

编辑:虽然强类型推断是一个有用的东西,但我不认为(并希望我们不会)看到typedef在托管语言中看到它是丑陋的头(永远?)。

编辑2:在C#中,您可以在源文件的顶部使用这样的using语句。它被使用,所以你不必做第二项显示。只有当范围引入两种类型之间的名称冲突时,才会看到名称更改。重命名仅限于一个文件,在该文件之外,使用它的每个变量/参数类型都以其全名称。

using Path = System.IO.Path;
using System.IO;

答案 11 :(得分:-14)

Java中不需要typedef。除了原语之外,一切都是对象。没有指针,只有引用。通常使用typedef的场景是您在其中创建对象的实例。