Java 声纳;“对局部变量的无效赋值”;解决办法?

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())) {

我正在努力改进我的代码,我在Sonar中遇到了这个问题:

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
    赋值给它。