So we've been using the static keyword when declaring variables and
methods throughout this course.
So it's now time to look at what static actually means and why we used it and
why we had to use it in particular places.
So what I've done is I've created a new class as you can see and
I've actually called the package static using a new.
Naming conventions for packages which we talked about earlier in this section.
So let's go ahead now and create a new class.
I'm gonna create a new class,
we're gonna come down here as I normally do into source.
And then right click it, new Java class, we're gonna call it static test.
Like so. And what we're going to do,
it's going to be a public class and we're gonna put private int which
is gonna be num instances, and set that equal to zero.
Row, private string, nine.
We're gonna create a constructor, and we're gonna use the name as a constructor.
What we're also going to do is every time a constructor is used We're gonna talk
numinstances plus plus, so we're gonna increment that variable numinstances.
And then also, we need a getter for the two, so we want
a getter for both numinstances and for the name as well, like so.
So that's it, very basic class.
And so we'll go back now to main and create two instances of the class.
And print out the value.
So I go back to there, and so let's start and
type StaticTest firstInstance = new StaticTest.
And we'll call this one, unsurprisingly, 1st Instance.
Put down original.
So we'll print it out.
We'll go firstInstance.getName()
+ " is instance number
Plus FirstInstance.getNumInstances.
So, and then we'll do static test,
second instance, Equals new static test.
Second instance and print out second instance.
Tuck it name plus is instance
number plus second instance dot get num instances.
So now, if you run this, You
probably may have expected each instance to think it was instance number one,
cuz both have a copy of the number of instances filled.
So when we increment it to the constructor, it becomes one in each case,
because the course We started with numbers is equal zero but
a static field which is also known as a class variable
is associated with the class rather than e with any particular instance of it, so
it's only ever one copy of the variable in memory.
All instances of the class share that one class variable.
So this mean we can get the behavior we originally wanted where this instance
number was incremented every time we instantiated a new object from this class,
by coming back here and changing the variable num instances to static.
So we make that a static num instance is equal to 0 and
not changing any other code.
Go back to Main and we run that again.
You can see now on the screen that we've got numInstances is number one for
the first instance.
And Incident number two is now for second instance.
And just to confirm, we can also create a third one if we wanted to.
[SOUND]
Third instance and
third instance.
Guys, if you run that now.
And we currently get first instance is set instance number one,
second is second, third to third.
So I'm still working as you can see.
We've got a single variable with static variable numInstances and
any one version of that exists in memory at any given time.
Now, you may or may not have noticed, if you're pretty sharp, that I didn't
change this variable here, the second instance, yet the program still worked?
So, why, if we're leaving that the second instance when we're calling
the third instance, does it still record or return, rather, the correct value?
Well, the reason it returned it is because they're all sharing the same
copy of instances, so it doesn't matter.
Which instance of the class we use to access a static field,
it's always going to return that what is then the valid number.
So one, two, and three, again, and likewise I could have changed that to
third instance which would've been technically correct, and run that, and
again, we still get the same numbers coming back and that's because we're still
only sharing one copy of that variable with all instances of the class.
Now it's a little bit odd that we can do that.
And if you come across code like that you probably have to stop and think for
awhile just to make sure it isn't a bug.
It's really bad practice,
leaving that error there is I I think it's really bad practice and
it's not something you'd really want to do even though it's perfectly valid.
It's much better to use the class time and
make it clear because what you're accessing is a so
in other words changing this to what should have been third instance.
Now, if you're using a method that only works on static fields,
it makes far more sense to make that method also static, and that means that we
can then access the method without having to use a classes instance to do so at all.
So what we're gonna do is we'll go back in to change the class On a static test
class, and we'll change get num instances to static, and we'll put static there.
So that's now public static int getNumInstances.
Still returning the same variable, numInstances.
But what that means is by doing that, we can go back to our main class, and
instead of having this instance name, we can do something like this.
We can put static Test.
[SOUND] Static test.
[SOUND] Static test like so,
and it makes it clear now, because you're saying that it's the class name, and
it's not using the instance name, [INAUDIBLE] instance.
That this is a static method, and
incidentally you have used static methods before.
When we use the integer.pass int method from the interface's challenge, for
example, pass int is a static method of the integer class.
And as a result,
we can use that without having a particular integer to call it from.
So just as a recap, static methods and fields belong to the class,
not to instances of the class, and as a result, can be called by referencing
the class name, as you see here, rather than a class instance.
This explains why the main method we've used throughout the course has
to be static.
This red on line five, because when we want to run a Java program there has to be
an entry point, in other words a method that is executed when the program runs.
However, until the program runs there's no classed instances to call methods on, so
Java has to use this static method that can be called from the class name rather
than from a class instance, so that's a reason, again, why Of the main methods.
The main method is marked as static.
So when we run our sample program in IntelliJ,
what IntelliJ does is invokes a Java executable and
passes to it the name of the class that contains the public study board main.
So provided you actually build the project, you can run the program from
the command line by changing it into the project production directory.
And then typing something like from a command line,
you type Javacom.company, company._static.main.
The Java will then expect main to have a static method called main with
the exact signature that we have been using throughout the course.
Now the main method doesn't have to be Class code main, it can exist in any of
the classes, but the convention is to put it in a class code main.
And if we're given a project containing hundreds of classes to work on,
you will at least know where the program starts by looking for
the main class rather than having to check every other on to find the main method,
and that's why it's sort of a standard convention.
So this example would be just running it from the command line we're not gonna do
that now But
that's how you would invoke it if you wanted to do it from the command line.
So now that we understand static methods and fields, and
these are sometimes referred to as class methods and class variables,
we can work out why all the methods we've created in main have also been static.
So what we're gonna do is use another example to discuss what's
happening and why.
Let's go ahead now and change this code.
I'm gonna cover this code out for now.
[NOISE] And let's come down here and
we'll put public int multiplier = 7.
Actually we'll make that a field in this class.
So put this at the top.
Like so and then we'll create a method called multiply so in public int
multiply and that accepts a parameter of a number,
returns the number times the multiplier.
So, and this is a slightly contrived example
that doesn't really do anything useful.
What it will do is help you to show what we can and can't do with static methods.
So as you can see, the public method multiply takes a number and
returns the result of multiplying it with the public multiplier field
that we defined on line five.
Now we've made multiplier public so
there's no confusion stemming from its visibility.
So let's call the method now in Main.
Here and see what 6 times 7 is.
So I'm going to do something like int answer equals multiply 6.
[SOUND] And Put down a message,
the answer answer.
No in theory, that code looks good, but intellij's showing an error.
And if we look at that, I'll call up the error.
Non-static method multiply int can't be referenced from a static context.
And we get a similar error if we try to do something like this.
Similar error,
non static field multiplier can't be referenced from a static con Context.
So if multiply is public, then why can't we access it from our main method?
Well as we've seen, normal class fields require an instance of the class
that don't actually exist until an instance has been created.
Now the main method Is static as we can see.
And it can be called with the class instance.
So as a result, Java can't allow a static method to access non-static fields or
methods because frankly they don't exist when the static Methods called.
So in many of our examples in earlier lectures,
what we did was we created methods for main to call.
And in order for that to work, we had to make the methods static.
And we're gonna do that here now, so that your program can actually work.
So the way we would get around that.
First we would make our variable, our field, static.
And also down here, we can make our method static as well.
So now that we've done that, we're calling a static method and
accessing a static field, everything should work fine.
And when we run it, we correctly get the answer 42, and we can see we're
now able to access multiplier because we've set it as static as well.
So note that the reverse is not true, and there's no reason why it should be.
So there's no problem at all with a nonstatic instructor
of the StaticTest class like here.
There's no problem with that accessing the static NumInstances field.
And we can also call the static methods from nonstatic ones With no problems.
You note that there's nothing to prevent a static method
from accessing nonstatic fields and methods in another class
because it creates in instance of a class in order to do so.
Now the restriction is purely on a static method Access non-static methods and
fields in it's own class.
So there's one more aspect of static that we need to look at, and
that's static initializers.
Now in the discussion of these, also need to consider final fields.
So we'll come back to static initializers in the next lecture
after we've discussed the final keyword.
So we'll see you in that next video.