What is difference between Fields and Constants in android documentations?
For example in View Class we have Fields and Constants.Whiles, I think that the Constants in View Class are Fields. Because each variable in each class is Field. Please example for me about this ambiguity.
When your app is compiled, any constant values are compiled directly into the application. Using an example from #CommonsWare's comment, ACCESSIBILITY_LIVE_REGION_ASSERTIVE is an integer with the value 2. That value will continue to be used by your app even if the View class is updated in a future release of Android, which is why you can't put "what version of Android am I currently running on" in a constant. Conversely, it's a fine way to record which version of the SDK your app was compiled against.
The fields are final, which means you can't change them, unless you use JNI, in which case you can. However, because the compiler uses the values directly whenever possible, changing the value of the final fields won't affect any code -- unless it accesses them through reflection.
So the distinction between "constant" and "field" may be of importance.
Primitive types and Strings may be constants. For arrays and other object types, such as the int[] used for SELECTED_STATE_SET, the reference itself is read-only, but the contents of the object are not. This is true of any mutable object type, so it doesn't make sense to list them under "constants".
There is no such thing as a Constant in Java. There are only fields which you can mark static to became a class field (i.e. one instance per class, for all objects of the same class, rather than one per each object, as if without "static"). You can access static fields by class name reference, without instantiating the class (i.e. MyClassName.sMyStaticField)
Furthermore, you can mark your field final. That means the field value assigned in initialization code and will never change. If you are assigning to static final field a constant value (for example, a number), this value will be unchanged and the same for all class instances. So, in Java it is used as a constant value, to assign a particular value to a particular name.
Since their values are known at a compile time, they can be used to make conditional compilation. Part of your code, depending on such constant values, could be excluded at a compile time
public static final boolean ENABLE_MY_SUPER_DUPER = false;
...
if (ENABLE_MY_SUPER_DUPER) {
doSuperDuper(); // Not just never executed, but not even compiled
}
That's cannot be happened, if value assigned to a field could not be known at a runtime (for example, references to objects, or arrays)
So, technically, static final fields and so called "constants" is the same, but in documentation "constants" denotes some predefined constant values, that the same for all applications (i.e. numbers, string constants etc.).
While in "field" under "static final" there are some objects, which are instantiated once just after application starts, but it's value cannot be known at a compile time. For example, arrays, some object instances, etc.
Technically you cannot alter their values, since they are finals, but you can alter their internal content. I.e. you cannot create new object or array and assign it to the same field, but you can alter items or fields of already created array/object.
Had same doubt though got the correct answer. In ViewGroup.LayoutParams class there are three constants and three fields
Constants :
int WRAP_CONTENT
int FILL_PARENT
int MATCH_CONTENT
Fields :
public int height
public layoutAnimationParameters
public int width
the difference can be seen in the source code of android
https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/view/ViewGroup.java#7857
here we see
public static final int FILL_PARENT = -1;
so the constants are nothing but fields which are final
Hope this helps!!
Related
I know that:
A blank final class variable must be definitely assigned by a static initializer of the class in which it is declared, or a compile-time error occurs.
A blank final instance variable must be definitely assigned at the end of every
constructor of the class in which it is declared, or a compile-time error occurs.
Why final variable cannot be assigned just once at any time instead of just at declare time?
The corollary to this, for non-final variables, is the initial value of a variable. Every field receives an initial value depending on its type - usually a variant of 0 or null.
It's implied here that, if you're declaring a variable to be final, then you have a specific value in mind that you wish that variable to be assigned and not have changed later in its run. Java doesn't know what value that is, and it likely takes away the convenience of automatically declaring those values for you so to not interfere with the developer's intentions.
That and requiring that all final variables be initialized is to support all variables being definitely assigned before their use. You can use a non-final field that you don't initialize to some value - it'll likely be null though - but you can't use a local variable that you haven't initialized yet for the same reason.
First it is not something against null. The following is legal too:
final String ABC;
{
ABC = null;
}
static final String DEF;
static {
DEF = null:
}
final String GHI = null;
It was the following decision:
When a final field or a local variable is not initialized it can very
well be a bug, forgetting to initialize.
(For normal fields it would be too much boiler code, and zeroing of fields is provided.)
For local variables you might find this obvious. As final variables can only be assigned once, and it was decided that this should happen only during construction (otherwise you would need administration of whether the variable was initialized).
Language design decisions are always a trade off between flexibility and error prevention. In this case, there are some simple questions to check:
In case, there is a code path in which a final variable is not assigned:
How likely is it that the developer declares a final variable just to hold the default value, null, 0 or false?
In contrast, how likely is it that the developer has forgotten the initialization or overlooked a possible code path, in other words, rejecting this code prevents a nasty bug?
How much work is it for the developer, to write the explicit assignment, if (s)he really wants the default value?
I think, trying to answer these questions should lead to the rationale behind this design decision.
This is the place for an important clarification. In case of local variables, all variables must be initialized before use. The restriction is only lifted for non-final heap variables, read, fields and array elements.
In case of arrays, it should be obvious why developers are not enforced to write explicit default values when arrays can be instantiated for lengths up to 2³¹ elements. For non-final instance fields, this decision can be discussed. But such a discussion would be outside the scope of Stackoverflow…
This question is not primarily about Strings. Out of academic curiosity I would like to know how the final modifier on a variable can change the behaviour a program. The following example shows it is possible.
These lines print true
final String x = "x";
System.out.println(x + x == "xx");
but these lines print false
String x = "x";
System.out.println(x + x == "xx");
Apart from String interning, are there any other things that can cause the behaviour of a program to change if the modifier final is removed from a variable declaration? I am assuming that the program compiles with or without the modifier.
Please don't vote to close it as duplicate of Comparing strings with == which are declared final in Java. I understand the Strings example.
I'm asking if there are any other reasons removing a final modifier can make a difference. Please can someone link to an answer or answer the question. Thanks.
The final modifier only ensures that the variable is definitely assigned, and prohibits any reassignment to and from that variable.
The only special cases that can be observed are expressly stated in the JLS:
A variable of primitive type or type String, that is final and initialized with a compile-time constant expression (§15.28), is called a constant variable.
Whether a variable is a constant variable or not may have implications with respect to class initialization (§12.4.1), binary compatibility (§13.1, §13.4.9) and definite assignment (§16).
There's a decent amount of JLS reading, and to cover the main point: By JLS §13.4.9, you will not encounter any ill effects upon removing the final modifier.
However, by JLS 17.5, if you rely on the guarantee of a thread only seeing the definitely assigned variables in an object that it can observe, then removing the final variable will cause those variables to no longer be visible to another thread.
So, if we look at class initialization first, there are rules surrounding class initialization if the field is static and not a constant variable:
A class or interface type T will be initialized immediately before the first occurrence of any one of the following:
T is a class and an instance of T is created.
T is a class and a static method declared by T is invoked.
A static field declared by T is assigned.
A static field declared by T is used and the field is not a constant variable (§4.12.4).
In JLS §13.1, it is spelled out that changing a field to final can break binary compatibility:
References to fields that are constant variables (§4.12.4) are resolved at compile time to the constant value that is denoted. No reference to such a field should be present in the code in a binary file (except in the class or interface containing the field, which will have code to initialize it). Such a field must always appear to have been initialized (§12.4.2); the default initial value for the type of such a field must never be observed. See §13.4.9 for a discussion.
From 13.4.9:
If a field that was not declared final is changed to be declared
final, then it can break compatibility with pre-existing binaries that
attempt to assign new values to the field.
Deleting the keyword final or changing the value to which a field is
initialized does not break compatibility with existing binaries.
If a field is a constant variable (§4.12.4), then deleting the keyword
final or changing its value will not break compatibility with
pre-existing binaries by causing them not to run, but they will not
see any new value for the usage of the field unless they are
recompiled. This is true even if the usage itself is not a
compile-time constant expression (§15.28).
This result is a side-effect of the decision to support conditional
compilation, as discussed at the end of §14.21.
So from that alone, be careful about suddenly changing fields to final. Removing the field is safe.
...but that only applies to a single-threaded world. From JLS 17.5:
Fields declared final are initialized once, but never changed under
normal circumstances. The detailed semantics of final fields are
somewhat different from those of normal fields. In particular,
compilers have a great deal of freedom to move reads of final fields
across synchronization barriers and calls to arbitrary or unknown
methods. Correspondingly, compilers are allowed to keep the value of a
final field cached in a register and not reload it from memory in
situations where a non-final field would have to be reloaded.
final fields also allow programmers to implement thread-safe immutable
objects without synchronization. A thread-safe immutable object is
seen as immutable by all threads, even if a data race is used to pass
references to the immutable object between threads. This can provide
safety guarantees against misuse of an immutable class by incorrect or
malicious code. final fields must be used correctly to provide a
guarantee of immutability.
An object is considered to be completely initialized when its
constructor finishes. A thread that can only see a reference to an
object after that object has been completely initialized is guaranteed
to see the correctly initialized values for that object's final
fields.
So, if your program relies on the above guarantee for it to function normally, then removing the final keyword will have consequences in threading.
I want to have a file with constants being accessed from multiple threads. Is it a safe implementation to have a class with a lot of public static final ints for this?
Yes, it is thread-safe. Any static final variable is guaranteed to be initialized after class initialization. Thus, once a class containing such a static final variable is used anywhere in your code, it is always fully initialized (i.e. the value is set) by requirement of the JVMS.
With a primitive int, this condition is even tighter. A primitive static final variable (same goes for String) is a so called compile-time constant which are inlined by the Java compiler javac. The only requirement is that the value can be computed by the Java compiler, i.e. it must not be the result of a non-constant evaluation. As you are write that you want to define constants, I assume that this does not apply for your use case. Those constant values are therefore directly copied to their access location what cuts the corner-case of non-thread safety of a static final variable being altered via reflection wich is hypothetically an issue with non-primitive types.
Furthermore, using such variables is a good idea because it avoids the use of so-called magic numbers.
Yes, it is safe.
The value never changes so there is no risk of race conditions. Java guarantees that the value will be initialized before anything tries to use it.
Whether it is the best architecture for other reasons (clarity of design etc) is another question.
Yes, 100% safe. It's final, so nobody can alter it. Every thread has to access as reader only, and there is no contention for reading only.
For primitives, making them final makes them compile time constants (if initialized directly and not as result of method) and an int is a primitive. So, final int makes it immutable and hence thread-safe.
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.
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.