Java 声纳;“对局部变量的无效赋值”;解决办法?
我正在努力改进我的代码,我在Sonar中遇到了这个问题:Java 声纳;“对局部变量的无效赋值”;解决办法?,java,null,sonarqube,sonar-runner,Java,Null,Sonarqube,Sonar Runner,我正在努力改进我的代码,我在Sonar中遇到了这个问题: Remove this useless assignment to local variable "uiRequest" 事实上,它并不是无用的,因为我在代码中刚刚使用它: // I am supposed to remove this UiRequest uiRequest = null; if("Party".equals(vauban.getName())) {
Remove this useless assignment to local variable "uiRequest"
事实上,它并不是无用的,因为我在代码中刚刚使用它:
// I am supposed to remove this
UiRequest uiRequest = null;
if("Party".equals(vauban.getName())) {
uiRequest = contextBuilder.buildContext(vauban);
} else {
// Maybe I could work my way around here ?
throw new NamingException(
String.format(
"Hey %s, change your name to %s, thanks",
vauban.getName(), "Vauban"));
}
// Set the generated Id in the result of context builder
MyOwnService response = callService(uiRequest, vauban);
return response;
声纳仍然告诉我“uiRequest”是无用的,为什么?它不是,因为如果它为null,我不希望它到达代码。我尝试初始化它(uiRequest=newuirequest()
),但它一直告诉我它没有用
有人知道为什么Sonar会这样/如何纠正吗?把它移到if语句中怎么样
if("Party".equals(vauban.getName())) {
UiRequest uiRequest = contextBuilder.buildContext(vauban);
// Set the generated Id in the result of context builder
MyOwnService response = callService(uiRequest, vauban);
return response;
} else {
throw new NamingException(
String.format(
"Hey %s, change your name to %s, thanks",
vauban.getName(), "Vauban"));
}
或者在if语句中抛出exception,而不使用else子句。i、 让正常情况成为“快乐路径”把它移到if语句中怎么样
if("Party".equals(vauban.getName())) {
UiRequest uiRequest = contextBuilder.buildContext(vauban);
// Set the generated Id in the result of context builder
MyOwnService response = callService(uiRequest, vauban);
return response;
} else {
throw new NamingException(
String.format(
"Hey %s, change your name to %s, thanks",
vauban.getName(), "Vauban"));
}
或者在if语句中抛出exception,而不使用else子句。i、 e让正常情况为“快乐路径”。赋值是无用的,因为没有代码可能看到赋值 赋值是无用的,因为没有代码可能看到该赋值 您可以通过以下方式避免警告,并可能使代码可读性稍高一些:
// I am supposed to remove this
// UiRequest uiRequest = null; <-- remove
// invert the test here
if(! "Party".equals(vauban.getName())) {
// Maybe I could work my way around here ?
throw new NamingException(
String.format(
"Hey %s, change your name to %s, thanks",
vauban.getName(), "Vauban"));
}
// you are only using the variable in the call service; make
// final since reference should not change after assignment
final UiRequest uiRequest = contextBuilder.buildContext(vauban);
// Set the generated Id in the result of context builder
MyOwnService response = callService(uiRequest, vauban);
return response;
//我应该删除这个
//UiRequest UiRequest=null 您可以通过以下方式避免警告,并可能使代码可读性稍高:
// I am supposed to remove this
// UiRequest uiRequest = null; <-- remove
// invert the test here
if(! "Party".equals(vauban.getName())) {
// Maybe I could work my way around here ?
throw new NamingException(
String.format(
"Hey %s, change your name to %s, thanks",
vauban.getName(), "Vauban"));
}
// you are only using the variable in the call service; make
// final since reference should not change after assignment
final UiRequest uiRequest = contextBuilder.buildContext(vauban);
// Set the generated Id in the result of context builder
MyOwnService response = callService(uiRequest, vauban);
return response;
//我应该删除这个
//UiRequest UiRequest=null 您的问题简化为:
Foo x = null;
if(a()) {
x = b();
} else {
throw new Exception();
}
c(x);
通过此代码有两种可能的路径:
a()
返回true
x
被赋值b()
然后调用c(x)
a()
返回false
。将引发异常,并且不会调用c(x)
这两条路径都没有使用null
的初始赋值调用c(x)
。所以,无论你一开始分配什么,都是多余的
请注意,如果初始赋值不是null,这也会是一个问题。除非作业的右侧有副作用,否则任何作业都是浪费的。(副作用的声纳分析)
这对声纳来说是可疑的:
- 也许程序员期望第一个任务会有效果——它没有,所以可能是个bug李>
- 这也是关于代码的清晰性——未来的人类代码读者可能会浪费时间想知道初始值的用途
- 如果右侧包含计算,但没有副作用,则会浪费计算
您可以通过两种方式解决此问题:
首先删除=null
,留下Foo x代码>-Java足够聪明,可以意识到所有到c(x)
的路由都涉及一个赋值,所以它仍然可以编译
更好的是,将c(x)
移动到块中:
if(a()) {
Foo x = b();
c(x);
} else {
throw new Exception();
}
这在逻辑上是等价的、更整洁的,并且缩小了x
的范围。缩小范围是一件好事。当然,如果您需要在更大的范围内使用x
,您不能这样做
还有一种变体,在逻辑上也是等效的:
if(! a()) {
throw new Exception();
}
Foo x = b();
c(x);
。。。对“提取方法”和“内联”重构的响应良好:
throwForInvalidA(...);
c(b());
使用最能传达您意图的选项。您的问题简化为:
Foo x = null;
if(a()) {
x = b();
} else {
throw new Exception();
}
c(x);
通过此代码有两种可能的路径:
a()
返回true
x
被赋值b()
然后调用c(x)
a()
返回false
。将引发异常,并且不会调用c(x)
这两条路径都没有使用null
的初始赋值调用c(x)
。所以,无论你一开始分配什么,都是多余的
请注意,如果初始赋值不是null,这也会是一个问题。除非作业的右侧有副作用,否则任何作业都是浪费的。(副作用的声纳分析)
这对声纳来说是可疑的:
- 也许程序员期望第一个任务会有效果——它没有,所以可能是个bug李>
- 这也是关于代码的清晰性——未来的人类代码读者可能会浪费时间想知道初始值的用途
- 如果右侧包含计算,但没有副作用,则会浪费计算
您可以通过两种方式解决此问题:
首先删除=null
,留下Foo x代码>-Java足够聪明,可以意识到所有到c(x)
的路由都涉及一个赋值,所以它仍然可以编译
更好的是,将c(x)
移动到块中:
if(a()) {
Foo x = b();
c(x);
} else {
throw new Exception();
}
这在逻辑上是等价的、更整洁的,并且缩小了x
的范围。缩小范围是一件好事。当然,如果您需要在更大的范围内使用x
,您不能这样做
还有一种变体,在逻辑上也是等效的:
if(! a()) {
throw new Exception();
}
Foo x = b();
c(x);
。。。对“提取方法”和“内联”重构的响应良好:
throwForInvalidA(...);
c(b());
使用最能传达您意图的代码。这是绝对无用的,因为如果uiRequest使用null赋值,使用它的代码块callService(uiRequest,vauban)
将永远无法到达。而不是uiRequest
是无用的,但是将null
赋值给它是绝对没有用的,因为如果uiRequest将赋值给null,使用它的代码块callService(uiRequest,vauban)
将永远无法到达。不是uiRequest
没有用,而是将null
赋值给它。