I have a couple of EXTREMELY basic Java questions that I would like to finally understand, once and for all. I have the following short piece of code:
public class VeryBasicJava{
public static void main(String[] args){
int x = 3;
int y = 4;
swapMe(x, y);
}
private void swapMe(int a, int b){
int a;
int b;
int tmp = a;
this.a = b;
this.b = a;
}
}
When I compile, I get the dreaded "non-static method swapMe(int,int) cannot be referenced from a static context" error. Also, I get "a is already defined in swapMe(int,int)" and "b is already defined in swapMe(int,int)"
What I need to finally get through my thick skull, is the "non-static method" error, how (why) it is caused, and how to avoid it.
Further, I was under the assumption that you could do what I am attempting to do with my 'a' and 'b' variables in the "swapMe" method. I thought I could pass in an 'a' and 'b', but also create new variables 'a' and 'b', and reference them with "this" keyword.
I know this is extremely basic, but these two "issues" are two of the main sticking points I have with Java, and for some reason, cannot seem to properly learn.
Thank you all, for taking the time to read this. Have a great day.
That means that the method swapMe()
is an instance method and you need an instance of the VeryBasicJava
class to invoke it, like this:
VeryBasicJava instance = new VeryBasicJava();
int x = 3; int y = 4;
instance.swapMe(x, y);
Alternatively, you could declare swapMe()
as static
, in that way you won't need to create an instance first:
private static void swapMe(int a, int b)
You have just a few minor problems. You mentioned in a comment that you have some experience with C, so I’ll try to draw some basic analogies. A static
method (such as main
) behaves like an ordinary C function. A non-static
method, however, takes a hidden parameter: this
, which refers to an object on which that method is to operate. When you write a method such as this:
private void swapMe(int a, int b) {
// ...
It really means something like this:
private void swapMe(VeryBasicJava this, int a, int b){
// ^^^^^^^^^^^^^^^^^^^^
// ...
Because the this
parameter is treated specially, there is a special syntax for calling non-static
methods on objects:
myInstance.swapMe(someA, someB);
// ^^^^^^^^^^ ^^^^^ ^^^^^
// this a b
And because swapMe
is not declared static
, it expects to be called like the above.
The fact that main
is declared inside the VeryBasicJava
class does not mean that you automatically have a VeryBasicJava
object. Again, because main
is static
, it is just like an ordinary C function:
void VeryBasicJava_main(...) {
// ...
In order to create an instance of an object, you use new
:
VeryBasicJava vbj = new VeryBasicJava();
This is analogous to malloc
in C:
VeryBasicJava *vbj = malloc(sizeof(VeryBasicJava));
VeryBasicJava_construct(vbj);
With an instance, you can invoke a method:
vbj.swapMe(spam, eggs);
Your other issue is twofold: one of scope, and of members. Scope, as you may know, refers to where a variable exists. Take this function:
1: private void swapMe(int a, int b) {
2: int a;
3: int b;
4: int tmp = a;
5: this.a = b;
6: this.b = a;
7: }
When this method is called, the following things happen:
a
and b
are created, given the values specified in the call to swapMe
.
A new a
is created, local to swapMe
, with the default value 0
. This a
hides the parameter a
, and there is no way to differentiate them.
A new b
is created, also strictly local. It too has the default 0
value, and hides the parameter b
.
tmp
is created, and its value is set to that of the newly declared a
, so it too is 0
.
[see below]
[see below]
The locals a
and b
cease to exist, as do the parameters a
and b
.
In lines 5 and 6, you attempt to use the syntax this.a
to refer to the local a
rather than the parameter. Though this syntax exists in Java, it does not do what you mean. Parameters are treated just the same as local variables, so rather than differentiating between those two categories, this.a
differentiates between locals and members. Now, what are members? Well, say your class declaration contains variable declarations:
class VeryBasicJava {
private int a;
private int b;
// ...
}
That’s just like member declarations in a C struct
:
struct VeryBasicJava {
int a;
int b;
};
What this means is that when you create an instance of VeryBasicJava
:
VeryBasicJava vbj = new VeryBasicJava();
That instance has its own variables a
and b
, which can be used in any non-static
method:
public void print() {
System.out.println("a is " + a);
System.out.println("b is " + b);
}
If you have a local variable with the same name as a member, then you must use this
to explicitly state that you want to refer to the member. This complete program illustrates how to declare, use, and differentiate between members and locals.
class VeryBasicJava {
private int a;
private int b;
private int c;
public static void main(String[] args) {
VeryBasicJava vbj = new VeryBasicJava();
vbj.a = 3;
vbj.b = 4;
vbj.c = 5;
vbj.print(1);
}
public void print(int a) {
int b = 2;
System.out.println("a is " + a);
System.out.println("b is " + b);
System.out.println("c is " + c);
System.out.println("this.a is " + this.a);
System.out.println("this.b is " + this.b);
System.out.println("this.c is " + this.c);
}
}
It will produce this output:
a is 1
b is 2
c is 5
this.a is 3
this.b is 4
this.c is 5
I hope these examples and explanations are helpful.
Your problems stem from not understanding how the object-orientated paradigm works.
The idea is that you define a class, which is a "type of thing". From that class, you create instances, which are effectively examples of that type of thing.
For example, when you create a class "Wallet", that defines how your system will treat wallets (i.e. what they can do, and what you can do with them). You can now create multiple different instances of wallets, that store different values, but still work the same way. (e.g. "myWallet" and "yourWallet" are both Wallets, so you can take money out and put money in etc, but if I check the money in yourWallet, I get a value of 50, whereas if I check the value in myWallet, I get a value of 20)
Now, "static" methods belong to the class. This means that they can't access members variables specific to the class. For example, if I'm keeping track of every wallet in my system, that value doesn't belong to any particular wallet in the class, but it's still involved with that class, so we make it static.
To use my example, if you have two objects of type "Wallet", and one has its "cash" value set to 30, and the other has its cash value set to "25", a static function can't access both values, so it can't access either. You have to give it a particular wallet to access.
The advantage of this method over C's approach is that it ties related functionality together. For example, if you see a C array of ints, you don't really know what they are intended to represent and may do something unexpected with them. But if I give you a Java array of Wallets, you also get the methods that influence how you interact with them. (This is a really stripped down explanation of encapsulation)
One of the principle issues with Java is that it ties everything to a class. This causes a problem for the main method, which has to start the program, because it has no instances yet, but must still be part of the class. Therefore the main method must always be static. This tends to confuse new programmers, as invariably the first thing you do within the main method is create an instance of the class it's "inside".
In your example, you've got no "specific" data. Everything's inside the methods, which means you're effectively trying to write procedural code in Java. You can do this (just declare everything static), but the language will fight you, and you'll write very bad code.
When I was originally starting out with Java, I effectively treated the main() method of a class as if it wasn't part of the class. Conceptually, it helped, because you stop thinking of the non-static stuff as something that's already there (which is your main issue). But my recommendation to you is try reading through this. But there are some very good transition courses out there for learning object-orientated programming, and you may want to invest in them.
Classes are a template for OBJECTS. An instance of a class (i.e. and object) has its own version of variables and methods that are non-static.
static methods and fields are not tied to any specific instance of a class.
So it makes no sense to invoke a class instance method from a static method, without the instance on which you want to invoke the method. In your example, this
is a reference to an instance, but you have no instance....
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With