Unsure about static variables.
import java.io.File;
public class Logger {
public static final File log = new File(File.listRoots()[0], "log.log");
public static void log (String message) {
/* ... */
}
}
Is the variable log pointing to the same memory throughout the life of the program? Basically is the log definition new File(File.listRoots()[0], "log.log") calculated multiple times or just one, and when?
Thanks in advance.
It is invoked once per classloader. Which, normally, means once.
A static variable is initialized as soon as the class declaring it is loaded by the classloader, and stays there until the classloader is destroyed, which in most cases means - at the end of the program execution / application lifecycle.
Just once. AFAIK, when class is loaded.
Related
I have instrumented JDK and application. Entry and exit points are recorded for call graph construction.
The call graph looks like
sun.misc.Launcher$AppClassLoader.loadClass->com.example.Main.main
->sun.misc.Launcher$AppClassLoader.loadClass->com.example.Foo.foo
Source code
public class Main{
public static void main(String[] args){
Foo.foo()
}
}
public class Foo{
public static void foo(){};
}
This must be how classloader works but I don't see anything shows in bytecode that indicate the call site "sun.misc.Launcher$AppClassLoader.loadClass". So, how does classloader work internally?
Classes are loaded lazily.
You can see this by writing code to print to the console within static initialisers.
The first time a class reference is used by any code loaded by a specific class loader, the JVM request the Class from the loader in the current thread. If the parent class loader hasn't loaded a class of the fully qualified name, then the current class loader will define it (or throw an exception).
In the early days applets would make a network connection for each class file.
Hi I've got a very simple class defined like this
public class Pokus {
public static String loginToken;
public String neco = "neco";
public Pokus() {
}
public static String getLoginToken() {
return loginToken;
}
public static void setLoginToken(String loginToken) {
Pokus.loginToken = loginToken;
}
}
When I create an instance of this class
Pokus pokus = new Pokus();
pokus.setLoginToken("bla1212");
In a debugger I can see that object pokus has a field/variable called "neco" but not that static variable "loginToken".
debbuger in Android Studio
Is there any way to see static variables as well as the non-static ones?
Thanks guys I knew all of this but didn't know that debugger is taking this into consideration. There is an option to show static field Settings > Build,Execution, Deployement > Debugger > Data Views > Java
Debugger shows it properly, pokus is instance of class Pokus so it have standard method and properties from class Pokus, static methods and properties are in Class not in instance of Class. Static properties are shared for every object created from class Pokus ( or for every component in program if their are public ) so debugger properly not shows them as properties of single instance.
To show static variable examine class not instance. When debugger stops on breakpoint You can use console and write Pokus.someStaticVar and You will see current value. Console is available in debugger - http://imgur.com/a/nHfEo.
You can right-click in the debugger's Variables area and select Customize Data Views...
In there, you can choose to add static and final static fields.
Static variables have the same values for all the instance of the class.Moreover they should be accessed using class and not an instance of the class. In Java, when you declare something as static, you are saying that it is a member of the class, not the object (hence why there is only one). Therefore it doesn't make sense to access it on the object, because that particular data member is associated with the class.
That is the reason i think debugger does not show and it is correct behaviour
After a WebLogic app has been running fine for a few weeks I suddenly get an Exception:
<Oct 25, 2014 9:31:11 PM EDT> <Error> <HTTP> <BEA-101020>
<[ServletContext#60724164[app:whatever3000 module:whatever3000.war path:
spec-version:2.5]] Servlet failed with Exception
java.lang.ExceptionInInitializerError
after which the application is completely defunct with NoClassDefFoundError until the app server is restarted.
The full stack trace shows the origin of the issue is a ConcurrentModificationException in a static initializer.
Specifically the equivalent / minimized code is as follows:
package a;
import b;
public class Whatever {
void doIt()
{
Password p = new Password();
}
}
package b;
public final class Password implements Serializable
{
private static final int PARAM1 = CommonStuff.someStaticMethod();
...
}
import java.util.Properties;
public class CommonStuff
{
private static Properties prp = new Properties();
static {
CommonStuff.load();
}
public static void load()
{
prp.putAll(System.getProperties()); <---FAIL
This is the origin of the Exception:
java.util.ConcurrentModificationException
at java.util.Hashtable$Enumerator.next(Hashtable.java:1017)
at java.util.Hashtable.putAll(Hashtable.java:469)
at b.CommonStuff.load(CommonStuff.java:55)
at b.CommonStuff.<clinit>(CommonStuff.java:77)
at b.Password.<clinit>(Password.java:44)
at a.doIt(Whatever.java:99)
So it seems at some point during the runtime of the application, WebLogic decided to reload classes from package b but when the static block runs it finds that the Properties object has been modified.
I don't know if it's being called concurrently or if it's being called multiple times. It could be that the Properties object is the original instance created when the app loaded fresh the first time and the reloading of CommonStuff class is trying to call putAll() again.
Would it help if I do:
private static Properties prp = null;
static {
CommonStuff.prp = new Properties();
CommonStuff.load();
}
I cannot just try things blindly because it's in a production app at a huge company. So I'm trying to understand where I'm going wrong and how to property initialize these variables while classes are being reloaded in the middle of the night.
Any ideas?
Could this be a WebLogic ClassLoader issue?
Classes/instances cannot access some class's members before this class is initialized. Because of this no one can access newly created prp before static constructor returns. Moving prp initializer inside on static {} block makes no difference. Also "old" prp in the "old" CommonStuff and "new" prp are not connected in any way (because "old" and "new" CommonStuff are different classes for JVM). This all make possibility of concurrent modifications of prp look pretty weird.
I believe the reason is in another place. Notice the first line of the stack trace: exception is thrown by Enumerator of Hashtable. Here is the code of the putAll method (as in JDK 8, probably didn't change for many years):
for (Map.Entry<? extends K, ? extends V> e : t.entrySet())
put(e.getKey(), e.getValue());
Here is the Enumerator that throws an exception - and it is not prp, it is argument's Enumerator.
So the exception is related not to prp but to Map returned by System.getProperties(). The reason is that iterating over system properties map is not thread safe. It seems that another thread is modifying it at the same time.
You need to initialize prp differently. I think clone() is the simplest way.
Assume, that I have class with static methods only. Will class loader load every imported class when loading class to memory? Or it will only load imports when a method from this would need access to it?
Question is whether class loader loads imports when the class is loaded to memory, or just before some methods want to use them.
If it is the first option I would probably need to divide some of my Util classes, to be more specialized.
I think you can test it as follows:
package pkg1;
public class Test {
static {
System.out.println("Hello 111");
}
public static void meth() {
System.out.println("Hello 222");
}
}
Test 1:
package pkg2;
import pkg1.Test;
public class Tester {
public static void main(String... args) {
Test t;
}
}
That prints nothing.
Test 2:
package pkg2;
import pkg1.Test;
public class Tester {
public static void main(String... args) {
Test.meth();
}
}
Prints:
Hello 111
Hello 222
So, just because you have imported a class does not mean the classloader will load the class into the memory. It loads it dynamically when it's used.
I don't claim to know a lot about the class loader, but if you're talking about import statements then the class loader is irrelevant.
Import statements exist purely to allow the developer to use short class names rather than the fully qualified name of each class referenced in the class being written. The compiler uses those import statements very early on to resolve the names of the referenced classes before a single line of bytecode is created.
In general, the static code block at the top of a class file with a report (i.e. a print statement ) will give you a good idea of when the loading happens in your particular application.
However, when dealing with corner cases, like dynamic classes, inner static classes, or classes off the classpath that are dynamically loaded, you will have to be careful - because these classes might actually be loaded MULTIPLE times in an application.
When is static variable loaded, runtime or compile time? Can someone please explain it.
I would really appreciate the help.
Thank you.
The compiler optimizes inlineable static final fields by embedding the value in the bytecode instead of computing the value at runtime.
When you fire up a JVM and load a class for the first time (this is done by the classloader when the class is first referenced in any way) any static blocks or fields are 'loaded' into the JVM and become accessible.
A demonstration:
public class StaticDemo {
// a static initialization block, executed once when the class is loaded
static {
System.out.println("Class StaticDemo loading...");
}
// a constant
static final long ONE_DAY_IN_MILLIS = 24 * 60 * 60 * 1000;
// a static field
static int instanceCounter;
// a second static initialization block
// static members are processed in the order they appear in the class
static {
// we can now acces the static fields initialized above
System.out.println("ONE_DAY_IN_MILLIS=" + ONE_DAY_IN_MILLIS
+ " instanceCounter=" + instanceCounter);
}
// an instance initialization block
// instance blocks are executed each time a class instance is created,
// after the parent constructor, but before any own constructors (as remarked by Ahmed Hegazy)
{
StaticDemo.instanceCounter++;
System.out.println("instanceCounter=" + instanceCounter);
}
public static void main(String[] args) {
System.out.println("Starting StaticDemo");
new StaticDemo();
new StaticDemo();
new StaticDemo();
}
static {
System.out.println("Class StaticDemo loaded");
}
}
Output:
Class StaticDemo loading...
ONE_DAY_IN_MILLIS=86400000 instanceCounter=0
Class StaticDemo loaded
Starting StaticDemo
instanceCounter=1
instanceCounter=2
instanceCounter=3
Notice how 'Starting StaticDemo' does not appear as the first line of output. This is because the class must be loaded before the main method can be executed, which means all static fields and blocks are processed in order.
They are loaded at runtime.
Static means: that the variable belong to the class, and not to instances of the class. So there is only one value of each static variable, and not n values if you have n instances of the class.
run time when class is loaded.
- Have a look at initialization
The static fields are loaded when the class is loaded. This usually happens which the file object of a class is created, but it can be earlier if the class is used another way.
The static initialiser is thread safe and you can access the class in multiple threads safely. This is useful as a way to create a thread safe singleton without having to use a lock.
Note: the class can be loaded (and its static intialisation block run) more than once if multiple class loaders are used. Generally, loading the same class in multiple class loaders can be confusing and is avoided, but it is supported and does work.
How would you load a variable at compile time? The variable is initialized when the corresponding class is loaded. See the JVMS.
Loading is a runtime operation. Everything is loaded at runtime.
When you type java ClassName then class loads into JVM with static variables, so you don't need an object for it.
Where as instance variable loaded by JVM when the object is created.
Static fields gets loaded at the time of class loading in JVM.