Static block is not being called - java

Who can explain what's going on?
public class MagicFinal {
public static void main(String[] args) {
System.out.println(A.s);
}
}
class A {
static {
System.out.println("class has been loaded");
}
public static final String s = "final";
public static final Integer i = 3;
}
Console :
final
What's it? I don't understand why the class has not been loaded, I know classes always load at the first call. Field s is in pool of string, I see that final modifier is magic.
If I delete final modifier (public static String s = "final" ) I will get
Console :
class has been loaded
final
Note: I have changed field i : public static final int i = 3; and show it in console.
I got the same as in String situation. Why?

"final" is a string literal and as such is a compile-time constant expression. The value of a static final variable initialized with a compile-time constant expression is directly hardcoded into the class which references it, and no reference is made to the originating class. Therefore the initialization of the originating class does not occur.
As a side point, please note the distinction between class loading and class initialization: only the latter's occurrence is precisely specified by the JLS. Class loading can happen at any time.

This is what is written in Java Language Specification {8.3.2.1 Initializers for Class Variables}. This must answer your question
One subtlety here is that, at run time, static variables that are final and that
are initialized with compile-time constant values are initialized first. This also
applies to such fields in interfaces (§9.3.1). These variables are “constants” that
will never be observed to have their default initial values (§4.12.5), even by devious
programs. See §12.4.2 and §13.4.9 for more discussion.

Related

When are enum values initialized? [duplicate]

When are static fields initialized? If I never instantiate a class, but I access a static field, are ALL the static blocks and private static methods used to instantiate private static fields called (in order) at that instant?
What if I call a static method? Does it also run all the static blocks? Before the method?
A class's static initialization normally happens immediately before the first time one of the following events occur:
an instance of the class is created,
a static method of the class is invoked,
a static field of the class is assigned,
a non-constant static field is used, or
for a top-level class, an assert statement lexically nested within the class is executed1.
See JLS 12.4.1.
It is also possible to force a class to initialize (if it hasn't already initialized) by using Class.forName(fqn, true, classLoader) or the short form Class.forName(fqn)
When does static class initialization happen?
See above.
When are static fields initialized?
As part of static class initialization; see above.
If I never instantiate a class, but I access a static field, are ALL the static blocks and private static methods used to instantiate private static fields called (in order) at that instant?
Yes. (Modulo that nothing is truly instantaneous.)
What if I call a static method? Does it also run all the static blocks? Before the method?
Yes and yes.
Note that it is possible to construct code where you can observe the default initialized value of a static field.
1 - The final bullet point was present in the JLS for Java 6 through Java 8, but it was apparently a mistake in the specification. It was finally corrected in the Java 9 JLS: see source.
Static fields are initialized during the initialization "phase" of the class loading (loading, linking and initialization) that includes static initializers and initializations of its static fields. The static initializers are executed in a textual order as defined in the class.
Consider the example:
public class Test {
static String sayHello() {
return a;
}
static String b = sayHello(); // a static method is called to assign value to b.
// but its a has not been initialized yet.
static String a = "hello";
static String c = sayHello(); // assignes "hello" to variable c
public static void main(String[] arg) throws Throwable {
System.out.println(Test.b); // prints null
System.out.println(Test.sayHello()); // prints "hello"
}
}
The Test.b prints null because when the sayHello was called in static scope, the static variable a was not initialized.
Yes, all static initializers are run before you access class first time. If it was any other way, I would call it a bug.

Object being static

I seen this bit of code, Even though I think I got the concept of static in Java I am bit confused. Can any one explain it to me, how an object being static works?
My code:
package com.oracle.certification.sampleTest;
public class Person {
static class Mail {
static String desc="Male";
}
static Gender Mail=new Gender();
}
package com.oracle.certification.sampleTest;
public class Gender {
String desc="Gender";
}
package com.oracle.certification.sampleTest;
public class Human {
public static void main(String str[]) {
System.out.println(Person.Mail.desc);
}
}
When the class Human is run, the O/P is 'gender' not 'male', even though des= gender is nonstatic and des=male is static with static inner class. Also I don't need to import the classes in Hman? I am sorry that I have very little knowledge about inner classes, first of all.
Can any one explain it to me, How an object being static works?
Essentially, static in that context means that the entity in question is attached to the class itself, not to an object of the class. Hence, with static there is exactly one instance of what you declare:
class T {
public static int staticMember = 0; // one variable stored in memory
public int nonStaticMember = 0; // as many variables stored in memory as objects are created from the class
}
See also What does the 'static' keyword do in a class?
However, your question is not necessarily a misunderstanding of static classes, but a corner case of name resolution: You are declaring both a type and a member variable with the same name (Mail) in one scope (within the Person class) - while one might think that this should not even be possible, the Java language does allow this and defines a couple of rules to determine which one to use.
From the JLS:
A simple name may occur in contexts where it may potentially be interpreted as the name of a variable, a type, or a package. In these situations, the rules of §6.5 specify that a variable will be chosen in preference to a type.
...
static class Mail { // a Type
}
static Gender Mail ... // a Variable with the same name
// - the compiler chooses to use this one
...
Hence, when referencing Person.Mail, the compiler chooses the variable, not the type (the inner class).

Performance - Huge string constants is duplicated across multiple class files

I am getting sonar vilation Performance - Huge string constants is duplicated across multiple class files.
What is the reason i am getting this?
How to resolve this?
This is the code
public static final String GET_CO_ADMIN_GRID_DTLS ="A 30 line huge query";
Solution : Performance - Huge string constants is duplicated across multiple class files.
1.Declare the class as final , make the field as public static final and assign inside static block.
2.Dont Forget to declare private constructor otherwise sonar will show "utility classes should not be public or default constructor as (MAJOR issue)".
public final class QueryConstants {
/**
* Default Constructor.
*/
private QueryConstants(){
//
}
public static final String COMMON_SELECT;
static {
COMMON_SELECT = "Your Query Here";
}
It is because of final keyword. the final field coppied into reference class also.
A large String constant is duplicated across multiple class files. This is likely because a final field is initialized to a String constant, and the Java language mandates that all references to a final field from other classes be inlined into that classfile. See JDK bug 6447475 for a description of an occurrence of this bug in the JDK and how resolving it reduced the size of the JDK by 1 megabyte.
We need to remove final keyword from that string....
The answer from Gowtham is the right one. Creating a Constants class doesn't solve the problem
// creating the constants class like this would lead into duplication of the huge string assigned to FOO
// class A and B would also contain the huge string, after compilation
class C {
public static final String FOO = "HUGE STRING";
}
class A {
public void f() {
String c = C.FOO;
}
}
class B {
public void f() {
String c = C.FOO;
}
}
creating the constant class like proposed in the mentioned bug report http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6447475 avoid the duplication of the huge string
class C {
public static final String FOO;
static {
FOO = "BAR";
}
}
If the string constant is same, then create a Constants file and place that constant there. Use that constant in your multiple class files. like:
Constants.CONSTANT_1

Java Error - Illegal Modifier for Parameter - Only final Permitted

What's wrong with the below Code
public static void main(String[] args){
public static final String Name = "Robin Wilson";
}
String Reference Name shows Compilation Error - Java Error - Illegal Modifier for Parameter Name - Only final Permitted
Am okay with the below given suggestions, but I want to understand why its not permitted, though both are static?
Your have modified your question to ask:
I want to understand why it is not permitted, though both are static?
Variables inside a method exist only on the stack frame. The JVM creates a new stack frame every time a method is invoked, and it is discarded once the method completes.
The public keyword is used on classes, methods and fields to control access. There is no concept of access that could be applied to a stack (local) variable. It only exists inside the method when it's called, and can only be accessed from within the method.
The static keyword is used on fields to denote that only one such member exists across all instances of a class, and on methods to create them as members of the class that do not require an instance. There is no concept of a static state for anything on the stack; it is temporary. The stack frame and all the local variables on it cease to exist once you return from a method call.
Basically, neither make any sense when talking about a local variable.
How to fix it
public and static cannot be used inside a method definition. So this error is telling you that the only modifier allowed for a variable defined inside of a method is final.
You fix it by either by removing the offending modifiers:
class MyClass
{
public static void main(String[] args){
final String Name = "Robin Wilson";
}
}
or moving the variable definition out of the method like this
class MyClass
{
public static void main(String[] args){
}
public static final Name = "Robin Wilson";
}
Explanation
To understand why, you need to understand what each of the three modifiers (public and static and final) means on its own. String Name just says that we are keeping track of a String and calling it Name.
public
class MyClass
{
public String Name = "Robin Wilson";
}
public says that any part of the program can read it (otherwise it could only be read by code written in the MyClass class).
public specifies what other code has access to it. Inside a method this doesn't make sense. Variables defined inside methods can only be accessed while inside that method, and once the method is complete they are thrown out. So it would be impossible for those variables to be public.
static
class MyClass
{
static String Name = "Robin Wilson";
}
static says that the Name variable is a part of the class itself, not of an instance of the class. In other words, all instances of the MyClass class share the same Name variable.
static specifies how it is accessed (either on an instance of the class or through the class itself). Inside a method this doesn't make sense, because local variables are discarded after the method closes, so nothing else will be accessing it.
final
class MyClass
{
final String Name = "Robin Wilson";
}
final says that the value of Name will never change once it has been assigned.
final describes how the variable is going to be used. It makes sense within a method, because it is not about access.
You can't declare this inside main, put it outside the method, you want it as a [class member]:
public static final String Name = "Robin Wilson";
public static void main(String[] args) throws IOException { }
Otherwise(I don't think this is what you want) just remove public static from there and simply write:
public static void main(String[] args){
final String Name = "Robin Wilson";
}
you can not use public static modifier for a local variable. Do any of the followings
public static void main(String[] args){
final String Name = "Robin Wilson";
}
or declare it as a member variable
public static final String Name = "Robin Wilson";
public static void main(String[] args){
}
Remember that the final is the only modifer of the local variables
Your can not declare a local variable(variables inside methods are local variables) as public static. Instead, the following code will work:
public static void main(String[] args){
final String Name = "Robin Wilson";
}
as you are Declaring the String variable as public static final String Name = "Robin Wilson";
According to java rules, This String name is Local variable as you are declaring it in Main method. So only final is permitted here.
you can define it as ** final String name="Robin Wilson";** in main method.
for Local variables only final is permitted.
Static declaration of a component makes in available on a class level. Declaring component in a method makes in available in method's stack memory hence can only be accessed through an object. Static belongs to the whole class. Therefore their is no point in declaring a variable static. You'll even get the compile time error if you try to do so.
Final keyword has nothing related to memory.
its mean you should write your static function outside the "main" block. It will work fine. Enjoy
The modifiers private, protected, and public cannot be used on variables inside of a method. This is because you can only have local variables inside of methods.
Java is simply telling you that the only modifier allowed at that time is the final keyword.

A static variable trying to access another static variable

I was wondering, whether the following code are safe.
public class GUIBundle {
// The technique known as the initialization on demand holder idiom,
// is as lazy as possible.
// http://en.wikipedia.org/wiki/Initialization_on_demand_holder_idiom
//private static class BundleHolder {
// private static final ResourceBundle bundle = ResourceBundle.getBundle("org.yccheok.jstock.data.gui");
//}
private static final ResourceBundle bundle = ResourceBundle.getBundle("org.yccheok.jstock.data.gui");
private GUIBundle() {
}
public static String getString(String key) {
// return BundleHolder.bundle.getString(key);
return bundle.getString(key);
}
}
public class SellPortfolioChartJDialog extends javax.swing.JDialog {
private static final String[] cNames = new String[] {
GUIBundle.getString("BuyPortfolioTreeTableModel_NetGainValue")
};
}
Since cNames is within static scope, is it safe for it to access static bundle? Does it make any different whether I am using lazy initialization technique?
I remember I came across an article (I lost the article anyway) talking about nondeterministic of initialization order of static variables. I am not sure whether the nondeterministic of initialization order of static variables, applied to the above case?
I believe the nondeterministic initialization order of static variables (in different compilation units) is a C/C++ "feature". In Java, static variables are initialized when their class is loaded, and within a single class in their order of declaration. So the order is deterministic (at least in a single threaded environment).
This guarantees that what you intend to do should work: when GUIBundle is first referenced, the classloader loads it and initializes bundle too. The call to GUIBundle.getString() happens only after the class initialization is done.
That works just fine. I got it to compile by keeping the principle the same but using different classes (I didn't want to bother getting your jars... :-).
Obviously there are some small problems, like how you declare your String[] needs to be
private static final String[] cNames = new String[] {
GUIBundle.getString("BuyPortfolioTreeTableModel_NetGainValue")
};
}
Other than that, it works just fine. The key to using statics in other statics is the order they're declared. You can't do this
static Foo b = a;
static Foo a = new Foo();
I think its perfectly safe, You see because the when
GUIBundle.getString
is used in your JDialog subclass, the JVM will completely initialize (see java language spec loading, linking and initialization) the class GUIBundle before calling the method getString on it, which will initialize all the class (static) initializers in the class GUIBundle.
Edit: Read more about this in VM spec:
http://java.sun.com/docs/books/jvms/second_edition/html/Concepts.doc.html#16491
To me it's safe.
bundle is initialized right after GUIBuilder is loaded and therfore before getString is called for the first time.

Categories