Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to declare a final String inside a constructor with an if-statement?

I used to declare a final String inside a constructor. Now I want to insert an if-statement in order to declare it differently if needed.

I used to do:

public Config(){
    final String path = "<path>";
    doSomething(path);
}

Now I'm trying

public Config(String mode){
    if (mode = "1") {
        final String path = "<path1>";
    } else {
        final String path = "<path2>";
    }
    doSomething(path);
}

Unfortunately path cannot be found now (cannot find symbol error) and I'm really lost with my research understanding this. The following works though, I just cannot explain... I must have a deep miss conception about something here.

public Config(String mode){
    final String path;
    if (mode = "1") {
        path = "<path1>";
    } else {
        path = "<path2>";
    }
    doSomething(path);
}

Can you explain me what is going on here, what should I read about to get this.

like image 738
programmar Avatar asked May 03 '19 08:05

programmar


People also ask

Can you put IF statement in constructor?

You can do this but It is not a good idea to write your business logic in constructor. The main purpose of the constructor is to initialize local variables when new instance of your class is created.

Can we declare final variable in constructor?

No, a constructor can't be made final. A final method cannot be overridden by any subclasses.

Can we declare string as final?

In Java, we know that String objects are immutable means we can't change anything to the existing String objects. final means that you can't change the object's reference to point to another reference or another object, but you can still mutate its state (using setter methods e.g).

Can we initialize final variable in parameterized constructor?

If final variable is initialized in parameterized constructor and data is assigned through constructor args then final value seems to be changing here for every object.


3 Answers

Can you explain me what is going on here,

Snippet 2: path declared in the scope of the if statement. It's not accessible outside that if.

Snippet 3: path declared in the scope of the constructor. It's accessible within that constructor.

what should I read about to get this.

The JLS, of course: https://docs.oracle.com/javase/specs/jls/se12/html/jls-6.html#jls-6.3 It's quite complicated, find the right part, read it thoughtfully and go with

doSomething("1".equals(mode) ? "<path1>" : "<path2>");
like image 164
Andrew Tobilko Avatar answered Sep 22 '22 09:09

Andrew Tobilko


The scope of any final variable lies within its code block. It is not visible outside this block. See this thread for why scope of final is defined this way: Scope of final local variable in java

like image 33
harshrd Avatar answered Sep 22 '22 09:09

harshrd


Thing is:

public Config(){
    final String path = "<path>";
    doSomething(path);
}

doesn't make any sense. doSomething() can not alter the String object you are passing to it anyway.

Your whole idea to use final like that is simply flawed. String objects are immutable, and that method receives a reference to such a String object. So even if you have

void doSomething(String whatever) {
  whatever = "in your face";
  ... 
}

Your path reference will still be the same after that call.

From that point of view, in your first example, you could (should for readability) go with doSomething("<path>");

Beyond that, the real answer here is: you seem to have misconceptions about proper usages of the final keyword. There is no point in declaring a variable final when it is used only once afterwards, like in your examples. Having a local variable final only prevents that this variable gets re-assigned within its scope. You are only reading the variable once, thus using final doesn't add anything useful to your code.

like image 25
GhostCat Avatar answered Sep 23 '22 09:09

GhostCat