Local variables before return statements, does it matter?

后端 未结 3 773
遇见更好的自我
遇见更好的自我 2020-12-02 19:20

Sorry if this is a newbie question but I couldn\'t find an answer for this. Is it better to do this:

int result = number/number2;
return result;
相关标签:
3条回答
  • 2020-12-02 19:38

    Edit: if, like me, you've been using more Kotlin than Java, it'd also be relevant to know that IntelliJ also has an inspection for this in Kotlin:

    Variable used only in following return and should be inlined

    This inspection reports local variables either used only in the very next return statement or exact copies of other variables. In both cases it's better to inline such a variable.


    There is actually a SonarQube rule inherited from PMD called Unnecessary Local Before Return that talks about this. It says:

    Avoid unnecessarily creating local variables.

    This rule was later replaced by SSLR rule Variables should not be declared and then immediately returned or thrown, which maintains the same position:

    Declaring a variable only to immediately return or throw it is a bad practice. Some developers argue that the practice improves code readability, because it enables them to explicitly name what is being returned. However, this variable is an internal implementation detail that is not exposed to the callers of the method. The method name should be sufficient for callers to know exactly what will be returned.

    And I totally agree with it.

    IntelliJ (or at least Android Studio) also has a warning for this situation:

    Variable used only in following return and can be inlined

    This inspection reports local variables either used only in the very next return or exact copies of other variables. In both cases it's better to inline such a variable.


    I don't think performance is something to worry about at all in this situation. That being said, as @Clashsoft mentioned in his comment, the JIT will most likely inline the variable and you'll end up with the same result either way.

    0 讨论(0)
  • 2020-12-02 19:40

    Choose the version that you think is more readable.

    There are legitimate cases where the named variable improves readability. For example

    public String encrypt(String plainString)
    {
        byte[] plainBytes      = plainString.getBytes(StandardCharsets.UTF_8);
        byte[] hashPlainBytes  = enhash( plainBytes, 4 );
        byte[] encryptedBytes  = doAes128(Cipher.ENCRYPT_MODE , hashPlainBytes );
        String encryptedBase64 = Base64.getEncoder().withoutPadding().encodeToString(encryptedBytes);
        return encryptedBase64;
    }
    
    public String decrypt(String encryptedBase64)
    {
        byte[] encryptedBytes = Base64.getDecoder().decode(encryptedBase64);
        byte[] hashPlainBytes = doAes128(Cipher.DECRYPT_MODE , encryptedBytes );
        byte[] plainBytes     = dehash( hashPlainBytes, 4 );
        String plainString = new String(plainBytes, StandardCharsets.UTF_8);
        return plainString;
    }
    

    There are also cases where we need a variable in a different type from the return type. This affects type conversion and inference, making a significant semantic difference.

    Foo foo()            vs.        Foo foo()
    {                               {
                                        Bar bar = expr;
        return expr;                    return bar;
    }                               }
    
    0 讨论(0)
  • 2020-12-02 19:45

    Compilers are usually smart enough to optimize this sort of thing as appropriate. See data-flow optimizations on Wikipedia.

    In this case, it will probably need to allocate a temporary variable to store the result even if you don't specify one yourself.

    Edit: Clashsoft is right about the bytecode compiler:

    $ cat a.java
    class a {
       public static int a(int x, int y) {
         return x / y;
       }
    
       public static int b(int x, int y) {
         int r = x/y;
         return r;
       }
    
       public static int c(int x, int y) {
         final int r = x/y;
         return r;
       }
    }
    $ javap -c a
    Compiled from "a.java"
    class a {
      a();
        Code:
           0: aload_0
           1: invokespecial #1                  // Method java/lang/Object."<init>":()V
           4: return
    
      public static int a(int, int);
        Code:
           0: iload_0
           1: iload_1
           2: idiv
           3: ireturn
    
      public static int b(int, int);
        Code:
           0: iload_0
           1: iload_1
           2: idiv
           3: istore_2
           4: iload_2
           5: ireturn
    
      public static int c(int, int);
        Code:
           0: iload_0
           1: iload_1
           2: idiv
           3: istore_2
           4: iload_2
           5: ireturn
    }
    
    0 讨论(0)
提交回复
热议问题