This forum is in archive mode. You will not be able to post new content.

Author Topic: [Java-Paper] static and non-static  (Read 2717 times)

0 Members and 1 Guest are viewing this topic.

Offline Deque

  • P.I.N.N.
  • Global Moderator
  • Overlord
  • *
  • Posts: 1203
  • Cookies: 518
  • Programmer, Malware Analyst
    • View Profile
[Java-Paper] static and non-static
« on: June 13, 2012, 06:42:56 PM »
Understanding the difference between static and non-static variables and methods is vital for understanding object oriented programming. This paper uses Java-examples and has two parts: What is an object? What is static and non-static?
The first part is important to understand the second, so don't skip it.

What is an object?

Like in the real world an object is something, that has a special behaviour and attributes.
Here are some examples of objects and their attributes:



The behaviour is not shown here, but some examples are:

Carl can talk, walk, eat, sleep.
Carl's car can be driven, otherwise it just stands around.
Little flower has the ability of photosynthesis and turns its head to the light.

So in summary an object is defined by its behaviour and its attributes.

As you also know, Carl is not the only object in the world that behaves like that. There are other, similar ones, who also eat, sleep, talk and walk.



These objects also have the same attributes, but their values can be different. So Carl has a driver's license, whereas Olef has not. Henrietta has another age than Carl and Olef.

Objects of the same type have the same behaviour and the same attributes, but the values of their attributes (the data itself) can be different.

In Java (also C++, C# and other) you can create a plan for an object type. You do this by defining a class. The following example code shows the plan for the objects of the type Person:

Code: (Java) [Select]
public class Person {

    private String name;
    private int age;
    private boolean driversLicense;

    public void talk() {
        System.out.println(name + " talks");
    }

    public void walk() {
        System.out.println(name + " walks");
    }

    public void eat() {
        System.out.println(name + " eats");
    }

    public void sleep() {
        System.out.println(name + " sleeps");
    }
}

The class Person defines the behaviour (the methods) and the attributes that are the same for every object of the type Person.
However the behaviour is not exactly the same. Although every Person can talk, walk, eat and sleep they do it in their own way. Carl is very slow in walking (which is the reason he got a drivers license in the first place) whereas Olef runs all the time. Henrietta has some problems with her foot, so she rather doesn't run, but she isn't slow either. The walking speed is an attribute, that alters the behaviour of walking for every object of the type Person. But still--every object of the type Person walks, so they have the same behaviour, they just do it in a different way.

Code: (Java) [Select]
public class Person {

    private String name;
    private int age;
    private boolean driversLicense;
    private int walkingSpeed;

    public void walk() {
       
        if (walkingSpeed > 10)
            System.out.println(name + " runs");
       
        else if (walkingSpeed > 5) {
            System.out.println(name + " walks at normal speed");
       
        } else {
            System.out.println(name + " walks at a slow pace");
        }
    }
}

The attribues name, age, driversLicense and walkingSpeed are instance variables (or non-static variables). That is, because their value can be different for every object of the type Person.

Saying "an instance of the class Person" is the same as saying "an object of the type Person". So if you create an instance of Person, you use the class Person to actually create an object. How can you do this? First thing you need to know: If you create an object, the constructor of this object is called. If you have no constructor, a default constructor is used, that does just nothing, like this one:

Code: (Java) [Select]
public class Person {

    private String name;
    private int age;
    private boolean driversLicense;
    private int walkingSpeed;

    public Person() { //constructor

    }

}

In our case, we would like to set the data of the object, when we create it. Once a person is born, the attributes name, age, walkingSpeed and driversLicense shall have values specified by us. This can be done with arguments in the constructor:

Code: (Java) [Select]
public class Person {

    private String name;
    private int age;
    private boolean driversLicense;
    private int walkingSpeed;

    public Person(String name, int age, boolean driversLicense, int walkingSpeed) {
        this.name = name;
        this.age = age;
        this.driversLicense = driversLicense;
        this.walkingSpeed = walkingSpeed;
    }

}

Everytime an object of Person is created you also have to specify its data by setting the arguments of the constructor. This is how you can create Henrietta, Carl and Olef (which are objects of the class Person):

Code: (Java) [Select]
Person henrietta = new Person("Henrietta", 45, true, 6);
Person olef = new Person("Olef", 23, false, 16);
Person carl = new Person("Carl", 23, true, 2);

Now that you know the difference between a class and its instance (object), we can go to the second part.

What is the difference of static and non-static?

In Java every method and variable that doesn't have the word "static" in its declaration, is non-static. So the methods and variables we already defined for Person are all non-static.
What does that mean? It means they belong to the object itself. If Carl turns 24 next month, it doesn't mean that Olef also turns 24 next month. He might still be 23 years old.

But sometimes you want a variable that is shared by all objects of a class. In that case you need a static variable. An example is a Person register, that counts every object of Person that was ever created. This is how to do it:

Code: (Java) [Select]
public class Person {

    private String name; //non-static variables
    private int age;
    private boolean driversLicense;
    private int walkingSpeed;

    private static int counter; //a static variable

    public Person(String name, int age, boolean driversLicense, int walkingSpeed) {
        this.name = name;
        this.age = age;
        this.driversLicense = driversLicense;
        this.walkingSpeed = walkingSpeed;
       
        counter++; //this increments the counter for every object that is created
    }

}

The counter belongs to the class, which is the reason you call it class variable. It also exists, if you never created an object of Person. In that case the counter is just 0--no person was created.
Non-static variables on the other hand only exist with and belong to their objects. If you never created a Person object, you can not ask for the age of Person. Imagine someone does this and asks for the age of the class Person:

Code: (Java) [Select]
System.out.println(Person.age); //wrong: static access to a non-static variable
The age of which Person? That is the question that should pop into your mind and that is also the reason the compiler will complain about your stupid question if you try something similar.

What you can do is this:

Code: (Java) [Select]
Person henrietta = new Person("Henrietta", 45, true, 6);
System.out.println(henrietta.age);

That makes sense. You ask for the age of henrietta. I can tell you that it is 45. No problem.

Back to the counter. The counter is static, it is always there, it is the same for every object, because it doesn't belong to a special object. It belongs only to the class Person.

Here is how you should ask for the number of Persons ever created (the counter):

Code: (Java) [Select]
System.out.println(Person.counter); //correct: static access to a static variable
Java also allows this, but it is bad code:

Code: (Java) [Select]
Person henrietta = new Person("Henrietta", 45, true, 6);
System.out.println(henrietta.counter); //works, but is bad: non-static access to a static variable

Here you ask the computer: What is the number of persons for henrietta? The computer understands your question and will give you an answer, but it also will give a sniff at the weird question. The number of persons has nothing to do with henrietta. You don't need henrietta to ask for the value of the counter. So the compiler tells you in a warning: The static field Person.counter should be accessed in a static way

Now what about static and non-static methods? It is exactly the same I told you about variables. Static methods belong to the class, whereas non-static methods belong to an instance of the class.

We used non-static methods for walk, talk, sleep and eat, because its behaviour depends on non-static variables of the objects.

Code: (Java) [Select]
   
public void walk() {
       
        if (walkingSpeed > 10)
            System.out.println(name + " runs");

        else if (walkingSpeed > 5) {
            System.out.println(name + " walks at normal speed");

        } else {
            System.out.println(name + " walks at a slow pace");
        }
}

As you can see, the method walk() uses the values of name and walkingSpeed. These values can only be determined, if you know which Person you are talking about. By making the method walk() non-static you ensure, that it is accessed via an object, like this:

Code: (Java) [Select]
Person henrietta = new Person("Henrietta", 45, true, 6);
henrietta.walk(); //uses the object henrietta to call walk()

This way the compiler knows, that the values of henrietta have to be used to perform the walking and the computer will print out "henrietta walks at normal speed" because her walking speed is 6.

If you try this, the compiler will get angry:

Code: (Java) [Select]
Person.walk(); //wrong, static access to non-static method
Which person shall walk? I don't know how to walk without knowing the name and walking speed of the person!

You might get the idea to turn the walk method into a static one like this:

Code: (Java) [Select]
public static void walk() {
       
        if (walkingSpeed > 10)
            System.out.println(name + " runs");

        else if (walkingSpeed > 5) {
            System.out.println(name + " walks at normal speed");

        } else {
            System.out.println(name + " walks at a slow pace");
        }
}

But the compiler is not stupid. By making this method static, you tell the compiler, that you want to access walk() like this:

Code: (Java) [Select]
Person.walk();
So the compiler knows, you will not specify a special person and it knows, you can not ask for non-static variables like name and walkingSpeed without knowing which person it is. So again, it will get angry and complain like this:
Cannot make a static reference to the non-static field walkingSpeed

For that reason you can only use class variables in a static method. You are not allowed to use instance variables.

A little Exercise: Every person can have a car. I.e. Carl has a car called "Carl's car". So if you implement this fact in Java, you would create a class Car like this:

Code: (Java) [Select]
public class Car {

    private String name;
    private String color;
    private String make;
   
    public Car(String name, String color, String make){
        this.name = name;
        this.color = color;
        this.make = make;
    }
}

You also have to add an attribute of the type Car to the class Person.
Would this attribute be static or non-static?
What happens if you make the car attribute static and Henrietta paints her car pink? Does that affect Carl's car?

I hope this made the difference between static and non-static more clear. Once you get the grasp, it is not that difficult. Just remember that a class and an object is not the same. Think of the class Person and its objects Henrietta, Carl and Olef to help you.

Deque
« Last Edit: June 13, 2012, 09:54:32 PM by Deque »

Offline Kulverstukas

  • Administrator
  • Zeus
  • *
  • Posts: 6627
  • Cookies: 542
  • Fascist dictator
    • View Profile
    • My blog
Re: [Java-Paper] static and non-static
« Reply #1 on: June 13, 2012, 07:42:37 PM »
Love your drawings! but they could be made a bit smaller.
Very nice explanation about static and non-static. Didn't think of using an object counter (duh) in some occasions. Btw did you hear about the "Singleton" object model? the thing is fucked in logic but comes in really handy :D
Basically a singleton is a static object definition that contains itself - object contains itself (like a person with a soul I guess :D).
Hope this example can explain a bit better:

Code: (java) [Select]
public class HistoryBrowser {
    public static HistoryBrowser historyBrowser = null;
    private HistoryBrowser() {
// this hides the normal constructor
    }
   
    public static HistoryBrowser buildHistoryBrowser() {
if (historyBrowser == null) {
    historyBrowser = new HistoryBrowser();
}
return historyBrowser;
    }
}


Offline Deque

  • P.I.N.N.
  • Global Moderator
  • Overlord
  • *
  • Posts: 1203
  • Cookies: 518
  • Programmer, Malware Analyst
    • View Profile
Re: [Java-Paper] static and non-static
« Reply #2 on: June 13, 2012, 10:20:13 PM »
Thanks, Kulver. I made the pics a bit smaller. Could still be smaller I think, but well.

Quote
Btw did you hear about the "Singleton" object model?

Yes, I know it, but I never really used it.

Quote
Basically a singleton is a static object definition that contains itself - object contains itself

No. The class (not the object) contains one instance of itself and doesn't allow any other instance to be created.

Let me change the code example a bit in case you ever use threads (I didn't run this code):

Code: (Java) [Select]
public class HistoryBrowser {

    private volatile static HistoryBrowser historyBrowser; //this shouldn't be public

    private HistoryBrowser() {
        // this hides the normal constructor
    }

   //you only create the instance once, so I changed the name
    public static HistoryBrowser getHistoryBrowserInstance() {
        if (historyBrowser == null) { // don't go into synchronized block without a reason
            synchronized(HistoryBrowser.class) {
               if (historyBrowser == null) { //you have to check again in case of a simultaneous first call
                  historyBrowser = new HistoryBrowser();
               }
            }
        }
        return historyBrowser;
    }
}

Thanks for your feedback, Kulver.
« Last Edit: June 13, 2012, 10:24:13 PM by Deque »

Offline p_2001

  • Royal Highness
  • ****
  • Posts: 684
  • Cookies: -64
    • View Profile
Re: [Java-Paper] static and non-static
« Reply #3 on: June 14, 2012, 12:23:39 PM »
good paper..


I think you missed static blocks and an elaboration on static methods would be good too, although a bit of thinking clears that one without further explanation.

we can declare a code block as "static", and it executes when the class is "loaded" in the memory, before the object is created and the constructor called.

This way a piece of code can be executed before the object is created. Also a static block is perhaps the only way to execute code without the presence of main().


something like

Code: [Select]
public class StaticExample
{
static {

            System.out.println("this is a static block");
          }
}

This will be executed just after the class is loaded..

like..

java StaticExample

output : this is a static block


Thus a class can run without using main.. though I don't know any particular use fort that.

although static block itself has many uses.
« Last Edit: June 14, 2012, 12:24:32 PM by p_2001 »
"Always have a plan"

Offline Deque

  • P.I.N.N.
  • Global Moderator
  • Overlord
  • *
  • Posts: 1203
  • Cookies: 518
  • Programmer, Malware Analyst
    • View Profile
Re: [Java-Paper] static and non-static
« Reply #4 on: June 15, 2012, 08:56:48 PM »
Thank you, p_2010.

Quote
I think you missed static blocks and an elaboration on static methods would be good too

Hm, I thought I had covered static methods. Maybe I made not clear enough that they behave just the same way.
For the static blocks--I don't think it is necessary explaining them for this paper. I wrote it, because some people really got confused about the differences of static and non-static and they didn't know when to use which and why some errors occured. So I concentrated on making that clear and leaving away everything that doesn't help with that. Static blocks are relatively rarely used and would have just have added some confusion, I think.

Offline p_2001

  • Royal Highness
  • ****
  • Posts: 684
  • Cookies: -64
    • View Profile
Re: [Java-Paper] static and non-static
« Reply #5 on: June 15, 2012, 09:19:44 PM »
^^^

yup, I can see that now... although when I learned java, I was confused in static functions a lot and not in static classes.

same goes for static blocks... I was confused with the title and did not think that you were trying to emphasize upon the more commonly used and confusing part of static. I thought that you forgot to mention them.. not that it was really needed, considering their rarer use.
"Always have a plan"

Offline begueradj

  • NULL
  • Posts: 1
  • Cookies: 0
    • View Profile
Re: [Java-Paper] static and non-static
« Reply #6 on: June 19, 2012, 05:04:46 PM »
that is good, man

 



Want to be here? Contact Ande, Factionwars or Kulverstukas on the forum or at IRC.