在某些语言中,可以在堆栈跟踪中获取行的列号,但在Java中,我们只有行号。
举个例子,我们可以用另一种语言:
Error
at <anonymous>:2:2
at Object.InjectedScript._evaluateOn (<anonymous>:641:39)
at Object.InjectedScript._evaluateAndWrap (<anonymous>:580:52)
at Object.InjectedScript.evaluate (<anonymous>:495:21)"
虽然这可能是一个糟糕的例子,因为我从浏览器控制台导致错误,但您可以看到列号,这对解决错误非常有帮助。
用Java提供示例(是的,名称已更改):
Caused by: java.lang.IllegalArgumentException: path was null
at org.jboss.resteasy.specimpl.ResteasyUriBuilder.path(ResteasyUriBuilder.java:362)
at enterprise.money.service(AbstractSomething.java:88)
这会导致包含
的行88
URI uri = uriInfo.getBaseUriBuilder().path(objectA).path(objectB).build();
使用堆栈跟踪,我无法检查哪个.path
调用导致异常。所以我的问题是,是否有任何解决方案可以让我获得该列的参考?
(为了防范一些可能的替代答案,我们需要一个解决方案来获取列号,其他答案,如如何逐步调试或重构每个构建器模式等,将无法回答问题)< / em>的
答案 0 :(得分:5)
这是不可能的。
您可以通过以这种方式格式化代码来绕过它:
URI uri = uriInfo
.getBaseUriBuilder()
.path(objectA)
.path(objectB)
.build();
在Oracle Java 8 中,您可以编写
public static void main(String... ignored) {
List<String> s = new ArrayList<>();
s.add("hello");
Predicate<? super String> predicate1 = (t) -> t.length() > 0;
Predicate<? super String> predicate2 = (t) -> t.length() < 8;
Predicate<? super String> predicate3 = null;
List<String> collect = s.stream()
.filter(predicate1) // 16
.filter(predicate2) // 17
.filter(predicate3) // 18
.collect(Collectors.toList());
}
你得到了
Exception in thread "main" java.lang.NullPointerException
at java.util.Objects.requireNonNull(Objects.java:203)
at java.util.stream.ReferencePipeline.filter(ReferencePipeline.java:161)
at Example.main(Example.java:18)
对于Oracle JDK,这似乎只在Java 8中,而不是Java 7。
答案 1 :(得分:3)
对Java进行逆向工程将非常痛苦。从理论上讲,您可以分析原始来源并找出哪些表达式可能引发此类异常。
如果你有这个问题,你的线很可能太复杂/密集。大多数IDE使得重构表达式以提取部分代码变得非常容易。这样可以更好地解决抛出异常的位置。
这个特定问题的另一个解决方案是使用@NotNull的方法,IDE可以检测哪些参数可以为null,但绝不应该是。
URI uri = uriInfo.getBaseUriBuilder().path(objectA)
.path(/*highlighted*/objectB).build();
IDE可以警告您,您正在将变量传递给无法使用null
的方法。如果您这样做,您将更早地获取这些错误并使其更容易修复。 (IDE附带了一些快速修复程序)
注意:一般来说,错误传递的null
参数API应该抛出NullPointerException IMHO,但是IllegalArgumentException通常会引起一些不一致的抛出。
正如我所看到的,IllegalArgumentException的一个参数是;
null
的处理应与其他不正确的参数相同,例如长度为-1 IMHO将null
传递给不接受null
的方法是编程错误,而不是提供错误输入的问题。
答案 2 :(得分:3)
您无法从堆栈跟踪中获取列。
你可以做的是使用中间变量,这样你就可以在不同的行上调用每个方法:
UriBuilder builder = uriInfo.getBaseUriBuilder();
builder = builder.path(objectA);
builder = builder.path(objectB);
URI uri = builder.build();
这很痛苦,但它可以暂时帮助找到问题,然后你可以把它恢复原状。