How to get information back and forth between classes? - java

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;
}

Related

Why Must this method be static(Java)?

For some background, I'm currently on chapter 8 in my book, we finished talking about arraylists, arrays, if statements, loops etc. Now this part of the book talks about call by reference,value and some other pretty neat things that seem odd to me at first.I've read What situation to use static and some other SO questions, and learned quite a bit as well.
Consider the following example my book gave (among many examples)
There is another reason why static methods are sometimes necessary. If
a method manipulates a class that you do not own, you cannot add it to
that class. Consider a method that computes the area of a rectangle.
The Rectangle class in the standard library has no such feature, and
we cannot modify that class. A static method solves this problem:
public class Geometry
{
public static double area(Rectangle rect)
{
return rect.getWidth() * rect.getHeight();
}
// More geometry methods can be added here.
}
Now we can tell you why the main method is static. When the program
starts, there aren’t any objects. Therefore, the first method in the
program must be a static method.
Ok, thats pretty cool, up until now I've just been really blindly putting public in front of all my methods, so this is great to know. But the review small problem on the next page caught my attention
The following method computes the average of an array list of numbers:
public static double average(ArrayList<Double> values)
Why must it be a static method?
Here I was like wait a sec. I'm pretty sure I did this without using static before. So I tried doing this again and pretty easily came up with the following
import java.util.ArrayList;
class ArrList
{
private double sum;
public ArrList()
{
sum = 0;
}
public double average(ArrayList <Double> values)
{
for(int i = 0; i < values.size() ; i++)
{
sum+=values.get(i);
}
return sum / values.size();
}
}
public class Average
{
public static void main(String [] args)
{
ArrList arrListObj = new ArrList();
ArrayList<Double> testArrList = new ArrayList<Double>();
testArrList.add(10.0);
testArrList.add(50.0);
testArrList.add(20.0);
testArrList.add(20.0);
System.out.println(arrListObj.average(testArrList));
}
}
TLDR
Why does my book say that public static double average(ArrayList<Double> values) needs to be static?
ATTEMPT AT USING STATIC
public class Average
{
public static void main(String [] args)
{
ArrayList<Double> testArrList = new ArrayList<Double>();
ArrayList<Double> testArrListTwo = new ArrayList<Double>();
testArrList.add(10.0);
testArrList.add(50.0);
testArrList.add(20.0);
testArrList.add(20.0);
testArrListTwo.add(20.0);
testArrListTwo.add(20.0);
testArrListTwo.add(20.0);
System.out.println(ArrList.average(testArrList));
System.out.println(ArrList.average(testArrListTwo)); // we don't get 20, we get 53.3333!
}
}
It doesn't.
The only method which needs to be static is the initial main() method. Anything and everything else is up to you as the programmer to decide what makes sense in your design.
static has nothing to do with public accessors (as you allude to), and it has nothing to do with the technical operation being performed. It has everything to do with the semantics of the operation and the class which holds it.
An instance (non-static) method exists on a particular instance of a class. Semantically it should perform operations related to that specific instance. A static method exists on a class in general and is more conceptual. It doesn't do anything to a particular instance (unless it's provided an instance of something as a method argument of course).
So you really just need to ask yourself about the semantics of the operation. Should you need new instance of an object to perform an operation? Or should the operation be available without an instance? That depends on the operation, on what the objects represent, etc.
If it is not static, then any other class that wants to use this method must first create an instance of this object.
From some other class:
Average.average(new ArrayList<Double>()); // legal only if static
new Average().average(new ArrayList<Double>()); // necessary if not static
// and only makes sense if Average can be instantiated in the first place
It's legal to make it an instance (i.e. not static) variable, but the method is actually harder to understand. If it is static then whoever reads the code knows it does not use any member variables of the class.
// In the class body
int x = 0; // member variable
public static double average() {
x = x + 1; // illegal
}
The less something can do, the easier to understand what it does do.
Static methods like the area, average are usually utility functions. You don't need any object to use an utility function. For example consider Math.pow you don't need to instantiate any object to use the power function, just use Math.pow(10.0, 2.0) to get (10.0)^2
In short :
Static method means class method, that is no instance of that object is needed to invoke.
whereas your average method is an instance method, you need an object to invoke that method.

Using XML-derived Variables in the Main Method

so I am making a game where the player's skill damage is determined by their Skill Level and their weapon Mastery. The two values are stored in an XML document, and I am using DOM to retrieve the values, and am trying to print their sum to the console.
public class Damage {
public String skillName = "Bash"; //name of the skill
Xml config = new Xml("C:/character.xml","config");//part of the XML retrieving
Xml version = config.child("Character");//another part of the XML retrieving
int mastery = version.integer("Mastery"); //mastery of the skill
int skillLevel = version.integer("skillName");//skill level
int skillDamage = mastery + skillLevel; //adding the two values together
public static void main(String[] args) {
System.out.println(skillDamage);
}
}
When I run this code, it tells me that I can't have non-static variables in the static Main method. However, when I place the static tag before the int on the variables, it results in 0.
My question is: How can I make the variables static but still produce the sum of the two XML values? Could I somehow collect the non-static data from the XML, make it static, and then use that?
Try
System.out.println(new Damage().skillDamage);
Because you need a instance for non-static class-variables
You need to create an instance of your Damage class first, if you want to use its non-static variables/members. Put your main method like this:
public static void main(String[] args) {
Damage dmg = new Damage();
System.out.println(dmg.skillDamage);
}
I don't think you want the variables to be static.
1) Make skillDamage a public int
2) Then, just create your object in your main method:
Damage d = new Damage();
System.out.println(d.skillDamage);
It would probably be best to encapsulate skillDamage in a method, something like
public int getSkillDamage(){...}
Imagine that you have class cow. You can create instances of that class, for example berta and milka . That would mean, that you have two cows and their behaviour is based on class cow.
If you define something static it means, it is static to its class, therefore you can not define specific actions for each cow.
You should have a new class, for example "GameEngine", you should have all what you need there and you should create it with something like : GameEngine ge = new GameEngine(); and then use methods like ge.readXML();

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

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.

Is static bad? How to remove static variables?

I have some code that I am working on. It's basically takes in user input and creates a directed graph. One person can travel one way, the other person the opposite. The output is the overlap of where they can visit.
I have most everything working the way that I want it to, but I am concerned with the use of static that I have. I don't seem to fully understand it and no matter where I look, I can't find out its exact use OR how to get rid of it.
Could someone please help me to understand what static is and why it would be helpful?
Also, would it be better to move most the code from MAIN to helper methods? If I do this I have to move all my variables from main to the top of the class and then they all have to be declared as static?!
The reason everything has to be static is because you aren't creating any objects. If you were to create an object by calling new in your main method, you could use non-static variables on that object. This isn't really a good place to give you a tutorial on why you might want to use object-oriented design; you can find one of those online to read (a commenter above gave a possible reference). But the reason everything has to be static is because it's all just running from the main method, which is always static in java. If you were to call new somewhere, you could use non-static variables.
Static makes a method or a variable accessible to all the instances of a class. It's like a constant, but for classes. To make it more easy to understand some code will do the work:
public class Example {
public static int numero;
}
public class Implementation {
public static void main (String args[]) {
Example ex1 = new Example();
Example ex2 = new Example();
Example.numero=10;
System.out.println("Value for instance 1 is: " + ex1.numero);
System.out.println("Value for instance 2 is: " + ex2.numero);
}
}
Running the follwing code will output:
Value for instance 1 is: 10
Value for instance 2 is: 10
Because you set the static variable numero (number in italian) to 10.
Got it?
It looks like a lot of your static methods (findNodeInList, etc) all take the ArrayList (which represents a map) as their first argument. So instead of having it static, you could have a class Map, which stores a list of nodes and has methods on them. Then the main method would read the input, but not have to manage any nodes directly. e.g:
class Map {
ArrayList<Node> nodes;
public void addNode(Node n) { nodes.add(n); }
public int findNodeInList(String s) { ... }
...
public static void main(String[] args) {
Map peggyMap = new Map();
Map samMap = new Map();
// Read the data
samMap.add(new Node(...));
}
}
This keeps all the stuff to do with nodes/maps well encapsulated and not mixed in with stuff to do with reading the data.
Static is useful if you going to be using the class/method throught out your program and you don't what to create a instance every time you need to use that method.
For ex
public class StaticExample {
public static void reusable() {
//code here
}
}
It means you can use it like this
StaticExample.reusable();
and you don't have to create an instance like this
StaticExample staticExample = new StaticExample();
staticExample.reuseable();
I hope this help you decide whether to use static or not.

Static methods and static fields in Java behave somewhat in a strange way

By convention, a static method specifically in Java can have access only to static fields or other static methods. The following simple code snippet however appears to violate the convention. Let's consider the following simple code snippet in Java.
class Super
{
protected static int x;
protected static int y;
public Super(int x, int y)
{
Super.x=x;
Super.y=y;
}
public static int sum()
{
return(x+y);
}
}
final class Sub extends Super
{
public static int temp=100;
public Sub(int x, int y)
{
super(x, y);
}
public void concreateMethod()
{
System.out.println("\nInstance variable x = "+x);
System.out.println("Instance variable y = "+y);
}
}
final public class Main
{
public static void main(String[] args)
{
Sub s=new Sub(10, 5);
System.out.println("\nAssociating with object x = "+s.x);
System.out.println("Associating with object y = "+s.y);
System.out.println("\nAssociating with class name x = "+Sub.x);
System.out.println("Associating with class name y = "+Sub.y);
System.out.println("\nSummation (Associating with object) = "+s.sum());
System.out.println("Summation (Associating with class name) = "+Sub.sum());
System.out.println("\nAssociating with class name temp = "+Sub.temp);
System.out.println("Associating with object temp = = "+s.temp);
System.out.println("\nConcreate method called.");
s.concreateMethod();
}
}
The above code produces the following output with the respective statements.
Associating with object x = 10
Associating with object y = 5
Associating with class name x = 10
Associating with class name y = 5
Summation (Associating with object) = 15
Summation (Associating with class name) = 15
Associating with class name temp = 100
Associating with object temp = = 100
Concreate method called.
Instance variable x = 10
Instance variable y = 5
The static fields s and x are being accessed through the following statements within the main() method using the object of the Sub class, though they are declared as static in the super class Super.
Sub s=new Sub(10, 5);
System.out.println("\nAssociating with object x = "+s.x);
System.out.println("Associating with object y = "+s.y);
The following statements of course, have no doubt.
System.out.println("\nAssociating with class name x = "+Sub.x);
System.out.println("Associating with class name y = "+Sub.y);
Since x and y are static, they can certainly be accessed in this way.
The same is the method call, observe the following statements.
Sub s=new Sub(10, 5);
System.out.println("\nSummation (Associating with object) = "+s.sum());
System.out.println("Summation (Associating with class name) = "+Sub.sum());
Both of the ways, the static method sum() is being accessed using the object of the class Super and also using the class name Sub.
Again the similar case with the static field temp declared within the Sub class
System.out.println("\nAssociating with class name temp = "+Sub.temp);
System.out.println("Associating with object temp = = "+s.temp);
The static field temp is being accessed in both the ways.
Why is this happening here?
Basically it's a flaw in the design of Java IMO which allows static members (methods and fields) to be referenced as if they were instance members. This can be very confusing in code like this:
Thread newThread = new Thread(runnable);
newThread.start();
newThread.sleep(1000);
That looks like it's sending the new thread to sleep, but it actually compiles down into code like this:
Thread newThread = new Thread(runnable);
newThread.start();
Thread.sleep(1000);
because sleep is a static method which only ever makes the current thread sleep.
Indeed, the variable isn't even checked for non-nullity (any more; it used to be, I believe):
Thread t = null;
t.sleep(1000);
Some IDEs can be configured to issue a warning or error for code like this - you shouldn't do it, as it hurts readability. (This is one of the flaws which was corrected by C#...)
There is no problem there. Static methods can only access static fields and call other static methods as you have stated. Nothing in your examples does otherwise.
Non-static methods can access both static and non-static methods and fields. Again, none of your examples violate that.
The Sub.temp and s.temp are equivalent and you can use both, it means the same. But 1st is better one because suggests it's a static field.
a static method specifically in Java can have access only to static fields or other static methods declared within the same class
Or its superclass.
I don't see any violation here, you can access static fields/methods via its concrete object or class name. both refer to the same thing.
Where do you see a non-static field or method being accessed by static code? Everything seems perfectly fine to me.
Perhaps what's confusing you is that static fields and methods can be accessed through instances as well as through the class name? It's certainly a big ugly and many consider it bad design, but that's all.

Categories