Initialization of local variables - java

What's the difference between the declaring an uninitialized final variable and setting a final variable to null?
void A(String pizza) {
String retVal = null;
if (StringUtils.isBlank(pizza)) {
retVal = "blank"
} else {
retVal = computeString(pizza);
}
}
void A(String pizza) {
final String retVal;
if(StringUtils.isBlank(pizza)) {
retVal = "blank"
} else {
retVal = computeString(pizza);
}
}

Maybe I didn't understand, but in your second example, you won't be able to reassign retVal after your if-else block. A final variable
may only be assigned to once. Declaring a variable final can serve as
useful documentation that its value will not change and can help avoid
programming errors.
If you had set your final variable to null, you would not be able to reassign it in the if block.

If you set a final variable to null you'll never be able to assign anything else to it...
A final variable (itself) can never change.

The difference is that a final variable can never be changed to have another value.

In this one, the retVal = null accomplishes nothing. You give it a value of null. You never have code that uses that value. Then you give it another value, depending on whether you do the if-then or the else part.
In code that falls where I've added the comment, you can use or change the value of retVal.
void A(String pizza) {
String retVal = null;
... code in here could use it or give it a new value ...
if(StringUtils.isBlank(pizza) {
retVal = "blank"
} else {
retVal = computeString(pizza);
}
... additional code here might change it (and can use it's value) ...
}
In this one, you are required to give retVal a value everytime the method is called. Your if-then-else code does that. The value can never be changed after it is given a value.
One difference is that the compiler would tell you if you used retVal before giving it a value. It would, reasonably, tell you that the variable has no value yet.
void A(String pizza) {
final String retVal;
... code in here cannot use it or give it a value, too ...
if(StringUtils.isBlank(pizza) {
retVal = "blank"
} else {
retVal = computeString(pizza);
}
... additional code here cannot change it but can use it's value ...
}

final means:
You have to assign something (even if it's null)
You can't change the reference to anything else afterwards (but you can, of course, modify
the referenced object).
The meaning is highly semantic, and makes sure you won't accidentally forget to care about what to assign, and you can code with the guarantee that the value is not accidentally changed.
Omitting this modifier just removes that guarantee, nothing else.

Related

How do I use return statements from a method as a parameter to another method?

I'm using a class variable, which I assigned a value in a method return. When I'm trying to use the return value as a parameter for another method it gives an error unless I declare the return statements again, which means I'd be creating a new local variable I'm guessing, and not using the class variable. So is it possible to use the return value, instead of ending up declaring a new variable.
I'm just asking whether it's possible. If it is, then there's probably something else wrong with my code.
When you have method returnOne do this:
public int returnOne() {
return 1;
}
And you have another method isOne like this:
public boolean isOne(int number) {
return (number == 1)
}
You can use the result of returnOne in isOne as a parameter like this:
boolean result = isOne(returnOne());
Hope this helps!

Assigning local variables inside a lambda expression

I'm trying to learn and understand the use of lambda expressions in Java.
I have written a function within a class that returns a boolean result based on an Optional value using a lambda expression.
private boolean isNullOrEmpty(Optional<String> value) {
boolean result;
value.ifPresent(v -> result = isEmptyOrWhitespace(v));
return result;
}
isEmptyOrWhitespace is a simple function I've defined elsewhere to check if a string is null or has only whitespace:
private boolean isEmptyOrWhitespace(String value) {
return value == null || value.trim().isEmpty();
The issue is, I cannot compile this because the compiler says
variable used in lambda should be final or effectively final
For the result variable. I have seen Java: Assign a variable within lambda with a similar problem but there the problem involved String and the solution was to set it to null beforehand.
I feel I'm close. How can I fix this?
The problem is that result is not effectively final as there are more than one assignments to it.
You can use Optional.map
private boolean isNullOrEmpty(Optional<String> value) {
return value.map(v -> isEmptyOrWhitespace(v)) //Or can use a Method reference as mentioned by Bohemian#
.orElse(false);
}
Option A - Rewrite the code:
private boolean isNullOrEmpty(Optional<String> value) {
return value.map(MyClass::isEmptyOrWhitespace).orElse(false);
}
Option B - Circumvent the "effectively final" restriction:
private boolean isNullOrEmpty(Optional<String> value) {
boolean[] result = {false};
value.ifPresent(v -> result[0] = isEmptyOrWhitespace(v));
return result[0];
}
The reference to the array is final, its contents need not be.
You can use filter with isPresent:
value.filter(x-> isEmptyOrWhitespace(x)).isPresent()

Making a variable unchangeable once stored

EDIT-
Sorry I may have been unclear in what im asking, the code works in finding the maximum. But once its stored how would I set the variable so If I wanted to change it in the future I can't
First: Declare your final variable without an initial value.
Second: Use a temporary variable to compute the unique value.
Last: Load the temporary value into your final variable.
If it is an instance variable, you'll have to do this computation into every constructor.
Update
class MyClass
{
private final int patientID;
public MyClass()
{
int temp = IDCount;
for (int i=0; PatientInfo.contains(temp) && i < 9999999;i++){
temp++;
}
this.patientID=temp;
}
}
As you initialise the value to zero you check if it is zero and if so it can be updated.
if (patientId == 0) patientId = IDCount +1;
Of course to make this more robust, the patientId should be a private field in another class and the setting should be done in a setter with the above logic.
On a further note, if you are simply want to get use the maximum value, consider using Math.max
You can create somewhere (probably in the PatientInfo class) a static field representing the current maximum PatientID.
Then just assign that number+1 to the newly created Patient and change the maximum.
The thing you want to seems to be pointless. I think you might just want to implement unique constraint on the specified attribute. But if you really want an "once mutable int", you got it:
class CustomInt {
private Integer val;
public void setVal(int val) throws Exception{
if(val != null)
throw new Exception("cannot reassign");
this.val = val;
}
}
But as I marked, it is pointless.

How can I make a method return a "variable" (not value)?

I have a set of global double variables called softPrice0 (and 1, 2, 3)
The thing is I had the idea to use a method like this:
SOMEWORD getOPrice() //I tried double, String, Object, variable, etc
{return softPrice0;}
So I can use it later like this:
getOPrice()=5.8;
I know that using an array would do the trick but I would like to know if I can make methods throw variable names to use it as I explained.
thanks ortang
This is how I made it, the approach changed though.
setOPrice(Double.parseDouble(txtPriceDolar.getText())); //thats the call
void setOPrice(double value) { //this is the setter, no need of getter
switch(combobox.getSelectedIndex())
{case 1: this.softPrice0 = value; break;
case 2: this.softPrice1 = value; break;
case 3: this.softPrice2 = value; break;
default: this.softPrice3 = value; break;}}
now looks more simple, Thanks to everybody. Asking the wrong questions teaches a lot.
For setting you can not use the getter as you want to. getOPrecio()=5.8; will not work. You have to use a setter method. Take a look at the following sample, to access the value you have to use the getter(read) or setter(write).
You would want to use something like setOPrecio(5.8).
public class DoubleHolder {
private double vaule;
public double getValue() {
return value;
}
public void setValue(double value) {
this.value = value
}
}
Java passes by value, so this isn't possible without a separate getter and setter.
Examples:
void setOPrecio(double softPrecio0) {
this.softPrecio0 = softPrecio0;
}
double getOPrecio() {
return softPrecio0;
}
However, if the value is a class, you may be looking for something along the lines of the singleton pattern.
public class Singleton {
private static final Singleton INSTANCE = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return INSTANCE;
}
}
Singleton example code from Wikipedia's article.
Java has no way of passing or returning a "variable".
The closest you are going to get are:
passing or returning an object whose fields are the "variables", or
passing or returning an array whose elements could be viewed as "variables".
And to be clear, neither of the contrivances are close to passing or returning a bare variable.
You need to rethink your problem / solution in terms of the constructs that Java does provide.

Java: Catch uninitialized variable

Suppose we have a case where a variable is declared in certain conditions:
if (x = 1)
boolean z = true;
Later on, we'd like to test if the variable z exists with try-catch. Is this possible and if so, what exception should we catch?
try {
if (z)
//do smth
} catch (<exception?> ex) {
//do smth_else
}
Of course it would be possible to declare z before and change it's value accordingly in if block, but just hypothetically, is the above possible in Java?
Python for example has NameError that will be raised when accessed local or global variable is not declared.
Thanks!
HSI.
What if you declared your variable like this:
Boolean x = null;
In that case you could check for it being null or not.
An even better alternative would be using an enum to represent the uninitialized value:
public enum MyEnum {
UNINITIALIZED, TRUE, FALSE;
}
because if you will try to maintain your code several months later you (or someone else) may be puzzled about the Boolean being null.
we'll get compilation error if the variable we are using is not declared or is not visible in current scope.
If it is declared we can check for NullPointerException if that was object. In case of primitive data types we should check for default values.
Suppose we have a case where a variable is declared in certain conditions:
Well it is difficult to assume because that would not compile:
you should use == to test for equality
you can't declare a variable in an if statement unless there is a block
Now assuming you enclose that declaration inside a block, the scope of that variable would be that block and you wouldn't be able to use it in your try / catch block (unless it is inside the if block of course, but I don't think that's what you want).
No, this is not possible in Java. You have to have the variable declared before you can refer to it, otherwise you will get a compilation error.
Boolean z = null;
if (x = 1){
z = true;
}
if(z == null){
//not initialized
}else{
//initialized
}
it's not possible, Java is a strongly typed programming language because every variable must be declared with a data type before it can be used.
int x = 1;
boolean z = null;
if (x == 1)
z = true;
try {
if (z)
//do smth
} catch (NullPointerException npe ) {
//do smth_else
}
So far I understand , you wont be able to compile this piece of code. I can not remember any exception class but what I think is even if you "Invent" exception for this type of error. It won't compile. Because default values of primitive types are assigned to uninitialized class variables called fields but for variable used in method body, it gives compile time error

Categories