Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将null传递给方法 我正在阅读优秀的_Java_Null_Assert - Fatal编程技术网

Java 将null传递给方法 我正在阅读优秀的

Java 将null传递给方法 我正在阅读优秀的,java,null,assert,Java,Null,Assert,其中一个讨论是关于将null传递给方法 public class MetricsCalculator { public double xProjection(Point p1, Point p2) { return (p2.x - p1.x) * 1.5; } } ... calculator.xProjection(null, new Point(12,13)); 它代表了不同的处理方式: public double xProjection(Point p1,

其中一个讨论是关于将null传递给方法

public class MetricsCalculator {
    public double xProjection(Point p1, Point p2) {
        return (p2.x - p1.x) * 1.5;
    }
}
...
calculator.xProjection(null, new Point(12,13));
它代表了不同的处理方式:

public double xProjection(Point p1, Point p2) {
    if (p1 == null || p2 == null) {
        throw new IllegalArgumentException("Invalid argument for xProjection");
    }
    return (p2.x - p1.x) * 1.5;
}

public double xProjection(Point p1, Point p2) {
    assert p1 != null : "p1 should not be null";
    assert p2 != null : "p2 should not be null";
    return (p2.x - p1.x) * 1.5;
}
我更喜欢这种方法,但我不喜欢断言默认关闭的事实

该书最后指出:

在大多数编程语言中,没有处理调用方意外传递的null的好方法。正因为如此,理性的方法是禁止默认传递null

它并没有真正涉及到你将如何实施这个限制


你们中有谁有强烈的意见吗?

我一般都不喜欢这样做,因为这样做只会让事情变慢。不管怎样,稍后都会抛出NullPointerException,这将很快导致用户发现他们正在将null传递给该方法。我过去经常检查,但我的代码中有40%最终都是检查代码,在这一点上,我决定不值得这么好的断言消息

它并没有真正涉及到你将如何实施这个限制

如果它们传入null,则抛出一个

if (p1 == null || p2 == null) {
    throw new IllegalArgumentException("Invalid argument for xProjection");
}
我同意或不同意,这取决于他具体说了什么

在这种情况下,当然,这个方法将在
null
上崩溃,因此这里可能不需要显式检查


但是,如果该方法仅存储传递的数据,并且您稍后调用的其他方法将处理该数据,尽早发现错误输入是更快修复错误的关键。在随后的时间点上,可能会有无数种方式碰巧将坏数据提供给您的类。这有点像是试图找出老鼠是如何在事后进入你家的,试图在某处找到洞。

我更喜欢使用断言


我有一条规则,我只在公共和受保护的方法中使用断言。这是因为我相信调用方法应该确保它将有效参数传递给私有方法。

一般规则是,如果您的方法不期望
null
参数,那么您应该抛出。抛出适当的
异常
不仅可以防止资源损坏和其他不好的事情,还可以作为代码用户的指南,节省调试代码的时间


还读了一篇关于克里斯·卡彻的文章,我认为这是绝对正确的。我要说的唯一一件事是单独检查参数,并让exeption报告为null的参数,因为它使跟踪null来自何处变得更容易


@哇!如果编写代码对您来说太费劲了,那么您应该研究类似的东西(或者Java等价物,如果有的话),它可以对程序集进行后期处理并为您插入参数检查

虽然它不是严格相关的,但您可能想看看

我认为它仍在开发中(由微软),但一些CTP是可用的,它看起来很有希望。基本上,它允许您执行以下操作:

  public static int Divide(int x, int y)
    requires y != 0 otherwise ArgumentException; 
  {
  }

它还提供了其他特性,如Notnull类型。它构建在.NETFramework2.0之上,完全兼容。正如您所看到的,语法是C#。

Spec#看起来非常有趣

当类似的东西不可用时,我通常使用运行时空检查和内部方法的断言来测试非私有方法。我没有在每个方法中显式地编写null检查代码,而是将其委托给具有check null方法的实用程序类:

/**
 * Checks to see if an object is null, and if so 
 * generates an IllegalArgumentException with a fitting message.
 * 
 * @param o The object to check against null.
 * @param name The name of the object, used to format the exception message
 *
 * @throws IllegalArgumentException if o is null.
 */
public static void checkNull(Object o, String name) 
    throws IllegalArgumentException {
   if (null == o)
      throw new IllegalArgumentException(name + " must not be null");
}

public static void checkNull(Object o) throws IllegalArgumentException {
   checkNull(o, "object");
} 

// untested:
public static void checkNull(Object... os) throws IllegalArgumentException {
   for(Object o in os) checkNull(o);  
}
然后检查变成:

public void someFun(String val1, String val2) throws IllegalArgumentException {
   ExceptionUtilities.checkNull(val1, "val1");
   ExceptionUtilities.checkNull(val2, "val2");

   /** alternatively:
   ExceptionUtilities.checkNull(val1, val2);
   **/

   /** ... **/
} 
可以添加编辑器宏或代码处理脚本。
编辑:详细检查也可以通过这种方式添加,但我认为自动添加一行要容易得多。

也不是立即使用,而是与提到规范有关。。。有人建议在Java的未来版本中添加“空安全类型”:

根据这个提议,你的方法将变得

public class MetricsCalculator {
    public double xProjection(#Point p1, #Point p2) {
        return (p2.x - p1.x) * 1.5;
    }
}
其中,
#Point
是指向类型为
Point
的对象的非
null
引用的类型,在我看来,在方法的开头,Java
IllegalArgumentException
是最清晰的解决方案


对于运行时异常,我们应该始终小心,这些异常不是在方法签名上声明的。由于编译器不强制您捕获这些,因此很容易忘记它们。确保您有某种“全面”异常处理,以防止软件突然停止。这是用户体验中最重要的部分。

处理这一问题的最佳方法是使用异常。最终,断言最终将为最终用户提供类似的体验,但在向最终用户显示异常之前,开发人员无法调用代码来处理这种情况。最后通牒,您希望确保尽早测试无效输入(尤其是在面向公众的代码中),并提供调用代码可以捕获的适当异常

在大多数编程语言中,没有处理调用方意外传递的null的好方法。正因为如此,理性的方法是禁止默认传递null

我发现到目前为止,处理这个问题的JetBrains
@Nullable
@NotNull
注释方法是最巧妙的。不幸的是,它是特定于IDE的,但在我看来,它确实干净而强大


将这个(或类似的东西)作为java标准将非常好。

这里使用断言和抛出异常都是有效的方法。这两种机制都可以用来指示编程错误,而不是运行时错误,这里就是这样

  • 断言具有性能优势,因为它们通常在生产系统上被禁用
  • 例外情况
    public class MetricsCalculator {
        public double xProjection(#Point p1, #Point p2) {
            return (p2.x - p1.x) * 1.5;
        }
    }
    
    //  allocate null
    var name : Option[String]
    name = None
    
    //  allocate a value
    name = Any["Hello"]
    
    //  print the value if we can
    name match {
      Any[x] => print x
      _ => print "Nothing at all"
    }