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

bn.*_*bn. 237 c c++ java design-patterns typedef

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

cle*_*tus 112

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

  • @TomášZato缩短长类型也很有用,例如`typedef MegaLongTemplateClass <With,Many,Params> IsShorten;`. (71认同)
  • @TomášZato我不认识大多数人,但根据我的经验,它对于添加语义非常有用:`typedef int PlayerID`,它使编译器能够确保PlayerID不会与其他整数互换使用,并且它还可以生成代码对人类来说更具可读性.基本上,它就像一个枚举,但没有一组有限的价值观. (62认同)
  • 我想大多数人都希望`typedef`将`boolean`重新定义为`bool`. (33认同)
  • @ weberc2"它使编译器能够确保PlayerID不会与其他整数交替使用" - "typedef"不会启用任何此类操作.它只给出了一个类型的另一个名称. (29认同)
  • 例如,如果您有一些类型为"int"的ID并且需要将其更改为"long",则必须在使用ID的代码中的每个位置更改它.如果你有`typedef`,你只需要在一个地方改变它. (6认同)
  • 'typedef'与'primitive type','object'或'array'不同.最后三个是所有类型的类型,而typedef与为现有类型赋予新名称的别名相同."Java有原始类型,对象和数组,就是这样." 'Java没有typedef'都是真正的陈述.只是第二个与第一个无关. (4认同)
  • 如果您想在尝试以错误的顺序传递两个长参数时出现编译错误,也很有用 - 如果它们具有语义 typedef,那么您可以确保它们始终以正确的顺序传递,因为调用者必须使用相同的顺序typedef 来声明它们。例如,您可能有一个 typedef `long` -&gt; `microdollars`,以便将某物的 *价格* 和您想要购买的 *金额* 以正确的顺序传递给 `buy` 函数。 (2认同)

Zed*_*Zed 97

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

public class MyMap extends HashMap<String, String> {}
Run Code Online (Sandbox Code Playgroud)

  • @Andreas_D:你的链接,已修复:http://www.ibm.com/developerworks/java/library/j-jtp02216/index.html (30认同)
  • 肯定是 - "typedef"没有文章描述的那些假类(并且它们非常真实). (21认同)
  • 虽然这种方法的_main_问题是你不能将它用于`final`类. (8认同)
  • 我喜欢这个,因为我喜欢typedef.如果您有一个对象容器,则可以通过更改typedef来轻松交换容器类型.此外,它可以将容器抽象给最终用户(这有时是可取的).我通常会在另一个类中执行此操作,因此类型变得更加明显(即MyTree.Branches,其中类Branches扩展HashSet <MyTree> {}) (7认同)
  • 我认为这是否比在C中使用typedef更具反模式. (4认同)
  • 而且,对于诸如`java.lang.String`之类的最终类,它甚至都不可能 (2认同)
  • 我搜索"java中的typedef"的确切原因是针对上面的HashMap声明.所以我可以使用HashMap <Person,Detail>之类的东西,而不是像这个HashMap <String,String>那样使用泛型声明,或者不使用String Class创建和扩展Person和Detail类. (2认同)

z *_* - 14

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

  • 引用的反模式文章基于这样的假设:您只想缩短您的输入(这实际上会隐藏有用的类型信息).大多数人想要的真正用途是消除类型的歧义,让编译器为你完成它的工作.见上面的IndexT.public Invoice fetchInvoiceItem(String,String,String); 与公共发票fetchInvoiceItem(CustomerId,InvoiceId,InvoiceLineItemId); 显式类型加转换器/验证器使编程Web API在一切开始时作为String更安全. (2认同)
  • java中没有运算符重载,所以它变得很难看 (2认同)

Yai*_*sky 8

正如其他人之前提到的,
Java中没有typedef机制.
我一般也不支持"假类",但这里不应该有一般的严格经验法则:
例如,如果你的代码使用了一遍又一遍的"基于泛型的类型",例如:

Map<String, List<Integer>> 
Run Code Online (Sandbox Code Playgroud)

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

//@Alias Map<String, List<Integer>>  NameToNumbers;
Run Code Online (Sandbox Code Playgroud)

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


小智 5

确实,继承到Javaland的typedef唯一用途是别名-即为同一个类提供多个名称。也就是说,您拥有一个“ A”类,并且您希望“ B”引用同一件事。在C ++中,您将执行“ typedef BA;”。

不幸的是,他们只是不支持它。但是,如果您控制所有涉及的类型,则可以在库级别进行讨厌的破解-您可以从A扩展B或让B实现A。

  • 具有`typedef`对于创建泛型类型的别名也很有用。例如:`typedef A &lt;Long,String&gt; B;`(这可能是您所描述的特例,但更清楚地显示了该想法的吸引力)。 (14认同)

shr*_*est 5

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

@Data
public class MyMap {
    @Delegate //lombok
    private HashMap<String, String> value;
}
Run Code Online (Sandbox Code Playgroud)

  • 您仍然可以执行 myMapInstance.SomeOperation() - 这就是 @Delegate 的用途 (3认同)
  • 您不认为现在有问题吗,因为每当您定义类型为“MyMap”的“myMap”实例时,您只能通过键入“myMapInstance.value.SomeOperation()”而不是“myMapInstance.SomeOperation(”来操作实际的 HashMap )`。这很烦人,不是吗? (2认同)