String constant vs variable in a Java method - java

Unchangeable, constant values should be stored in constants rather than variables for both safer and cleaner code.
The latter doesn't apply to all cases of unchangeable values though: There's the following method that is only called once, on initialising the app that uses the same value of a String twice. The String is only referenced and used inside the method.
My question is: What's the best way of variable/constant definition? Being a simple String in a large application, performance and memory can be neglected, it's more about readability and maintenance.
Is it as variable inside the method:
protected void init() {
final String thestring = "thevalue";
methodA(thestring);
methodB(thestring);
}
or is it as constant on class level (although only used in the method):
private static final String THESTRING = "thevalue";
protected void init() {
methodA(THESTRING);
methodB(THESTRING);
}
or a third, better solution? Please also take into consideration that there can be more, similar methods in the same class.

For me the best solution is to use variable inside the method - because it's internal variable. So other methods shouldn't see it. Consider the encapsulation and clean code, when you try to move this variable on class level you will get a long list of class variables.
Another thing is memory. After method is executed the variables are destroyed. When you define it as a static it will be in your memory all the time.

I can think of three places to put your variable (all final ofc), each has it advantages and disadvantages.
Local variable.
Private static field inside your class.
Public static field inside some Properties class.
1 - Advantages: variable can only be seen inside your method - high code safety. Disadvatages: variable is buried inside a method, can be difficult to find and change.
(I'll skip 2 because it is just compromise between 1 and 3)
3 - Advantages: your field is among other configurable fields, that makes it easy to change your setting. Disadvantages: field is public and everyone can see it (but String is immutable so no one will be able to change it).
Summary: depends on how much you expect you will need to change your variable (e.g. balancing, color changing, ...). If you are sure that this string value is the right one, i wouldn't fear to put that into local variable.

Typically constants are not instance specific. It is thus a better practice to store constants as static variables rather than as member variables. The advantages are:
There is only one allocation of the variable instead of one allocation per object.
You don't need to create an instance variable to access a constant, e.g. PI is declared to be static in the java Math class.

Related

Local variable log defined in an enclosing scope must be final or effectively final

I'm new to lambda and Java8. I'm facing following error.
Local variable log defined in an enclosing scope must be final or
effectively final
public JavaRDD<String> modify(JavaRDD<String> filteredRdd) {
filteredRdd.map(log -> {
placeHolder.forEach(text -> {
//error comes here
log = log.replace(text, ",");
});
return log;
});
return null;
}
The message says exactly what the problem is: your variable log must be final (that is: carry the keyword final) or be effectively final (that is: you only assign a value to it once outside of the lambda). Otherwise, you can't use that variable within your lambda statement.
But of course, that conflicts with your usage of log. The point is: you can't write to something external from within the lambda ... so you have to step back and look for other ways for whatever you intend to do.
In that sense: just believe the compiler.
Beyond that, there is one core point to understand: you can not use a local variable that you can write to. Local variables are "copied" into the context of the lambda at runtime, and in order to achieve deterministic behavior, they can only be read, and should be constants.
If your use case is to write to some object, then it should be a field of your enclosing class for example!
So, long story short:
local variables used (read) inside a lambda must act like a constant
you can not write to local variables!
or the other way round: if you need something to write to, you have to use a field of your surrounding class for example (or provide a call back method)
The reason for this limitation is the same as the reason for the Java language feature that local variables accessed from within (anonymous) inner classes must be (effectively) final.
This answer by rgettman gets into the details of it. rgettman explains the limitations in clear detail and I link to that answer because the behavior of lambda expressions should be same as that of anonymous inner classes. Note that such limitation does not exist for class or instance variables, however. The main reason for this is slightly complicated and I couldn't explain it better than what Roedy Green does it here. Copying here only so it is at one place:
The rule is anonymous inner classes may only access final local
variables of the enclosing method. Why? Because the inner class’s
methods may be invoked later, long after the method that spawned it
has terminated, e.g. by an AWT (Advanced Windowing Toolkit) event. The
local variables are long gone. The anonymous class then must work with
flash frozen copies of just the ones it needs squirreled away covertly
by the compiler in the anonymous inner class object. You might ask,
why do the local variables have to be final? Could not the compiler
just as well take a copy of non-final local variables, much the way it
does for a non-final parameters? If it did so, you would have two
copies of the variable. Each could change independently, much like
caller and callee’s copy of a parameter, however you would use the
same syntax to access either copy. This would be confusing. So Sun
insisted the local be final. This makes irrelevant that there are
actually two copies of it.
The ability for an anonymous class to access the caller’s final local
variables is really just syntactic sugar for automatically passing in
some local variables as extra constructor parameters. The whole thing
smells to me of diluted eau de kludge.
Remember method inner classes can`t modify any value from their surrounding method. Your second lambda expression in forecach is trying to access its surrounding method variable (log).
To solve this you can avoid using lambda in for each and so a simple for each and re-palace all the values in log.
filteredRdd.map(log -> {
for (String text:placeHolder){
log = log.replace(text,",");
}
return log;
});
In some use cases there can be a work around. The following code complains about the startTime variable not being effectively final:
List<Report> reportsBeforeTime = reports.stream()
.filter(r->r.getTime().isAfter(startTime))
.collect(Collectors.toList());
So, just copy the value to a final variable before passing it to lambda:
final LocalTime finalStartTime = startTime;
List<Report> reportsBeforeTime = reports.stream()
.filter(r->r.getTime().isAfter(finalStartTime))
.collect(Collectors.toList());
However, If you need to change a local variable inside a lambda function, that won't work.
If you do not want to create your own object wrapper, you can use AtomicReference, for example:
AtomicReference<String> data = new AtomicReference<>();
Test.lamdaTest(()-> {
//data = ans.get(); <--- can't do this, so we do as below
data.set("to change local variable");
});
return data.get();
One solution is to encapsulate the code in an enclosing (inner class). You can define this:
public abstract class ValueContext<T> {
public T value;
public abstract void run();
}
And then use it like this (example of a String value):
final ValueContext<String> context = new ValueContext<String>(myString) {
#Override
public void run() {
// Your code here; lambda or other enclosing classes that want to work on myString,
// but use 'value' instead of 'myString'
value = doSomethingWithMyString(value);
}};
context.run();
myString = context.value;

Java Strings: private static vs local variable performance

Is there any performance benefit by using a private final static String in java vs using a local string variable that has to get "initialized" every time the method is accessed?
I do think that using private static final strings is a good practice for constants that get reused in different parts of a class, however if a string were to be used only in one method, in one location, for a very specific reason that no other method is concerned about, I actually prefer to keep the class' internal interface clean with less private members, and just use a local variable.
Given that java has String interning, and actually keeps a pool with a single copy of each string that gets declared using quotes (String s = "some string"), would there actually be a performance hit from having to declare / initialize / assign the variable each time the method is accessed vs using a static string?
To make it a bit more clear, would there be any difference between using SS or LS?
class c {
private final static String SS = "myString";
private void method(){
//do something with SS
}
private void OtherMethod(){
String LS = "myOtherString"
//do same thing with LS
}
}
Using a named constant is likely to be better for maintainability. However constants known at compile time can be used as inline in which case there is unlikely to be any difference.
Note: if you are using a String literal, this will be created just once, no matter where in the JVM it is used.
In this case the only difference is using a local variable on the stack which is unlikely to be any more expensive than a constant which have been used as inline.
would there actually be a performance hit from having to declare the variable each time the method is accessed
As Java uses a static compiler, a variable is only declared once (or once for each stage of compilation), when loading the class/method, regardless of how many times the methods is called. The variable might be initialized each time however.
The truth is, at the end, there is no difference. A constant string in a local variable will still end up in the constant pool and optimized. So generally speaking, local variables are faster because they are easier to access, but in the case of constant strings it does not make a difference. So choose whatever is more readable and intuitive in your case.
I guess creating constants comes from old time when creating statics helped in maintaining only one string as part of the class in the jvm, rather than the object which gets created and garbage collected every time the object is created and destroyed. But with spring default scope as singleton rather than prototype, I guess it makes no difference. So, yeah, it depends how the class will be used, is the answer.

Declaring variable as final makes to code more efficient? [duplicate]

I've found a couple of references (for example) that suggest using final as much as possible and I'm wondering how important that is. This is mainly in the the context of method parameters and local variables, not final methods or classes. For constants, it makes obvious sense.
On one hand, the compiler can make some optimizations and it makes the programmer's intent clearer. On the other hand, it adds verbosity and the optimizations may be trivial.
Is it something I should make an effort to remember?
Obsess over:
Final fields - Marking fields as final forces them to be set by end of construction, making that field reference immutable. This allows safe publication of fields and can avoid the need for synchronization on later reads. (Note that for an object reference, only the field reference is immutable - things that object reference refers to can still change and that affects the immutability.)
Final static fields - Although I use enums now for many of the cases where I used to use static final fields.
Consider but use judiciously:
Final classes - Framework/API design is the only case where I consider it.
Final methods - Basically same as final classes. If you're using template method patterns like crazy and marking stuff final, you're probably relying too much on inheritance and not enough on delegation.
Ignore unless feeling anal:
Method parameters and local variables - I RARELY do this largely because I'm lazy and I find it clutters the code. I will fully admit that marking parameters and local variables that I'm not going to modify is "righter". I wish it was the default. But it isn't and I find the code more difficult to understand with finals all over. If I'm in someone else's code, I'm not going to pull them out but if I'm writing new code I won't put them in. One exception is the case where you have to mark something final so you can access it from within an anonymous inner class.
Edit: note that one use case where final local variables are actually very useful as mentioned by #adam-gent is when value gets assigned to the var in the if/else branches.
Is it something I should make an effort to remember to do?
No, if you are using Eclipse, because you can configure a Save Action to automatically add these final modifiers for you. Then you get the benefits for less effort.
I use final all the time to make Java more expression based. See Java's conditions (if,else,switch) are not expression based which I have always hated especially if your used to functional programming (ie ML, Scala or Lisp).
Thus you should try to always (IMHO) use final variables when using conditions.
Let me give you an example:
final String name;
switch(pluginType) {
case CANDIDATE_EXPORT:
name = "Candidate Stuff";
break;
case JOB_POSTING_IMPORT:
name = "Blah";
break;
default:
throw new IllegalStateException();
}
Now If add another case statement and do not set name the compiler will fail. The compiler will also fail if you do not break on every case (that you set the variable). This allows you to make Java very similar to Lisp's let expressions and makes it so your code is not massively indented (because of lexical scoping variables).
And as #Recurse noted (but apparently -1 me) you can do the preceding with out making String name final to get the compiler error (which I never said you couldn't) but you could easily make the compiler error go away setting name after the switch statement which throws away the expression semantics or worse forgetting to break which you cannot cause an error (despite what #Recurse says) without using final:
String name;
switch(pluginType) {
case CANDIDATE_EXPORT:
name = "Candidate Stuff";
//break; whoops forgot break..
//this will cause a compile error for final ;P #Recurse
case JOB_POSTING_IMPORT:
name = "Blah";
break;
}
// code, code, code
// Below is not possible with final
name = "Whoops bug";
Because of the bug setting name (besides forgetting to break which also another bug) I can now accidentally do this:
String name;
switch(pluginType) {
case CANDIDATE_EXPORT:
name = "Candidate Stuff";
break;
//should have handled all the cases for pluginType
}
// code, code, code
// Below is not possible with final
name = "Whoops bug";
The final variable forces a single evaluation of what name should be. Similar to how a function that has a return value must always return a value (ignoring exceptions) the name switch block will have to resolve name and thus bound to that switch block which makes refactoring chunks of code easier (ie Eclipe refactor: extract method).
The above in OCaml:
type plugin = CandidateExport | JobPostingImport
let p = CandidateExport
let name = match p with
| CandidateExport -> "Candidate Stuff"
| JobPostingImport -> "Blah" ;;
The match ... with ... evaluates like a function ie expression. Notice how it looks like our switch statement.
Here is an example in Scheme (Racket or Chicken):
(define name
(match b
['CandidateExport "Candidate Stuff"]
['JobPostingImport "Blah"]))
The development-time benefits of "final" are at least as significant as the run-time benefits. It tells future editors of the code something about your intentions.
Marking a class "final" indicates that you've not made an effort during design or implementation of the class to handle extension gracefully. If the readers can make changes to the class, and want to remove the "final" modifier, they can do so at their own risk. It's up to them to make sure the class will handle extension well.
Marking a variable "final" (and assigning it in the constructor) is useful with dependency injection. It indicates the "collaborator" nature of the variable.
Marking a method "final" is useful in abstract classes. It clearly delineates where the extension points are.
Well, this all depends on your style... if you LIKE seeing the final when you won't be modifying the variable, then use it. If you DON'T LIKE seeing it... then leave it out.
I personally like as little verbosity as possible, so I tend to avoid using extra keywords that aren't really necessary.
I prefer dynamic languages though, so it's probably no surprise I like to avoid verbosity.
So, I would say just pick the direction you are leaning towards and just go with it (whatever the case, try to be consistent).
As a side note, I have worked on projects that both use and don't use such a pattern, and I have seen no difference in the amount of bugs or errors... I don't think it is a pattern that will hugely improve your bug count or anything, but again it is style, and if you like expressing the intent that you won't modify it, then go ahead and use it.
I've found marking method parameters and locals as final is useful as a refactoring aid when the method in question is an incomprehensible mess several pages long. Sprinkle final liberally, see what "cannot assign to final variable" errors the compiler (or your IDE) throws up, and you just might discover why the variable called "data" ends up null even though several (out of date) comments swear that can't happen.
Then you can fix some of the errors by replacing the reused variables with new variables declared closer to the point of use. Then you find you can wrap whole parts of the method in scoping braces, and suddenly you're one IDE keypress away from "Extract Method" and your monster just got more comprehensible.
If your method is not already an unmaintainable wreck, I guess there might be value in making stuff final to discourage people from turning it into said wreck; but if it's a short method (see: not unmaintainable) then you risk adding a lot of verbosity. In particular, Java function signatures are hard enough to fit into 80 characters as it is without adding six more per argument!
It is useful in parameters to avoid change the parameter value by accident and introduce a subtle bug. I use to ignore this recommendation but after spending some 4 hrs. in a horrible method ( with hundreds of lines of code and multiple fors, nested ifs and all sort of bad practices ) I would recommend you to do it.
public int processSomethingCritical( final int x, final int y ){
// hundreds of lines here
// for loop here...
int x2 = 0;
x++; // bug aarrgg...
// hundreds of lines there
// if( x == 0 ) { ...
}
Of course in a perfect world this wouldn't happen, but.. well.. sometimes you have to support others code. :(
If you are writing a application that someone will have to read the code after, say, 1 year, then yes, use final on variable that should not be modified all the time. By doing this, your code will be more "self-documenting" and you also reduce the chance for other developers to do silly things like using a local constant as a local temporary variable.
If you're writing some throwaway code, then, nah, don't bother to identify all the constant and make them final.
I will use final as much as I can. Doing so will flag if you unintentionally change the field. I also set Method parameters to final. Doing so I have caught several bug from code I have taken over when they try to 'set' a parameter forgetting Java passes by value.
It's not clear from the question whether this is obvious, but making a method parameter final affects only the body of the method. It does NOT convey any interesting information about the method's intentions to the invoker. The object being passed in can still be mutated within the method (finals are not consts), and the scope of the variable is within the method.
To answer your precise question, I wouldn't bother making an instance or local variable (including method parameters) final unless the code required it (e.g. the variable is referenced from an inner class), or to clarify some really complicated logic.
For instance variables, I would make them final if they are logically constants.
There are many uses for the variable final. Here are just a few
Final Constants
public static class CircleToolsBetter {
public final static double PI = 3.141;
public double getCircleArea(final double radius) {
return (Math.pow(radius, 2) * PI);
}
}
This can be used then for other parts of your codes, or accessed by other classes, that way if you would ever change the value you wouldn't have to change them one by one.
Final Variables
public static String someMethod(final String environmentKey) {
final String key = "env." + environmentKey;
System.out.println("Key is: " + key);
return (System.getProperty(key));
}
}
In this class, you build a scoped final variable that adds a prefix to the parameter environmentKey. In this case, the final variable is final only within the execution scope, which is different at each execution of the method. Each time the method is entered, the final is reconstructed. As soon as it is constructed, it cannot be changed during the scope of the method execution. This allows you to fix a variable in a method for the duration of the method. see below:
public class FinalVariables {
public final static void main(final String[] args) {
System.out.println("Note how the key variable is changed.");
someMethod("JAVA_HOME");
someMethod("ANT_HOME");
}
}
Final Constants
public double equation2Better(final double inputValue) {
final double K = 1.414;
final double X = 45.0;
double result = (((Math.pow(inputValue, 3.0d) * K) + X) * M);
double powInputValue = 0;
if (result > 360) {
powInputValue = X * Math.sin(result);
} else {
inputValue = K * Math.sin(result); // <= Compiler error
}
These are especially useful when you have really long lines of codes, and it will generate compiler error so you don't run in to logic/business error when someone accidentally changes variables that shouldn't be changed.
Final Collections
Different case when we are talking about Collections, you need to set them as an unmodifiable.
public final static Set VALID_COLORS;
static {
Set temp = new HashSet( );
temp.add(Color.red);
temp.add(Color.orange);
temp.add(Color.yellow);
temp.add(Color.green);
temp.add(Color.blue);
temp.add(Color.decode("#4B0082")); // indigo
temp.add(Color.decode("#8A2BE2")); // violet
VALID_COLORS = Collections.unmodifiableSet(temp);
}
otherwise, if you don't set it as unmodifiable:
Set colors = Rainbow.VALID_COLORS;
colors.add(Color.black); // <= logic error but allowed by compiler
Final Classes and Final Methods cannot be extended or overwritten respectively.
EDIT:TO ADDRESS THE FINAL CLASS PROBLEM REGARDING ENCAPSULATION:
There are two ways to make a class final. The first is to use the keyword final in the class declaration:
public final class SomeClass {
// . . . Class contents
}
The second way to make a class final is to declare all of its constructors as private:
public class SomeClass {
public final static SOME_INSTANCE = new SomeClass(5);
private SomeClass(final int value) {
}
Marking it final saves you the trouble if finding out that it is actual a final, to demonstrate look at this Test class. looks public at first glance.
public class Test{
private Test(Class beanClass, Class stopClass, int flags)
throws Exception{
// . . . snip . . .
}
}
Unfortunately, since the only constructor of the class is private, it is impossible to extend this class. In the case of the Test class, there is no reason that the class should be final. The Test class is a good example of how implicit final classes can cause problems.
So you should mark it final when you implicitly make a class final by making it's constructor private.
Somewhat of a trade-off as you mention, but I prefer explicit use of something over implicit use. This will help remove some ambiguity for future maintainers of code - even if it is just you.
If you have inner (anonymous) classes, and the method needs to access variable of the containing method, you need to have that variable as final.
Other than that, what you've said is right.
Use final keyword for a variable if you are making that variable as immutable
By declaring the variable as final, it aids developers to rule out possible modification issues of variables in highly multi-threaded environment.
With java 8 release, we have one more concept called "effectively final variable". A non-final variable can heave as final variable.
local variables referenced from a lambda expression must be final or effectively final
A variable is considered effective final if it is not modified after initialization in the local block. This means you can now use the local variable without final keyword inside an anonymous class or lambda expression, provided they must be effectively final.
Till Java 7, you cannot use a non-final local variable inside an anonymous class, but from Java 8 you can
Have a look at this article
First of all, the final keyword is used to make a variable constant. Constant means it does not change. For example:
final int CM_PER_INCH = 2.54;
You would declare the variable final because a centimeter per inch does not change.
If you try to override a final value, the variable is what it was declared first. For example:
final String helloworld = "Hello World";
helloworld = "A String"; //helloworld still equals "Hello World"
There is a compile error that is something like:
local variable is accessed from inner class, must be declared final
If your variable cannot be declared final or if you don't want to declare it final try this:
final String[] helloworld = new String[1];
helloworld[0] = "Hello World!";
System.out.println(helloworld[0]);
helloworld[0] = "A String";
System.out.println(helloworld[0]);
This will print:
Hello World!
A String

Making final class variables static in GWT

In Java when a final field is assigned a constant value compile-time, it usually makes sense declaring it static. It saves overhead according to the relevant PMD rule.
Does it make any sense or difference doing it in GWT regarding the generated Javascript code?
If the variable is assigned when it is declared final, then yes, static makes a certain amount of sense, but there are cases where it should not be static:
public MyClassWithFinal {
private final String finalVar;
public MyClassWithFinal(String name) {
this.finalVar = name;
}
}
Another case: If the instance var is not a string or number constant, but requires running a constructor, that constructor may have side effects each time it is invoked, so running it only once is different than running it multiple times.
That said, GWT will inline/intern constant string values, so if you have multiple String fields all assigned to the same value, GWT will probably detect that and promote them all to static.
public final String constant = "Some Constant that really ought to be static";
GWT will notice that this is never assigned except when declared, and may even remove the field itself.
The best rule is to start with the best (i.e. most readable, most maintainable, most efficient) Java code, and to only break from that in cases where GWT requires something specific. This is not one of those cases: the compiler should perform the same basic optimizations no matter how you write this.
A field marked as final doesn't mean that it is immutable, only that its reference won't point to any other memory chunk. Therefore, it can only make sense to make a field static if it is really immutable, or if it is a primitive.
For instance, it's common to declare lists as final if you want to make sure that they will never point to a different list object, but the list itself can still be filled with data, cleared, filled again, etc. And of course, each object declaring such list does not mandatory want to share it among every instances.
private final List<...> list = new ArrayList<...>();
Final keyword is there to prevent you from doing mistakes, like setting to null a reference that should never change.

Java Variables Conventions

I'm confused with variable declarations in Java code.
I read... don't try to use global variables declarations .
Don't use something like this:
package cls;
public class test {
private String var;
public someMethod(){ ... }
}
And use ?
package cls;
public class test {
public someMethod(){
String var = null;
}
}
I don't know which is the correct way....
It totally depends on what you need.
Your first example, however, isn't a global variable--it's an instance variable.
Variables should have as small a scope as possible. This makes code easier to reason about.
Instance variables are central to what OOP is all about--classes (objects) exist to encapsulate object state, and the methods that operate on that state. For example, a Person class would likely have first and last name instance variables:
public class Person {
private String firstName;
private String lastName;
// Plus getters and setters for each.
}
This allows instance methods to access the first and last name variables directly without having to pass them between all the methods that need them.
The second example is a local variable. It's visible only in the method it's declared in. A reference to it may be passed to other methods.
Both are correct. Neither of those are global variables. The first one is a class field. It's unique to each instance of the class that you make. Class fields (ie. variable) stay with the instance of the class until the class itself is deleted.
The second one is a method scope variable. It's only there for temporary purposes to perform the calculations needed for the method to work, and once the code in the method is done, the variable goes away.
You use each for different purposes. For example, if you're writing a Car class, you'd probably have a class field for SteeringWheel and Brake. But if you had a method to calculate the average miles per gallon, you might create a method scoped variable to help perform the calculation.
Java doesn't have global variables. The first variable is class level and maintains the state of class instances and hence exists as long as an instance of the class while the second is a method's local variable that exists only during method's execution. You can use the first variable to store state information that spans multiple method calls. The second variable disappears as soon as the control leaves the method. Also, every time you call the method another variable, accessible by the same local name is created on the stack.
You can't have truly "global" variables in Java the same way as you can in a language such as C. Java forces you to structure your program in an object oriented way.
In your example above, if var is required throughout a whole test object and is important to have stored, then you would use the first example. If var is only required in someMethod and it's not important for a test object to store it then use the second example.
Take note that even with the first example, var is encapsulated within a test object, so it's not really "global" at all, apart from maybe slightly to the member function of test (which is the whole point of instance/member variables).
The closest thing in Java to "global" data is something like:
public class GlobalVars {
public static int globalInt;
}
And you could access globalInt throughout your code as GlobalVars.globalInt, without creating an instance of GlobalVars.

Categories