我来自.NET背景,现在涉足Java.
目前,我在设计防御输入错误的API方面遇到了大问题.假设我有以下代码(足够接近):
public void setTokens(Node node, int newTokens) {
tokens.put(node, newTokens);
}
Run Code Online (Sandbox Code Playgroud)
但是,此代码可能会失败有两个原因:
null节点.在.NET中,我会抛出一个ArgumentNullException(而不是一个NullReferenceException!)或ArgumentException分别传递有问题的参数(node)的名称作为string参数.
Java似乎没有等效的例外.我意识到我可以更具体,只是抛出最接近描述情况的异常,或者甚至为特定情况编写我自己的异常类.
这是最好的做法吗?或者是否存在类似于ArgumentException.NET 的通用类?
null在这种情况下检查是否有意义?无论如何代码都会失败,异常的堆栈跟踪将包含上面的方法调用.检查null似乎多余和过度.当然,堆栈跟踪会稍微清晰一些(因为它的目标是上面的方法,而不是HashMapJRE实现中的内部检查).但这必须抵消额外if声明的成本,此外,永远不应该发生 - 毕竟,传递null给上述方法不是预期的情况,这是一个相当愚蠢的错误.期待它是彻头彻尾的偏执 - 即使我不检查它也会失败,同样的例外.
[正如评论中指出的那样,HashMap.put实际上允许null键的值.所以这里的检查null不一定是多余的.]
我在Spring + hibernate中开发了一个Web应用程序,持续了几个月.我一直严重缺少的是异常处理.
我想知道处理异常的最佳方法和实践吗?我脑子里有一些问题,不能涵盖异常处理的所有方面,例如:
1.是否做出检查或未检查的例外?如何决定?
2.如何处理以及如何处理Controller中生成的异常.
3.关于在服务层和DAO层中生成的异常,应该只在该层处理还是应该转移到控制器层?
4.既然有许多例外情况,我怎么能准备好处理将来可能发生的事情?
5.如何向UI或浏览器显示相关消息?
请建议或提供好博客的链接?
我在C#入门书中读到,如果你不知道如何处理它,你不应该发现异常.在使用Java编程时考虑到这些建议,我有时会发现我不知道如何处理异常,但我不得不抓住它或"渗透它"以避免编译错误.我宁愿不要throws在调用树的整个过程中使用子句混乱方法,所以我经常使用"转换"异常,RuntimeException如下所示.throws为许多方法添加子句,这些异常并未真正"处理"(正确处理),这看起来很冗长,令人分心.是以下不好的风格,如果是这样,有什么更好的方法来处理这个?
try {
thread.join();
}
catch (InterruptedException e) {
Console.printwriter.format("%s\n", e.printStackTrace());
throw new RuntimeException();
}
Run Code Online (Sandbox Code Playgroud)
编辑:除了杂乱之外,渗透异常还有另一个问题:在代码修改之后,你可能最终会遇到一些不必要的throws条款.我知道清除它们的唯一方法是通过反复试验:删除它们并查看编译器是否抱怨.显然,如果您想保持代码清洁,这很烦人.
我被告知我应该考虑在我的代码中对Checked异常抛出Unchecked异常,而不仅仅是这样,而是用我自己的扩展RuntimeException.现在,我确实理解了两者之间的区别,但仍然不明白我为什么要这样做?
如果我有这个方法标题,抛出2种异常:
public static Optional<String> getFileMd5(String filePath) throws NoSuchAlgorithmException, IOException {}
Run Code Online (Sandbox Code Playgroud)
为什么我要用一个(不太详细的)例外替换它们?
java exception-handling checked-exceptions unchecked-exception
有一个com.myco.myproj.MyProjRuntimeException有什么意义,它完整地扩展了RuntimeException?
这是不好的做法吗?
public String foo(File file) {
StringBuilder sb = new StringBuilder();
try(
BufferedInputStream bis =
new BufferedInputStream(
new FileInputStream(file))
) {
for(int c = bis.read(); c != -1; c = bis.read())
sb.append((char) c);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
return sb.toString();
}
Run Code Online (Sandbox Code Playgroud)
假设没有办法从已检查的异常中优雅地恢复.
我的课堂作业是编写一个程序,让用户输入一组数值。如果用户输入的值不是数字,程序应该给用户 2 秒的机会正确输入一个数字,在这两次机会之后,停止要求输入并打印到目前为止正确输入的所有值的总和.
照原样,我的代码不能正常工作。当输入第一个非数字时,程序执行一次 catch 块中的代码,在 try 块的开头打印“gimme input”行,然后立即再次执行 catch 块中的代码,无需等待用户输入另一个号码。
在仔细阅读我的教科书以寻找线索时,我注意到这一行:“任何 catch 子句都不会捕获NoSuchElementException 。异常一直抛出,直到它被另一个 try 块捕获或 main 方法终止。”
这很好,因为现在至少我知道发生这种情况是有充分理由的,但是我的教科书没有包含有关此怪癖的任何进一步信息,而且我无法通过 StackOverflow 或 Google 找到任何可以理解的答案。所以我的问题是两部分:
a) 为了这个任务的目的,我应该如何解决这个问题?
b) 异常没有被 catch 子句捕获到底是什么意思?那不是catch 子句存在的目的吗?我确实想要我的任务的解决方案,但我也想了解为什么会这样,如果可能的话。
谢谢你的帮助!
import java.util.InputMismatchException;
import java.util.NoSuchElementException;
import java.util.ArrayList;
import java.util.Scanner;
public class NotANumber {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("This program computes the sum of any number of real numbers. When you are done entering values, enter something …Run Code Online (Sandbox Code Playgroud) 我有以下两个问题:
我试图将一个自定义throws子句添加到由接口定义的方法.这是不可能的.我怎么能绕过它呢?这是一些代码:
private void sendRequestToService(final ModuleRequest pushRequest)
{
ServiceConnection serviceConnection = new ServiceConnection()
{
public void onServiceConnected(ComponentName name, IBinder service)
{
try
{
//some lines..
} catch (RemoteException e)
{
throw new RuntimeException(new UnavailableDestException()) ;
}
}
};
}
Run Code Online (Sandbox Code Playgroud)
知道如何抛出我的自定义异常吗?
Java规范要求如果抛出异常,则由try/catch语句处理,或者使用"throws XYZException"声明该函数.这有RuntimeException的例外,如果抛出它而没有被捕获,则可以.
这可能听起来像是一个意见问题,但我想的越多,它看起来就越反直觉:
为什么我们有一个RuntimeException扩展Exception?
当我第一次开始使用Java时,我认为必须以这种方式捕获所有异常,并且它是有意义的,因为所有异常都扩展了Exception.有一个RuntimeException异常异常似乎违反了OOP:P.由于RuntimeException使throws变得多余,为什么Java在运行时首先不允许所有异常,只有当你想强制调用者处理那种类型的异常时才添加throws?
例子:
void noThrows() {
throw new Exception();
}
Run Code Online (Sandbox Code Playgroud)
......没有错误.
void hasThrows() throws AnyBaseOfXYZException {
throw new XYZException();
}
Run Code Online (Sandbox Code Playgroud)
......没有错误.
void testFunction() {
hasThrows();
}
Run Code Online (Sandbox Code Playgroud)
...失败,因为"hasThrows"抛出AnyBaseOfXYZException,并且没有处理
void testFunction() {
try {
hasThrows();
} catch (AnyBaseOfXYZException e) {
...
}
}
Run Code Online (Sandbox Code Playgroud)
......没有错误.
我想过可能会有一些扩展Exception的"CompileTimeException",但是当你给它足够的思考时,它就不会像RuntimeException那样丑陋.
基本上,throws除了RuntimeExceptions之外,为什么Java决定强制要求所有异常,当所有异常都可以是运行时异常时,除非另有说明throws?