出于多种原因,异常处理是在 Java 中实现错误处理的一种更为优雅的方式。
错误代码
返回错误代码works well in C 尤其是因为能够在 C 中将指针作为函数参数传递:通过这种方式,您可以例如在函数内部创建一个新对象,并通过传递给函数的指针“返回”它,并让函数实际上 return 一个正确的错误代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int create_message_str(char *p_message, const size_t p_message_len)
{
int result = -1;
const char message[] = "Hello, world!";
if (NULL != p_message && strlen(message) <= p_message_len)
{
strcpy(p_message, message);
result = 0;
}
return result;
}
int main(int argc, char **argv)
{
int result = EXIT_FAILURE;
const size_t p_message_len = 13;
char *p_message = malloc(p_message_len * sizeof(char));
if (create_message_str(p_message, p_message_len) == 0)
{
printf("%s\n", p_message);
result = EXIT_SUCCESS;
}
else
{
fprintf(stderr, "%s\n", "Could not copy string to pointer memory.");
}
free(p_message);
return result;
}
然而,在 Java 中,您必须创建一个实例,例如某种可变的Supplier-like 对象,用于保存对对象的引用,该对象将由 C 函数中的指针引用:
public class ReferenceSwapper {
private static class MutableSupplier<T> implements Supplier<T> {
private T supplied;
public MutableSupplier(final T supplied) {
this.supplied = supplied;
}
@Override
public T get() {
return supplied;
}
public void set(final T supplied) {
this.supplied = supplied;
}
}
public static void main(final String[] args) {
final MutableSupplier<String> firstSupplier = new MutableSupplier<String>("foo");
final MutableSupplier<String> secondSupplier = new MutableSupplier<String>("bar");
System.out.println("Before reference swap: " + firstSupplier.get() + secondSupplier.get());
swapSupplied(firstSupplier, secondSupplier);
System.out.println("After reference swap: " + firstSupplier.get() + secondSupplier.get());
}
private static <T> void swapSupplied(final MutableSupplier<T> firstSupplier,
final MutableSupplier<T> secondSupplier) {
final T firstSupplied = firstSupplier.get();
final T secondSupplied = secondSupplier.get();
firstSupplier.set(secondSupplied);
secondSupplier.set(firstSupplied);
}
}
这段代码打印出来:
Before reference swap: foobar
After reference swap: barfoo
如您所见,由于 pass-by-value semantics,这在 Java 中非常复杂。
例外情况
不过,Java 提供了一种更高级别的方式来定义错误处理行为:异常。尽管some people debate if the idea of exceptions are a good thing or not 和exception handling is really just fancy conditional logic,它们是Java 语言的一部分,can work well 用于报告异常(即错误)状态。
作为Andy Turner already mentioned,抛出IllegalArgumentException 将是报告与方法的特定参数有关的错误的最自然方式,您不应该(通常)必须捕获和处理:您会假设人们使用sumPoints(Point p) 足够聪明,可以传递正确的参数,或者如果不是这样,至少会导致程序停止。但是,如果您确实认为这是一个常见的事件,那么至少是通过明智的编程无法避免的事件(例如,如果数据是从磁盘读取的并且可能以某种方式损坏或不可用),那么最好抛出一个捕获的异常以强制调用方法处理发生这种情况的情况。