Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can you assign a variable a value inside a if statement in Java

Tags:

java

I need to do something like this,

if (first_var > second_var)
  int difference = first_var - second_var;
if (first_var < second_var)
  int difference = second_var - first_var;

When I try to compile this, an error comes stating the variable 'difference' may not have been initialized. Making the variable 'difference' global doesn't help either.

like image 757
Dananjaya Avatar asked Aug 29 '10 10:08

Dananjaya


2 Answers

The issues that you need to learn are:

  • The scope of variables
  • Block declaration and how that creates new scopes
  • Why you should prefer to use {...} block for if statements
  • How to guarantee definite assignment
  • When to use if-else instead of if (something) {...} if (!something) {...}

By the way, the idiomatic way to find the difference of two values is:

int difference = Math.abs(firstVar - secondVar);

Do note that Math.abs has a corner case: when the argument is Integer.MIN_VALUE, the returned value is Integer.MIN_VALUE. That's because -Integer.MIN_VALUE == Integer.MIN_VALUE. The issue here is 32-bit two's complement representation of numbers.

References

  • JLS 16 Definite Assignment
  • JLS 14.4.2 Scope of Local Variable Declarations
  • JLS 14.9.2 The if-then-else Statement
  • Math.abs(int)
  • Wikipedia/Two's complement (read: the most negative number)

Attempt #1: Declaring before the if

Here's one attempt to fix the snippet, by declaring the variable before the if

int difference;
if (first_var > second_var) {
  difference = first_var - second_var;
}
if (first_var < second_var) {
  difference = second_var - first_var;
}

// note: difference is not definitely assigned here!
//           (but at least it's in scope!)

We now have a problem with definite assignment: if first_var == second_var, the variable difference is still not assigned a value.


Attempt #2: Initializing at declaration

Here's a second attempt:

int difference = 0;
if (first_var > second_var) {
  difference = first_var - second_var;
}
if (first_var < second_var) {
  difference = second_var - first_var;
}

// note: difference is in scope here, and definitely assigned

Beginners tend to do this, but this precludes the possibility of making difference a final local variable, because it's possibly assigned value twice.


Attempt #3: if-else

Here's a better attempt:

final int difference;
if (first_var > second_var) {
  difference = first_var - second_var;
} else {
  difference = second_var - first_var;
}

// note: difference is in scope, and is definitely assigned here,
//       (and declared final)

There are still ways to improve on this.


Attempt #4: The ternary/conditional operator

Once you're more comfortable with the language and programming, you may use the following idiom:

final int difference = (first_var > second_var) ? first_var - second_var
                                                : second_var - first_var;

This uses the ?: ternary/conditional operator. Do be careful with this operator; it has some behaviors that may be surprising, and it definitely can be abused. Use carefully, judiciously, idiomatically.

References

  • JLS 15.25 Conditional Operator ?:
like image 141
polygenelubricants Avatar answered Oct 15 '22 23:10

polygenelubricants


You have two options:

  1. Do the condition on one line using the ternary operator ?:

    int difference = first_var > second_var ? first_var - second_var : second_var - first_var;
    
  2. Declare the variable up front, then do the condition.

    int difference = 0;
    if (first_var > second_var)
      difference = first_var - second_var;
    if (first_var < second_var)
      difference = second_var - first_var;
    
like image 21
Peter Alexander Avatar answered Oct 16 '22 00:10

Peter Alexander