when exactly are we supposed to use "public static final String"? - java

I have seen much code where people write public static final String mystring = ...
and then just use a value.
Why do they have to do that? Why do they have to initialize the value as final prior to using it?
UPDATE
Ok, thanks all for all your answers, I understand the meaning of those key (public static final). What I dont understand is why people use that even if the constant will be used only in one place and only in the same class. why declaring it? why dont we just use the variable?

final indicates that the value of the variable won't change - in other words, a constant whose value can't be modified after it is declared.
Use public final static String when you want to create a String that:
belongs to the class (static: no instance necessary to use it), that
won't change (final), for instance when you want to define a String constant that will be available to all instances of the class, and to other objects using the class, and that
will be a publicly accessible part of the interface that the class shows the world.
Example:
public final static String MY_CONSTANT = "SomeValue";
// ... in some other code, possibly in another object, use the constant:
if (input.equals(MyClass.MY_CONSTANT)
Similarly:
public static final int ERROR_CODE = 127;
It isn't required to use final, but it keeps a constant from being changed inadvertently during program execution, and serves as an indicator that the variable is a constant.
Even if the constant will only be used - read - in the current class and/or in only one place, it's good practice to declare all constants as final: it's clearer, and during the lifetime of the code the constant may end up being used in more than one place.
Furthermore using final may allow the implementation to perform some optimization, e.g. by inlining an actual value where the constant is used.
Finally note that final will only make truly constant values out of primitive types, String which is immutable, or other immutable types. Applying final to an object (for instance a HashMap) will make the reference immutable, but not the state of the object: for instance data members of the object can be changed, array elements can be changed, and collections can be manipulated and changed.

Static means..You can use it without instantiate of the class or using any object.
final..It is a keyword which is used for make the string constant. You can not change the value of that string. Look at the example below:
public class StringTest {
static final String str = "Hello";
public static void main(String args[]) {
// str = "world"; // gives error
System.out.println(str); // called without the help of an object
System.out.println(StringTest.str);// called with class name
}
}
Thanks

The keyword final means that the value is constant(it cannot be changed). It is analogous to const in C.
And you can treat static as a global variable which has scope. It basically means if you change it for one object it will be changed for all just like a global variable(limited by scope).
Hope it helps.

static means that the object will only be created once, and does not have an instance object containing it. The way you have written is best used when you have something that is common for all objects of the class and will never change. It even could be used without creating an object at all.
Usually it's best to use final when you expect it to be final so that the compiler will enforce that rule and you know for sure. static ensures that you don't waste memory creating many of the same thing if it will be the same value for all objects.

final indicates that the value cannot be changed once set. static allows you to set the value, and that value will be the same for ALL instances of the class which utilize it. Also, you may access the value of a public static string w/o having an instance of a class.

οƒ˜ public makes it accessible across the other classes. You can use it without instantiate of the class or using any object.
οƒ˜ static makes it uniform value across all the class instances.
It ensures that you don't waste memory creating many of the same thing if it will be the same value for all the objects.
οƒ˜ final makes it non-modifiable value. It's a "constant" value which is same across all the class instances and cannot be modified.

You do not have to use final, but the final is making clear to everyone else - including the compiler - that this is a constant, and that's the good practice in it.
Why people doe that even if the constant will be used only in one place and only in the same class: Because in many cases it still makes sense. If you for example know it will be final during program run, but you intend to change the value later and recompile (easier to find), and also might use it more often later-on. It is also informing other programmers about the core values in the program flow at a prominent and combined place.
An aspect the other answers are missing out unfortunately, is that using the combination of public final needs to be done very carefully, especially if other classes or packages will use your class (which can be assumed because it is public).
Here's why:
Because it is declared as final, the compiler will inline this field during compile time into any compilation unit reading this field. So far, so good.
What people tend to forget is, because the field is also declared public, the compiler will also inline this value into any other compile unit. That means other classes using this field.
What are the consequences?
Imagine you have this:
class Foo {
public static final String VERSION = "1.0";
}
class Bar {
public static void main(String[] args) {
System.out.println("I am using version " + Foo.VERSION);
}
}
After compiling and running Bar, you'll get:
I am using version 1.0
Now, you improve Foo and change the version to "1.1".
After recompiling Foo, you run Bar and get this wrong output:
I am using version 1.0
This happens, because VERSION is declared final, so the actual value of it was already in-lined in Bar during the first compile run. As a consequence, to let the example of a public static final ... field propagate properly after actually changing what was declared final (you lied!;), you'd need to recompile every class using it.
I've seen this a couple of times and it is really hard to debug.
If by final you mean a constant that might change in later versions of your program, a better solution would be this:
class Foo {
private static String version = "1.0";
public static final String getVersion() {
return version;
}
}
The performance penalty of this is negligible, since JIT code generator will inline it at run-time.

Usually for defining constants, that you reuse at many places making it single point for change, used within single class or shared across packages. Making a variable final avoid accidental changes.

Why do people use constants in classes instead of a variable?
readability and maintainability,
having some number like 40.023 in your code doesn't say much about what the number represents, so we replace it by a word in capitals like "USER_AGE_YEARS". Later when we look at the code its clear what that number represents.
Why do we not just use a variable? Well we would if we knew the number would change, but if its some number that wont change, like 3.14159.. we make it final.
But what if its not a number like a String? In that case its mostly for maintainability, if you are using a String multiple times in your code, (and it wont be changing at runtime) it is convenient to have it as a final string at the top of the class. That way when you want to change it, there is only one place to change it rather than many.
For example if you have an error message that get printed many times in your code, having final String ERROR_MESSAGE = "Something went bad." is easier to maintain, if you want to change it from "Something went bad." to "It's too late jim he's already dead", you would only need to change that one line, rather than all the places you would use that comment.

public makes it accessible across other classes.
static makes it uniform value across all the class instances.
final makes it non-modifiable value.
So basically it's a "constant" value which is same across all the class instances and which cannot be modified.
With respect to your concern "What I don't understand is why people use that even if the constant will be used only in one place and only in the same class. Why declaring it? Why don't we just use the variable?"
I would say since it is a public field the constant value can also be used elsewhere in some other class using ClassName.value. eg: a class named Math may have PI as final static long value which can be accessed as Math.PI.

It is kind of standard/best practice.
There are already answers listing scenarios, but for your second question:
Why do they have to do that? Why do they have to initialize the value as final prior to using it?
Public constants and fields initialized at declaration should be "static final" rather than merely "final"
These are some of the reasons why it should be like this:
Making a public constant just final as opposed to static final leads to duplicating its value for every instance of the class, uselessly increasing the amount of memory required to execute the application.
Further, when a non-public, final field isn't also static, it implies that different instances can have different values. However, initializing a non-static final field in its declaration forces every instance to have the same value owing to the behavior of the final field.

This is related to the semantics of the code. By naming the value assigning it to a variable that has a meaningful name (even if it is used only at one place) you give it a meaning. When somebody is reading the code that person will know what that value means.
In general is not a good practice to use constant values across the code. Imagine a code full of string, integer, etc. values. After a time nobody will know what those constants are. Also a typo in a value can be a problem when the value is used on more than one place.

I think these are all clear explanations. But, Let me clarify it by giving a java inbuild example.
In java, most would have used System.out.println()
The system is a class and out is a PrintStream class.
So what java says is I will take care of the initialization of the out object(PrintStream) and keep the initialization private to myself in the System class.
public final class System {
public final static PrintStream out = null;
//Some initialization done by system class which cannot be changed as it is final.
}
You just access the println method statically without worrying about its initialization.

Related

final static variables and their use [duplicate]

This question already has answers here:
private final static attribute vs private final attribute
(22 answers)
Closed 8 years ago.
I've created an interface with the following code
final static char RIVER = '~';
final static char PATH = 'Y';
The list will increase (not hundres or even tens but maybe at most 15 symbols)
Originally I was just coding the values directly into the object but I started wondering why I couldn't just create a single file with the global constansts (for the symbols on the map and only the symbols) for easy access.
I'm aware that per OO logic, encapsulation is how we should program. At the same time, final static variables exist so surely they do have a purpose.
My question then is there a reason for me to avoid using the global constants and go back to putting each symbol with each object? Does global constants have a role to play within OO programming at all or is it purely for Procedural Programming?
This is a project that only I will ever work on however I am using as a testbed to improve my standards and as such I would like to use the best method possible (in terms of standard).
Defining global constants in an interface is an anti-pattern. Either use classes to define constants and then use static imports. Or simply use enums, which gives more flexibility.
Defining global (public static) constants is okay. It helps to keep you code clear and maintainable, by giving certain values meaningful names.
What you should not do, is define global constants in an interface and then add an implements-clause to each class that uses these constants. The reason for this, that you pollute the public signature of your class in this way. Instead, alsways refer to the constants by their full name (e.g. SomeClass.SOME_CONSTANT) or statically import them (import SomeClass.SOME_CONSTANT).
I would not define all global constants in one single file however, but define each of them in the class or interface that makes the most sense, for example because they define methods that return these constants or where the constants are typical arguments.
There are several benefits in use the constants, these are some of them:
Readability: If you hard code the number, when you or some other programmer have to use the code, they have to know what the value means. If a constant is used, a meaningful name is provided.
Reusability: If the same constant needs to be used in several place, when a modification is needed, you only have to change the value in one place instead of all the places where the constant is used.
Maintainability: If you have your constants in a single place instead of multiple places in the code, it is easier to modify.
It is considered a bad practice to use interfaces to hold the constants, use classes instead. If the constants are related with the class, you can define the constants within the class. If they are general purpose constants and used in several classes, you can create an utility class to hold all the constants.
public class MyUtilityClass {
public static final int MY_INT_CONSTANT = 1234;
public static final String MY_STRING_CONSTANT = "example";
...
/* Create a private constructor to avoid creation of instances of this class */
private MyUtilityClass() {
}
}
Global constants are absolutely fine.
That having been said, do not even try programming without the maximum number* of compiler warnings enabled. If you had enough warnings enabled, your compiler would be telling you that fields in interfaces do not need to be declared final and they do not need to be declared static.
(* warnings that make sense. Every compiler has its own set of warnings that are rather nonsensical and best disabled, but these are generally few.)
Encapsulation is the mechanism which protects you from changes - for example, changing the implementation of a class, will not affect the rest of your code as long as the interface (the public or protected methods) does not change.
So you can apply this reasoning to your case. Will future changes of these constants affect the rest of the code? If not, then putting all those constants as final static instances in a single class is fine. But think of this. What if you want to change how you represent your map? (from the names of the variables I assume you're using them to represent a map) Maybe you want to use special objects which also have their own behaviour, not just how to represent them on the map. Then maybe you'll want to abstract those in new classes, and not use constants anymore. And this will affect all the code where you reference these constants - probably lots of classes.
Of course, you can start with this simple representation, and if at a later point you find it's not working anymore, then you can switch. This is what I would do. I don't think it's wrong.

Why shouldn't all function arguments be declared final?

Ok, so I understand why we should declare an argument to be final from this question, but I don't understand why we shouldn't...
Since Java always uses pass by value, this means that we can't return a new value through the given argument, we can only overwrite it, and make the argument useless therefore, because we don't use the passed value...
Is the only benefit of non-final method arguments in Java the fact that you don't have to make a local variable of the arguments' type?
P.S. This question was triggered by PMD's rule of MethodArgumentCouldBeFinal
I can think of only 2 reasons not to make a parameter final:
to save the use of a local variable if you need to overwrite the parameter's value in some edge cases (for instance to put a default if the param is null etc.).
However, I wouldn't consider that a good practice in general.
to save 6 characters per parameter, which improves readability.
Reason 2 is what leads me not to write it most of the time. If you assume that people follow the practice of never assigning a new value to a parameter, you can consider all parameters as implicitly final. Of course, the compiler won't prevent you from assigning a parameter, but I can live with that, given the gain in readability.
It prevents you from making unintentional error in your code. Rule of thumb here is to make each field and each function argument you know you shouldn't change (I mean reference, you still can change value) in your code as final.
So basically its a mean to prevent programmer from shooting their foot. Nothing more.
Whether you've to declare a local variable final or not (method parameter comes under this), is more of the requirement than a convention. You'll not get a certain answer saying you should always use final or you should never use final. Because that is really a personal preference.
I personally mark the parameters or local variables final when I really don't want their values to be changed, and it even shows my intention to other developers not to overwrite the values. But I don't do it for every parameters. Also for some, using final seems to be noise, as that really increases the code base.
Rule of thumb: Don't use it.
Final cannot stop you changing objects, only its reference, and this is because objects in java are, usually, not inmutable.
Take a look to this code:
class Example{
// think about this class as a simple wrapper, a facade or an adapter
SomeClass inner = new SomeClass();
setInnet(Someclass inner){
this.inner = inner;
}
// delegate methods.....
}
Now, in a method:
private void (final Example examp){
....
examp will be always the same object, but inner can vary... And inner is the important object here, the one which makes everything!
This may be an extreme example, and you may think that inner could be final but, if it's a utillery class, maybe it shouldn't. Also it's easy to find a more common example:
public void (final Map map){;
....
//funny things
....
//and then, in a line, someone does:
map.clear()
// no we have the same reference... but the object has change...
....
So, my point against final in arguments is that it's not guaranteed that all the code inside a final class is inmutable and so the final word can end lying you and mascarading a bug...
By putting final in params you can only show wishes, not facts, and for that you should use comments, not code. Moreover: it's a standar (de facto) in java that all arguments are only input arguments (99% of the code). Thus, final word in params is NOISE because it exists and means nothing.
And I don't like noise. So I try to avoid it.
I only use final word to mark the inner variables that will be used in an anonymous inner class (you can avoid marking it if they are effectively final, but it's cleaner and more readable).
UPDATED
final means 'assigned once' which in applied to method arguments means nothing in a program's logic nor in its design.
You can assign the arguments to a new object inside a method and outside there will not be any change.
The only difference putting final in arguments will be that you will not be able to assign that entities to another objects. Assigning arguments is something which may be ugly and something to avoid but its only a style problem and, at that point, the style problem should be the assignation itself and not the ausence of 'final' word.
I think that final is useless in arguments (and so, noise), but if someone is able to find a use of it I'll be happy to learn it. What can I achieve putting 'final' that cannot achieve without putting it?

Why do we declare constants, and is it necessary to make them static?

I know that constants are those variables whose values cannot be changed, but if no part of the program changes their value, are they still required to be declared final? And it also seems that they must be static. Why is that?
You are actually asking several questions at once which I am trying to answer.
Why use constants at all?
Constants are used to avoid magic numbers/strings in your code. If you have a string that appears in several occasions of your code, once you have to change that string you only need to change the constant definition and not every occurrence of the string in your code. Also if a constant is only used once it is often a good thing because of its better visibility.
The final keyword.
Its purpose (at least in this context) is twofold. One is to make it impossible to a programmer to change the value. You might have forgotten that it is a constant. The other is to tell the compiler that the value cannot change at runtime. This can be used to create optimized bytecode (e.g. the constant could be removed and every occurrence replaced by its value by the compiler).
The static keyword.
In Java everything is a Class. And every Class can have several instances (objects). If you dont mark your constant as static then every object has "its own constant". Since you dont want that it makes sense to mark it as static. Static fields (or methods) do exist only once per class (as opposed to once per object of the class).
It is certainly possible to declare non-static finals:
class Employee {
final String empId;
public Employee(String empId) { this.empId = empId; }
}
In other cases you want the field to be constant across all instances of the class:
class Color {
final static int BLACK = 0xFFFFFF;
}
As to why you want to declare them final at all instead of just not changing them ever,
It increases program readability, it tells the reader of program something about its behavior that would otherwise have to be in documentation
Compiler reminds if you attempt to change it by mistake
Because static belongs to class rather than any instance.
When it is static single copy shared across all the instances. Where as instance member have the individual copy.
consider you need to increase/decrease game score (count), in each stage (Stage class) of your game.
Normally when you're going to use a constant value on your code, you declare a final static variable. That prevents you from spreading "magic values" around the code, which is not a good practice, for mantainability and legibility reasons.
If you don't declare them final, code made by other people (or you, in case you forget your initial intention) may modify the variable.
If you don't declare them static, every instance of the class you create will have a copy of it, also you'll have to create an instance to get the value. That's not what you want, usually.
We declare constants because we will always need some "magic numbers" that are fixed in the code. Using constants means that they are easier to spot, and that when you change them you will change all of them with a edit.
Imagine that your code defines that your window will show 15 records, and that you will consider people as adults when they are 15 years old. Without constants, changing the size of the windows means that you will have to find the 15 ocurrences, do not miss any, and do not change a 15 that means age by mistake.
The static part is because you do not want to instantiate an object to get a data that is not related to a particular instance (that is exactly what static means, btw, not only when used for constants).
It's not strictly necessary, but it's recommended for reasons of memory-efficiency:
If you don't declare your constant as static every instance of the class (possibly thousands of them) that is created will keep it's own value of (or at least a reference to) that constant in memory, whereas a static member is only kept once per class - and since it's constant anyway, that's sufficient.

Is there ever a correct time to use a public variable?

Is there a situation were using a public variable would be beneficial? If not, why do they even exist?
Also I am specifically talking about Java, but if they have use in another language perhaps that would give reason to their existence.
Yes, I use them for my representation of a vector.
public class Vec3f {
public final float x, y, z;
// the methods
}
Note that because these are final primitives it is safe to expose them. This is shorter in code and uses less method calls (none).
In general, they are viable to use in value-objects (let's use that name) if made final.
I define value-objects as possibly immutable, possibly short-lived objects holding just data, yielding new objects on mutation.
You shouldn't use public non-final variables in your public API though...
public static final variables are a common and handy way of defining constants
Public member variables are a little harder to justify, but I have seen a massive number of bean type objects with a load of private member variables and a corresponding set of getters and setters that do nothing but return or set the private variables. In those cases, there is an argument to make those variables public as the data is hardly "encapsulated" by the class - the user can set it to whatever they like, and they retrieve whatever the variable is set to without any modification.
I don't do it personally, but I'm not 100% against it either.
Global variables (when the language allows), can cause major problems especially in complex systems, where a piece of code can change its value at any time. Besides creating a coupling between places that should not have.
so avoid
In java I usually use public final constants in a single centralized source.

Are all compile-time constants inlined?

Let's say I have a class like this:
class ApplicationDefs{
public static final String configOption1 = "some option";
public static final String configOption2 = "some other option";
public static final String configOption3 = "yet another option";
}
Many of the other classes in my application are using these options. Now, I want to change one of the options alone and deploy just the compiled class.
But if these fields are in-lined in the consumer classes this becomes impossible right?
Is there any option to disable the in-lining of compile time constants?
You can use String.intern() to get the desired effect, but should comment your code, because not many people know about this. i.e.
public static final String configOption1 = "some option".intern();
This will prevent the compile time inline. Since it is referring to the exact same string that the compiler will place in the perm, you aren't creating anything extra.
As an alternative you could always do
public static final String configOption1 = "some option".toString();
which might be easier to read. Either way, since this is a bit odd you should comment the code to inform those maintaining it what you are doing.
Edit:
Found another SO link that gives references to the JLS, for more information on this.
When to use intern() on String literals
No, it's part of the JLS, I'm afraid. This is touched upon, briefly, in Java Puzzlers but I don't have my copy to hand.
I guess you might consider having these constants defined in a properties file, and have the class that loads them periodically.
Reference: http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#5313
No. You could replace them with a static method call, though, like:
class ApplicationDefs {
public static String configOption1() { return "some option"; }
}
Granted, it’s not beautiful but it would fulfill your requirement. :)
Actually, if you remove the final keyword the constants stop being compile-time constants and then your configuration will work like you want.
However, it is strongly suggested that if this is indeed some sort of configuration you are trying to do, you should move to to a more manageable way than constants in some class file.
You can inhibit inlining by making your constant non-compile time constants...
For instance, null is not a compile time constant. Any expression involving a non-compile time constant is not a compile time constant, although javac may do constant folding within the compilation unit.
public static final String configOption1 = null!=null?"": "some option";
There is nothing here that says these values should be inlined. You are just declaring some public, static members. Those other classes are using the values of these members. No inlining is asked. Even the final keyword
But for performance reasons, some JVMs may inline these values in those other classes. This is an optimization. No optimization should change the behaviour of a program. So if you change the definition of these members, the JVM should un-inline the previous values.
This is why there is no way to turn inlining off. Either the JVM does not inline and there is no problem or if it is inlined, the JVM guarantee the un-inlining.
I am not sure what happens when you import statically this class. I think (not sure) the inlining is performed and may cause the trouble you mention. If that is the case, you could basically delete the static import and you are ok.

Categories

Resources