简体   繁体   中英

final static vs final non-static fields and JVM optimization

I'm curious how are the static final fields treated by the JVM. I saw a similar question here but it's not what I'm looking for. Let's consider such example:

public class TestClassX {
   public final int CODE_A = 132;
   public final int CODE_B = 948;
   public final int CODE_C = 288;
   // some other code
}

public class TestClassY {
   public static final int CODE_A = 132;
   public static final int CODE_B = 948;
   public static final int CODE_C = 288;
   // some other code
}

In TestClassX fields, as they are final and cannot be modified, have the same values in all instances of the TestClassX class. Of course I cannot write TestClassX.CODE_A but I can say, that these values are actually common for all instances - I'm sure, that each instance has a CODE_A field with the value 132 .

In the TestClassY I can use the syntax TestClassY.CODE_A , but at a first sight it's only easier for a developer who sees "Oh, those values are common for all instances".

My main question: I guess that JVM, in case of TestClassX , doesn't use any extra memory for final fields each time a new instance is created. Does it? Does JVM make any optimization in this case and what kind of optimization it is?

Extra question 1) I'm also sure that I'm missing something very important here which is the cause of my doubts. What's that?

Extra question 2) Btw. How can I take a look at how my Java source code looks like after the JVM optimization (so I can use in in the future ;))? Does any IDE support such a functionality? IntelliJ for example? I would like simply to see how JVM treats my TestClassX and TestClassY .

  • Non-static fields are always present in the instances. They do not save memory.
  • In general JVM does not optimize non-static fields. Even if they are final they can be still set to different value using reflection or during deserialization.
  • There is an experimental VM option -XX:+TrustFinalNonStaticFields (off by default) which tells JVM to optimize access to such fields, ie treat them as constants and eliminate field loads.
  • There is a -XX:+PrintAssembly VM option to dump JIT-compiled code.

For the first part of your question, maybe this answer can help you.

For the second part you could see the generated assembly (as stated in this answer ) by adding -XX:+PrintOptoAssembly flag when you run/compile your code.

I should also add that the assembly code given to you is not the real opcode generated by the jvm, but the code needed to be run under your actual architecture.

Hope this helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM