【问题标题】:Is there auto type inferring in Java?Java中有自动类型推断吗?
【发布时间】:2013-04-14 12:11:19
【问题描述】:

Java 中是否有像 C++ 中一样的 auto 变量类型?

一个例子:

for ( auto var : object_array)
    std::cout << var << std::endl;

for( auto var : object_array)
    var.do_something_that_only_this_particular_obj_can_do();

我知道在 Java 中有一个增强的 for 循环,但是有一个自动循环吗?如果没有,这样做是否有技巧?我指的是C++11中的新特性

【问题讨论】:

  • 除了基本类型之外的所有东西都可以赋值给Object类型的变量,所以对于某些操作,你可以在你想要auto的地方使用Object
  • no java 没有这样的变量
  • @Zyx2000 :然后,它会使用对象的to_string 函数,而不是实际的对象,不是吗?
  • @GamesBrainiac:不,如果存在,它将使用覆盖的版本。
  • 您要查找的术语不是“自动”,而是“类型推断”。 Java 中有很多关于类型推断的问题,虽然它们大多是指泛型,所以我不知道如何找到重复的......

标签: java c++ auto


【解决方案1】:

可能是 Java 10 通过 var 关键字拥有您(和我)想要的。

var list = new ArrayList<String>();  // infers ArrayList<String>
var stream = list.stream();          // infers Stream<String>

来自JDK Enhancement Proposals 286


更新:是的,该功能已进入 Java 10 版本!

【讨论】:

  • 是的,它是一种改进,但该关键字只能与局部变量一起使用。不如 C++ 自动类型推断强大
  • 次要挑剔:var 不是关键字!来自JLS:“var 不是关键字,而是具有特殊含义的标识符,作为局部变量声明的类型”。因此,与关键字不同,没有什么可以阻止您调用变量或方法“var”。
  • 好点@KlitosKyriacou。然而,如果我想用“标识符”替换“关键字”——甚至是“具有特殊含义的标识符作为局部变量声明的类型”——我认为答案就不太清楚了。但是,是的,var 确实不在关键字列表中。
  • 它不仅仅是一个向后兼容的关键字。除了您可以使用此名称的标识符这一事实之外,var 还充当关键字的角色。
  • 最后,很遗憾花了这么长时间。那么我们可以期待再过 20 年左右的类型别名吗?
【解决方案2】:

Java 10 引入了 var 标识符,类似于 C++ auto;见sorrymissjackson's answer

在 Java 10 之前,没有与 auto 关键字等效的功能。同样的循环可以实现为:

for ( Object var : object_array)
  System.out.println(var);

Java 具有局部变量,其范围在定义它们的块内。 类似于 C 和 C++,但没有 auto 或 register 关键字。但是,Java 编译器不允许使用未显式初始化的局部变量,并且会给出编译错误(与 C 和 C++ 不同,编译器通常只会给出警告)。 礼貌:Wikipedia .

Java 中没有像 C++ 这样的主流类型推断。有一个RFE,但它被关闭为“不会修复”。给出的是:

人类可以通过两种方式从类型声明的冗余中受益。 首先,冗余类型是有价值的文档——读者不会 必须搜索 getMap() 的声明以找出它的类型 返回。其次,冗余允许程序员声明预期的 类型,从而受益于编译器执行的交叉检查。

【讨论】:

  • @GamesBrainiac 不,Java 中的方法调用总是多态的。但是,许多其他事情(例如重载决议,或任何未在 Object 上定义的操作)不能像这样完成。这不是一个很好的答案,它只是碰巧起作用,因为问题中的例子很弱。
  • 这个问题是关于 C++11 中的类型推断,而不是关于 C 和 C++11 之前的 auto 的旧用法。您的编辑偏离主题。
  • " 这不是我的意思,一旦你把它转换成一个对象,它就会给你对象的 to_string" False。绝对 100% 错误。
  • “人类从冗余中受益。”这是真的。每天早上我醒来都会想“我怎样才能让我的代码更加冗余?”。因为好处。
  • 不实现这么方便的功能的最荒谬的理由,现在我弄清楚为什么我的非开发人员朋友称我为打字员。
【解决方案3】:

Java 7 引入了diamond syntax

Box<Integer> integerBox = new Box<>(); // Java 7

与旧的 java 相比

Box<Integer> integerBox = new Box<Integer>(); // Before Java 7

挑剔的读者会注意到,这种新语法无助于在原始问题中编写 for 循环。这似乎是正确且完全有意的。请参阅引用 Oracle 的错误数据库的其他答案。

【讨论】:

  • 没错,但他(和我)正在寻找的是类似:auto integerBox = new Box&lt;Integer&gt;();,这通常用于从函数中获取返回值,该函数有时可能会像 HashMap&lt;String, LinkedList&lt;Operation, Set&lt;Integer&gt;&gt;&gt;
  • 这个问题正是我在代码示例之后解决的问题。结论是 Java 没有这样做,这是故意的。
  • 当我知道这个添加时,我完全困惑了。它与您的预期完全相反,并提供了适度的好处。
【解决方案4】:

在 Java 8 中,您可以使用 lambda 类型推断来避免声明类型。与提问者的例子类似的是:

object_array.forEach(obj -> System.out.println(obj)); 
object_array.forEach(obj -> obj.do_something_that_only_this_particular_obj_can_do());

两者都可以使用方法引用进行简化:

object_array.forEach(System.out::println); 
object_array.forEach(ObjectType::do_something_that_only_this_particular_obj_can_do);

【讨论】:

    【解决方案5】:

    这不是一个纯 Java 解决方案,但是添加一个名为 lombok 的库将使下面的魔法能够编译和工作非常类似于 C++ 中的 auto 关键字

    List<String> strList = Arrays.asList("foo", "bar", "baz");
    for (val s: strList){
        System.out.println(s.length());
    }
    

    【讨论】:

      【解决方案6】:

      简而言之,不,没有自动类型。如果您所做的只是打印该值,则可以将该值称为Object

      【讨论】:

      • 或计算hashCodes,或收集类名,或者......你明白了;)虽然列表很短。见Object class' docs(评论是给初学者的,我相信你知道SimonC)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-24
      • 2015-08-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多