I want detailed explanation about

static int var;
final int var;
static final int var;

Please explain it in the memory implementation level.

If there is any mistake in these please explain.

__________________

Recommended Answers

All 12 Replies

I'll take a stab at this, hoping that any errors or omissions will be remedied by other members.

Final simply means that once the variable is assigned, it may not be reassigned. That is, it is a constant. This is useful for two reasons. The first is performance: the compiler can handle the code more efficiently if it knows that a particular variable can be treated as a constant. For example, it can rewrite

final double PI = 3.1415;
area = PI * r * r

as

area = 3.1415 * r *r;

in all cases. This saves some steps.

The second advantage that strikes me at this moment (there may be others) is a code-safety thing. If you know that a given variable should not change in the course of the program, and you mark it final, you'll be warned if you inadvertantly reassign that variable. Of course, none of us would ever make such a mistake, but it's always nice to know that the person maintaining the code after you will be caught if they goof. :)

Static is a kettle of fish of a different color, to mix a metaphor.

Static tells the compiler that this variable pertains to the class, not to any instance of the object.

For example, if you have Circle objects, and for some reason you want your circles to have an internal value for pi (pi might change, after all, and you want to be ready for that!), you would probably want to make that a static rather than an instance field.

That way, when it's set, it applies to all circles.

For example:

public class Circle
{
static double pi = 3.1415;
double radius;

public Circle(double radius)
{
  this.radius = radius;
}

public double area()
{
  return radius*radius*pi;
}


public static setPi(double newPi)
{
  pi = newPi;
}
}

This is a silly example, but in this case pi is the same value for all Circles. But since it's not declared final, I can re-set it. Perhaps I come up with a more accurate value, or I want to experiment with different values, or who knows why, but I can do that. When I call setPi(), following calls to area() for any Circle object will return a value based on the new value of pi.

One real-life use would be coordinating GUI values (colors, line widths, default values for drawing objects) by setting them as static variables in a utility class. If your user decides that selected items should be red, you can set them once:

GraphicsSettings.selectedColor = Color.RED;

and then render them that way by setting the pen color to GraphicsSettings.selectedColor if the object is flagged as "selected".

Does that help?

your answer was fantastic ...... :)

can u explain this

what is const ?
what is the difference between const and final?
Or is there any difference
_____________________

The keyword final makes the declaration a constant.
you cannot reassign value.

eg;
final int i=10
i=20;//error:i can't be assigned

The keyword static makes the declaration belong to the class as a whole. A static field is shared by all instances of the class, instead of each instance having its own version of the field. A static method does not have a "this" object. A static method can operate on someone else's objects, but not via an implicit or explicit this.

SO COMBINATION OF FIANL AND STATIC is make a variable constant and belongs to the class and cannot be reassigned and modified

http://www.informit.com/articles/article.aspx?p=349047


Static Variable:
it maintains the single copy for all the instances.
Declaring a member variable to be static causes it to be a class variable. Local variables cannot be declared static. Only member variables can be declared static. To begin with don't ever use static variables without declaring them final unless you understand exactly why you are declaring them static. Static final variables or constants are often very appropriate. See the fields in the Color class for example. I can only think of a few situations where the use of a non-final static variable might be appropriate. One appropriate use might be to count the number of objects instantiated from a specific class. I suspect there are a few other appropriate uses as well.

Static methods
Don't declare methods static if there is any requirement for the method to remember anything from one invocation to the next. A static method only has access to other static members of the class so it cannot depend on instance variables defined in the class. Declaring a method to be static causes it to be a class method.

Example:
The main method is a class method

public static void main(String[] args)
{
//statements;
}

The important thing to note here is that the main method is declared static. That causes it to be a class method. As a result the main method can be invoked without a requirement for an object of the class to exist. Also the main method has direct access only to other static members.


/*File MyClass01.java
Copyright 2005 Sumit Kumar

This program illustrates static members of a class.

import java.util.Date;
class MyClass01
{
static Date v1 new Date();
Date v2 new Date();

public static void main(String[] args)
{
//Display static variable
System.out.println( Static variable );
System.out.println(MyClass01.v1);

//Delay for five seconds
try
{
Thread.currentThread().sleep(5000);
}
catch(InterruptedException e){}

//Instantiate an object and display instance variable
MyClass01 ref1 new MyClass01();
System.out.println();//blank line
System.out.println( Instance variable );
System.out.println(ref1.v2);

//Now display the static variable using object reference
System.out.println( Static variable );
System.out.println(ref1.v1);
System.out.println();//blank line

//Delay for five seconds
try
{
Thread.currentThread().sleep(5000);
}
catch(InterruptedException e){}

//Instantiate another object
MyClass01 ref2 new MyClass01();
System.out.println();//blank line
System.out.println( Instance variable );
System.out.println(ref2.v2);

//Now display the same static variable using object reference
System.out.println( Static variable );
System.out.println(ref2.v1);
}//end main
}//end class MyClass01

Output is:

Static variable
Mon Aug 30 09:52:27 CDT 2005

Instance variable
Mon Aug 30 09:52:32 CDT 2005
Static variable
Mon Aug 30 09:52:27 CDT 2005


Instance variable
Mon Aug 30 09:52:37 CDT 2005
Static variable
Mon Aug 30 09:52:27 CDT 2005
**************************************/

FINAL

Final variable can't be modified.
Final variables are implicitly final.
Final methods can't be overriddern.
Final class can't be subclassed.

Please do not, I repeat, do not link to any roseindia material. These guys are content thieves and more concerned about driving traffic to their site than imparting knowledge; a bad sign indeed. BTW, the original article is here.

Okay, you've got some folks interested. This is good.

You asked about what's happening at the memory level. I've just written up a little piece of code that will show you some stuff, but it'll take a little reading.

Okay, here's the source:

public class StaticFinal
{
   public static int staticInt;

   public final int FINAL_INT;
  
   public static final int STATIC_FINAL_INT=3;


   public static void main(String[] args)
   {
      StaticFinal sf = new StaticFinal();
      sf.doSomeStuff();

   }
      
      
   public void doSomeStuff()
   {
      
   // load the variables to print them

      System.out.println(staticInt);
      System.out.println(FINAL_INT);
      System.out.println(STATIC_FINAL_INT);
   

   // let's see some constant folding
   
      int instanceInt = 4;
      int newVar = instanceInt+instanceInt;
      int newVar2 = staticInt+staticInt;
      int newVar3 = FINAL_INT +FINAL_INT;
      int newVar4 = STATIC_FINAL_INT + STATIC_FINAL_INT;
   }


   public StaticFinal()
   {
      staticInt = 1;
      FINAL_INT = 2;


   }
}

Take that and compile it. Running it will produce very little of interest. However, if you use javap, you get some fun stuff.

At the command line, type "javap -v StaticFinal", and you'll see a bunch of lines. This is the JVM code - these are the instructions that the jvm is actually implementing. I'll post the relevant section, and possibly s.o.s. can help me point out the features of interest, if he's game.

As an aside, if you want to see what's going on in the machine, javap -v is a great tool. It's best, I find, when you work with as simple a class as you can manage, which is why this code doesn't actually do anything, but it's fascinating to see what it is that your class looks like to the machine.

More in a moment.

Okay, here's the jvm code for the doSomeStuff() method. Complicated, I know. I'll break it down a little below. For now, note that the stuff in lines 0-23 (using the internal line numbers, not the DaniWeb numbers) is overly complicated because it's calling up the println method. Skip all that, and we'll look at the stuff starting with 26.

public void doSomeStuff();
  Code:
   Stack=2, Locals=6, Args_size=1
   0:	getstatic	#4; //Field java/lang/System.out:Ljava/io/PrintStream;
   3:	getstatic	#5; //Field staticInt:I
   6:	invokevirtual	#6; //Method java/io/PrintStream.println:(I)V
   9:	getstatic	#4; //Field java/lang/System.out:Ljava/io/PrintStream;
   12:	aload_0
   13:	getfield	#7; //Field FINAL_INT:I
   16:	invokevirtual	#6; //Method java/io/PrintStream.println:(I)V
   19:	getstatic	#4; //Field java/lang/System.out:Ljava/io/PrintStream;
   22:	iconst_3
   23:	invokevirtual	#6; //Method java/io/PrintStream.println:(I)V
   26:	iconst_4
   27:	istore_1
   28:	iload_1
   29:	iload_1
   30:	iadd
   31:	istore_2
   32:	getstatic	#5; //Field staticInt:I
   35:	getstatic	#5; //Field staticInt:I
   38:	iadd
   39:	istore_3
   40:	aload_0
   41:	getfield	#7; //Field FINAL_INT:I
   44:	aload_0
   45:	getfield	#7; //Field FINAL_INT:I
   48:	iadd
   49:	istore	4
   51:	bipush	6
   53:	istore	5
   55:	return

The following lines:

26:	iconst_4
   27:	istore_1
   28:	iload_1
   29:	iload_1
   30:	iadd
   31:	istore_2

correspond to these lines in the source:

int instanceInt = 4;
      int newVar = instanceInt+instanceInt;

iconst_4 loads the constant value 4, and the following line stores it in a local variable on the stack, at offset 1 (istore_1). iload_1 loads the local variable from offset 1 and puts it on the stack. We load it twice in this case, so we now have two copies of "instanceInt" on the stack. iadd takes the top two items from the stack and replaces them with their sum. istore_2 puts whatever's on top of the stack in the local variable at offset 2. In this case, what's on top of the stack is the sum of instanceInt+instanceInt, and the destination is "newVar".


And that's how ordinary instance variables look to the virtual machine.

Next, we'll look at statics.

Great, it was great ... :) i really like you reply jon.kiparsky
10x a lot

Moving along, here's what

int newVar2 = staticInt+staticInt;

looks like in the machine:

32:	getstatic	#5; //Field staticInt:I
   35:	getstatic	#5; //Field staticInt:I
   38:	iadd
   39:	istore_3

getstatic loads a static variable. This is a class field, necessarily, because a static is a part of the class, not any particular instance of that class.

Compare this to the jvm code for the lines dealing with FINAL_INT, which is an instance field:

44:	aload_0
   45:	getfield	#7; //Field FINAL_INT:I
   48:	aload_0
   49:	getfield	#7; //Field FINAL_INT:I
   52:	iadd
   53:	istore_3

And when it comes to STATIC_FINAL_INT, here's what we get:

#
51: bipush 6
53: istore 5

You can learn some things about how these are represented in memory by the jvm instructions used to load them. Notice that the three different types are handled in three different ways. The last one is maybe the most interesting. For a static final, the compiler is able to take "get this static field, which is final and equals 3, and get it again, and add the two values together, and store it in slot #5" and reduce that to "load up the nuber 6 and put it in slot 5". Cool, huh? Note also that on lines 44 and 48, you find "aload_0". This is an instruction to "load the reference that's at offset 0", which in an instance method is the reference to the current object, or "this". (No such thing in a static method of course) That reference gets put on the stack, and then getfield is called, as opposed to just a getstatic in lines 32 and 35.
If you look at the JVM spec, you can find out more about the difference between getstatic and getfield, which will tell you something about what's going on here. Also, JLS chapter 8 has more details about what the language requires. The JLS is a pretty good place to go for this sort of thing.

Okay, that's enough of this for one night. This should keep you busy for a few days. Come back with more questions when you've soaked up some of this.

Ah - as for "const", it's a reserved keyword in java, but it doesn't mean anything and it won't parse. "Final" is the equivalent to C++'s "const" declaration.

Not exactly; the "const" of C++ has much more complicated usage than the "final" keyword of Java. More about "const".

One thing you should know about "static final" variables (at least "public static final", but probably also for "static final" and "protected static final", although I haven't tried those), and that is that their values get compiled directly into the classes using them. I.E.

compile both of these classes

package test;

public class bogus1 {
  public static final int a = 1;
}

--------------------------

package test;

public class bogus2 {
    public static void main(String[] args) {
        System.out.println(bogus1.a);
    }
}

Then execute bogus2 and it will print "1", obviously.

Now change bogus1.a to 2 and compile only bogus1 (note do not do this in an IDE as that will automatically compile both classes, per default)

Now execute bogus2 and it will still print "1".

Just a small note of warning.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.