【问题标题】:Returning "void" or "null" from a method [closed]从方法返回“void”或“null”[关闭]
【发布时间】:2013-01-05 20:15:26
【问题描述】:

这里我有几个问题:

1)我试图从一个方法返回一个null 值,类似这样(仅当TypeCasted 进入对象时):

 public static Object returns()
{
   return (Object)null ;
}

并存储对象:

 ...main()..{
 Object obj=  returns();
 ...}

当我检查时:

  if( obj.equals(obj))

抛出NullPointerException

但是,

 if(null==null)
 System.out.println("works");

编译并给出正确的输出。有什么原因吗?

2) 另外,当我尝试时:

 public static Object returns()
{
  return (Object)void ;
}

给我Syntax Error。有什么理由吗?

3) 这种行为在C/C++ 或任何其他OO 语言中会有所不同吗?

【问题讨论】:

  • 因为它们是基于不同语言规则的不同语言,它们必然会表现出不同的行为。
  • this behaviour be different in C/C++
  • obj.anythingobj 为空时将不起作用。 .equals 几乎在所有情况下都不同于 ==
  • 上述三种语言处理事情的方式完全不同。你应该一次问一个。
  • 在 C++ 中,就像在 Java 中一样,您不能在空指针上调用成员函数(又名方法)(或以任何其他方式取消引用它),但您会得到未定义的行为而不是异常。在 C 中,没有方法等价物,但再次取消引用空指针会产生未定义的行为。在所有三种语言中,void 是一个类型名称,不是一个有效的表达式,所以它不能被强制转换为任何东西。

标签: java c++ c methods return-value


【解决方案1】:

您不能在null 上调用equals,而应使用==。请注意,调用==equals 是不一样的。 == 比较引用,而equals 是按照惯例比较的方法。由于 null 对象没有值,因此对它没有任何意义。

Void 不是任何语言的值,因此不能转换为任何东西(在这种情况下为 Object)。

在 C++ 中要返回 NULL,您必须返回一个指针。要比较返回的对象,您必须输入如下内容:

 if( *obj == *obj)

这将再次失败,因为 obj 为 NULL。在我知道的任何语言中,您都必须在比较之前明确检查 null。

编辑:想一想你尝试在ruby 中的作用

【讨论】:

  • 嗯,没错!其他两种情况呢?
【解决方案2】:

1)

if(obj.equals(obj))

确实,默认的equals 实现只是使用== 来检查两个对象(实际上是两个引用)是否实际上引用了内存中的同一个对象,但它仍然是对实例方法的调用,如果通过null 调用它,它肯定会以NullPointerException 失败。

 if(null==null)

反而没有任何问题,因为你没有调用任何实例方法,你只是在比较地址。

2) void 只是一个关键字,用来标记一个什么都不返回的函数1;尝试退货没有任何意义。相反,null 将对象引用标记为不指向任何内容,这是一个完全不同的概念。

3) 在 C++ 中没有默认的“equals”方法,并且整个对象模型都是基于 值类型(在 Java 中,您通常使用对对象的引用),所以很难进行精确比较。2

在 C++ 中,对象(或引用)保证是“有效”对象(=为其分配了空间并且构造函数已运行),因此不可能得到假设在对象上调用实例方法时等效于NullPointerException

另一方面,有一个 指针NULL 是完全有可能的,在这种情况下,如果你试图在某些情况下取消引用它,你会进入未定义的行为(通常是崩溃)方式(例如通过*->3.

关于相等性检查:默认情况下不实现对象的== 运算符,因此只有当类的实现者实际上为operator== 编写了重载时,比较对象的相等性才有意义;至于指针,== 运算符由语言本身提供(不能被覆盖),它实际上是比较两个地址。


  1. 与在 C 和 C++ 中,void 被认为是一种类型(特别是“无法完成的不完整类型”)相比,在 Java 中 it's not,尽管在某些方面它可以被认为是这样的。
  2. 在 C 中没有类或方法句号 - 它不是 OO 语言;不过,接下来的大部分讨论都适用于 structs 并访问他们的字段。
  3. 虽然...如果实例方法不是 virtual 并且不使用对象的任何字段(=this 指针不会以任何方式取消引用),在大多数实现中你可能会逃脱在NULL 指针上调用实例方法。此外,通过“正式取消引用”指针,您可以避免创建“空引用”,这可能会在使用时造成麻烦。但在这两种情况下,它仍然是未定义的行为 - 即,它不正确,尽管通常不会执行预防性检查,有利于性能而不是严格的规则执行。

【讨论】:

    【解决方案3】:

    (Object)null 为 null,这意味着您不能对其使用任何方法,因为它不存在。

    至于语法错误,在Java中void是一个类型,而不是一个值,所以你不能返回void

    【讨论】:

    • 我们可以在 c/c++ 中做到这一点吗?
    • @joeyrohan:不,您不能取消引用空指针或使用void 作为这些语言中的表达式。
    • 像 Pascal 这样的旧语言会区分过程和函数。两者都是参数化的代码例程,但函数将被允许将结果返回给调用者,类似于数学函数。 C 和后来的语言统一了创建void 类型的概念,表示函数不返回值
    猜你喜欢
    • 2012-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-20
    • 2015-01-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多