non-static variable bankAcc cannot be referenced from a static context [duplicate] - java

This question already has answers here:
What is the reason behind "non-static method cannot be referenced from a static context"? [duplicate]
(13 answers)
Closed 9 years ago.
I'm fairly new with Java and I'm having some trouble understanding what I'm doing wrong. Here is a brief description of the purpose of the program.
Make a bank account.
Deposit 1000 into it.
Withdraw 400.
Withdraw 500.
Print out results and expected results.
Here is my code. Keeps on saying non-static variable bankAcc cannot be referenced from a static context.
public class BankAccountTester
{
private double bankAcc; //Stores bankAcc balance
public void money(double deposit)
{
deposit= (1000);
int withdraw1 = -400;
int withdraw2= -500;
bankAcc= bankAcc + withdraw1 + withdraw2;
}
public double getbankAcc()//Returns value to bankAcc so it has new balance
{
return bankAcc;
}
//Prints out value and expected value
public static void main(String[] args){
System.out.Println("My bank account has " + bankAcc);
System.out.Println("Expected is 100");
}
}

main() is a static method i.e. no class instance is associated with it. While bankAcc is an instance member of BankAccountTester class and hence cannot be accessed without creating its instance first. Test your program with an object instance available as:
public static void main(String[] args){
BankAccountTester bat = new BankAccountTester();
bat.deposit(0.0);
System.out.Println("My bank account has " + bat.getbankAcc());
System.out.Println("Expected is 100");
}
Also, see here.

When you write a class, there are two "flavours" of class content. Static, which exists as global properties tied to "the class" and non-static, which lives on individual objects that you build using that class definition. As such, your code -to java- looks like this:
for objects: private double bankAcc, public void money, public double getbankAcc
for global class access: public static void main
static code exists irrespective of whether any objects have been built, so you can't tell a static method that it should access an object variable: it doesn't exist as far as it knows. Even if you do create an object from this class, it will locally have a variable called backAcc, but it's not statically accessible.
The general recipe you want to follow is this:
public class Test {
private long whatever = 123456;
public Test() {
// real code goes here.
System.out.println("my whatever variable holds " + whatever);
}
public static void main(Sting[] args) {
// build an object based on the Test class.
// and let it handle everything else.
new Test();
}
}
When you compile and run this code, the Test class will have a static (=globally callable) method main, which builds an actual Test object. Before you do, there are objects to work with, only the class definition exists. Once you build a Test object, it can then do everything you need to do, in a nice object-oriented way.

First, static (re. a variable) means that there exists one global instance of that variable for the class. This is opposed to simply private double bankAcc;, which is saying that each instance of the class has its own bankAcc.
More particularly to your problem, since main is static, it is not a method on an instance of BankAccountTester. This means that, when you are trying to print out bankAcc, you are trying to access a non-static variable from a static context, which is not allowed.
Without seeing where exactly you use money and getbankAcc, you can fix this by changing:
private double bankAcc;
to:
private static double bankAcc;

The variable bankAcc is an instance variable, meaning that it only exists when you create an instance of BankAccountTester (using new BankAccountTester()). Since you are only calling it from the static main() method without creating an instance, there is no bankAcc variable. Change the declaration to private static double bankAcc; to make your program work.

Since main is a static method, it can only refer to static variables and methods. A static variable looks like:
private static double bankAcc;
As you have it written, bankAcc is an instance variable, meaning it's tied to a specific instance of BankAccountTester.
Since you don't have any instances (i.e., you have not created a new BankAccountTester()), you can only refer to the static parts of BankAccountTester.

This is basic Java. That's why someone has voted your question down. But here's the answer.
In Java, the most common way to execute code is to reference a class that contains a main method when starting a JVM via the java command. For instance:
java com.me.MyClass
This will start a jvm and look for a main method on MyClass to execute. Note, main method is static.
On the other hand, Java classes most commonly define "classes". These are the definition of object structure. An object is a runtime instance of a class, complete with it's own memory. Your field bancAcc is an instance field, as opposed to a static field. That means each object instance of your class BankAccountTester will have it's own dedicated memory for hold a value of a bankAcc. Note, this doesn't exist unless you create an ojbect.
So, in your code, you haven't created an instance object. You could do so with the new constructor, and then reference the bankAcc on that instance object; note, there is no bankAcc unless there's an instance object. So . . .
BankAccountTester accTester = new BankAccountTester();
accTester.bankAcc = 100.00;
System.out.Println("My bank account has " + accTester.getBankAcc() );
Note, you have been confused because you have wrongly assumed that the main method's existence in your class has something to do with the class defined therein. The placement of the main here is arbitrary and unrelated to your actual class definition. To clarify it in your head, you should create two classes, one that defines the bank account, and another that is your "bootstrapper" class.
The bootstrapper will contain ONLY a main method, and it will create instances of the objects, defined by classes found in separate class files, and execute methods on them.

Related

How to get information back and forth between classes?

Hello im learning how to handle multiple classes in one code but here is a problem i couldnt figure out how it is called nor an answer to it. So i have one variable x in Back class, i get it to the main then i want to push it back to the back class and then again pull it to the main. Its a simplified code so i can use it as an example to change variables in other classes depending on certain condintions. Currently its not working.
package Classes;
public class Main {
public static void main(String[] args) {
Back Q = new Back();
double f = Q.x;
System.out.println(Q.g);
}
}
//-------------------
package Classes;
public class Back {
Main K = new Main();
double x = 10;
double g= K.f; //f cannot be resolved or is not a field
}
First of all you need to read more about access modifiers in java. There are few main things that you must understand:
Difference between static and non-static members;
Difference between different access levels (public, protected, package-private/default and private);
Local variables.
These things can help you to decide what type of variables you need.
Right now you're trying to get an access from a static main method to a non-static package-private variable in a neighbor class via newly created object, and is ok.
But you also try to get an access from the inside of a non-static object to a local variable that is defined in a static method - this is impossible. Instead, it is probably better to introduce setter methods or introduce other methods that accept external parameters.
The attribute x in class Back is package-private, so it can be accessed directly via the Back object called Q you create in main().
In the class Back you try to access the attribute f of the class Main which is references by the object called K. But the class Main does not define any attributes.
You only have a local variable called f in the scope of the main() method that has been definied in class Main.
A possible solution could be something like this. But I don't know what problem you want to solve with your code. So here is just an idea that should compile...
package Classes;
public class Main {
double d = 5.0;
public static void main(String[] args) {
Back Q = new Back();
double f = Q.x;
System.out.println(Q.g);
}
}
//-------------------
package Classes;
public class Back {
Main K = new Main();
double x = 10;
double g = K.d;
}

Strugling with the keyword this in Java

I've read a lot of explanations for the use of keyword 'this' in java but still don't completely understand it. Do i use it in this example:
private void login_BActionPerformed(java.awt.event.ActionEvent evt) {
if(user_TF.getText().equals("admin")&& pass_PF.getText().equals("admin")){
this.B.setVisible(true);
}else{
JOptionPane.showMessageDialog(null, "Warning!", "InfoBox: "+"Warning", JOptionPane.INFORMATION_MESSAGE);
}
this.user_TF.setText("");
this.pass_PF.setText("");
}
It's supposed to open a new window if a user and pass match. Do i use 'this' keyword anywhere here?
I think there are two main usages you should know:
If you have a class variable with name N, and a method variable with name N, then to distinguish them, use this.N for class variable and N for method variable. Screenshot displaying possible usage
Imagine you have 2 constructors. One takes String name, another takes name + age. Instead of duplicating code, just use this() to call another constructor. Another screenshot displaying the usage
In your case, I don't see any LOCAL (method) variables of name 'B', so I guess you can do without it.
Any non static method of the class needs an object of that class to be invoked. Class has the blueprint of the state and behavior to modify and read the state. Object is the realization of this blueprint. Once object is created , it has those states and methods.
Suppose you have below code.
public class A{
int property;
public void foo(){
bar();
}
public void bar(){
property = 40;
}
}
public class B{
public static void main(String[] args){
A obj = new A();
obj.foo();
}
}
Lets try to answer few questions.
Q1. Inside the mwthod foo we invoke bar , we have not used any explicit object to invoke it (with . dot operator), upon which object is the method bar invoked.
Q2. Method bar tries to access and modify the variable named property. Which object does this state called property belong to ?
Answers
A1. Object referred by A.this (it is same as this) . It is the object which has invoked foo method which is implicitly made available insode the called method. The object upon which execution of the method takes places can be accessed by this.
A2. same as answer to Q1.
The object at anytime can be accessed by Classname.this inside the non static methods or blocks of the class.

Java: initialization sequence of object

There is a code which is given as a task for a junior Java developers. I use Java during five years and this piece of code completely confusing me:
public class Main {
String variable;
public static void main(String[] args) {
System.out.println("Hello World!");
B b = new B();
}
public Main(){
printVariable();
}
protected void printVariable(){
variable = "variable is initialized in Main Class";
}
}
public class B extends Main {
String variable = null;
public B(){
System.out.println("variable value = " + variable);
}
protected void printVariable(){
variable = "variable is initialized in B Class";
}
}
The output will be:
Hello World!
variable value = null
But if we change String variable = null; to String variable; we will have:
Hello World!
variable value = variable is initialized in B Class
The second output is more clear for me.
So, as far as I know the sequence of inizialisation in Java like this:
We go to the root of the class hierarchy (for Java it is always Object class), when we come to this root parent class:
All static data fields are initialized;
All static field initializers and static initialization blocks are executed;
All non-static data fields are initialized;
All non-static field initializers and non-static initialization blocks are executed;
The default constructor is executed;
Then we repeat the procedure for the underlying child class.
Also there is post which describes the behavior of the this keyword in context of a superclass - Calling base class overridden function from base class method
Based on the rules given above, I assume to have sequence like this:
We are going to create a new instance of class B;
We go to the part class Main;
Initialize main.variable with null;
Then we move to the default constructor of class Main;
Constructor calls method b.printVariable() in class Main; (Why doesn't it call main.printvariable? We don't have this key word here.)
The field b.variable "variable is initialized in B Class"
Now we come back to the class B;
We should initialize field b.variable with null value, am I right?;
The default constructor of class B executed
Please, can someone give a complete and full explanation of how this inheritance inizialisation sequence works. And why changing String variable = null; to String variable; leads to another output.
The sequence is:
Main -> "Hello"
Main -> new B()
B() -> Main() -> b.printVariable() -> sets the variable
Back to initialising B, so variable=null occurs.
So basically, the super object Main() is constructed before any intialisation events of class B. Which means variable=null occurs later. This makes sense as otherwise B could break the initialisation of Main.
Joshua Bloch covers a lot of good ground in his effective java book about how dangerous inheritance is to get right, I would recommend it.
First, you need to understand, what happens when you write variable = null;. When is that code executed. This basically determines the output.
Before I begin, I should also mention that when you create an object of class B, the printVariable() function of the main class is not called. Instead, always the printVariable() of B will be called.
Keeping this in mind, when you have variable = null, the execution for B's constructor will begin. First Main() will be called, which will call the printVariable() method. At last, variable=null, will be called overwriting the variable variable.
In the other case, where you do not initialize variable=null, the variable set by the printVariable() function will not be overwritten, hence you get what you were expecting.
In summary, this is the order of execution of statements, when you do new B():
Main() //super constructor
B#printVariable()
initializtion of variables in B's constructor (if any) [i.e. variable=null, if present]
This is a nice exercise! But it's not a fair question to ask junior developers. This one is for seniors. But to make this text useful during the technical interview, I'd modified it by adding an argument to the Main's constructor:
public Main(String something){
printVariable();
}
If the person will answer what will happen, then remove the argument and ask the original questions. If the person won't answer - there is no need to continue - s/he is junior.
You can also remove the protected qualifier in class B and ask what will happen if you have a goal not to hire this person :)

What's the usage of static field in Java?

From the question What's the meaning of System.out.println in Java? I found that out in System.out.println is a static field.
From C/C++ background, it's easy to understand static method, as it's the same as function in C. However, I'm not sure the use case of static field.
Is it just a way to use multiple methods without instantiating an object just as we use System.out.println without instantiating anything? Or is there any use cases for static field?
static variables/methods not only have the property of being used without instantiation, but they are also consistent across multiple instances.
For example,
public class A {
public int a = 1;
public static int b = 2;
}
Now, when I do A a1 = new A() and A a2 = new A(), A.a gets 2x the memory and is stored in the object instance, while A.b gets the memory only once and is stored outside the instance.
A prime example of this would be
a1.b = 3;
System.out.println(a2.b);
This will print 3, instead of 2, because a1 changed the value of b for the whole class, and therefore, all the instances.
A static field is a property of the class, which gets allocated on the heap and is independent of a particular object instance.
You could use a static variable to count the number of instances of a class for example.
out is an object of PrintStream.
System is a class in java.lang package
println is an instance method(not a static method) of PrintStream class
To access the field out in System without instantiating System, the field is declared static.
The System class has only one instance of the OutputStream that writes to standard output (called out) so it's a static variable. We don't need more than one instance because there's only one standard output.
A static field, is a field that is set-up and can be get without instantiating a class (using new ClassName()).
For example:
public class MyClass {
public static int number = 1;
}
With the code above, you can get the "number" field using MyClass.number.
public class MyClass {
public int number = 1;
}
Now, you need to instantiate MyClass via constructor. Since there is no constructor declared, you just use new MyClass():
MyClass cl = new MyClass();
cl.number; // <-- The number
Static fields are also known as 'class' fields (as opposed to 'instance' fields).
That means that they are accessible without you needing to instantiate the class first.
So, you can call class methods (like Math.abs() on the Math class) without having to instantiate a Math class. You can also access properties like Math.PI.
Also, changing a class property means that it affects all instances of that class, meaning that every object that was instantiated will see this value change, allowing you to affect them with a single property change.
In addition to the .out var in System, it can either be used as a shared variable that all instances of a class can update
private static int meatballsConsumed;
Or as a general-purpose shared variable
public static String thisSeemsDangerous;
Or as a constant
public static final String FLD_OF_DREAMS = "COSTNER,KEVIN";

Why is there a problem with a non-static variable being read from main?

String name = "Marcus";
static String s_name = "Peter";
public static void main(String[] args) {
System.out.println(name);//ERROR
System.out.println(s_name);//OK
}
ERROR: Cannot make a static reference to the non-static field name
The reason this causes a problem is that main is a static method, which means that it has no receiver object. In other words, it doesn't operate relative to some object. Consequently, if you try looking up a non-static field, then Java gets confused about which object that field lives in. Normally, it would assume the field is in the object from which the method is being invoked, but because main is static this object doesn't exist.
As a general rule, you cannot access regular instance variables from static methods.
To access non-static member variables and functions, you must have a specific object. (e.g. if all that was inside class Bob { ... }, you would need to do something like
Bob bob = new Bob();
System.out.println(bob.name);
inside your main.
name is an instance variable in this case, and you are trying to access it without an object created, so technically name variable doesn't exist in memory, but for a static variable(s_name), its a class variable, it comes into existence once the class is created.

Categories