Using XML-derived Variables in the Main Method - java

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();

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

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.

creating arrays on-demand in java

I consider myself an intermediate Java programmer having been at it for a year and a half and having some experience in other languages. However I have run into an issue that I feel I need an experts help on.
As I understand it arrays when created by java exist somewhat outside of where they were created i.e. if you create an array called s in one class and another called s in a second class then try to use both those classes as part of a program you will run into problems with them overwriting each other.
However this brings me to an interesting dilemma. What if one wanted to create a unique array on-demand for an infinite number of sets of user input. i.e. is it possible to have the user enter a string value for use as the array name or have a generic value that then gets a number or letter appended to it. This is more a theoretical issue (there being other ways to accomplish the same thing) but any insight would be greatly appreciated.
i.e. is it possible to have the user enter a string value for use as
the array name or have a generic value that then gets a number or
letter appended to it.
The user should not need to care about your array names. The name of an array should neither be visible to the user, nor should it affect your application in any way.
If you want to allow the user to create collections of elements that he can store under a FriendlyName you could use a (Hash)map for that:
Map<String, Integer[]> userDefinedArrays = new HashMap<>();
userDefinedArrays.put("NameTheUserSelectsForThisArray", new Integer[]{1,2,3});
The "Key" of this map will be the FriendlyName provided by the user - he still does not know, that the actual map is called userDefinedArrays - or even someMapThatHoldsSomeThingsTheUserWantToUse.
The name of a actual variable needs to be set during designtime and is fixed (at least in java)
if you create an array called s in one class and another called s in a second class then try to use both those classes as part of a program you will run into problems with them overwriting each other.
No! Each Variable declared exists inside it's own scope! You can change the value of an array inside it's scope, and also reuse the same name inside different scopes - it doesn't matter. If you try to redeclare a variable already existing withing the current scope your compiler will warn you! - you simple can not do that.
Example:
class MyApplication{
public static void Main(String[] args){
Integer[] arr1;
Integer[] arr1; //Compiler error!
}
}
but:
class MyApplication{
public static void Main(String[] args){
Integer[] arr1;
Integer[] arr2;
}
}
or
class MyApplication{
public static void Main(String[] args){
foo();
bar();
}
public static void foo(){
Integer[] arr1;
}
public static void bar(){
Integer[] arr1;
}
}
is fine. arr1 just exists within the scope of either foo() or bar().
As I understand it arrays when created by java exist somewhat outside of where they were created i.e. if you create an array called s in one class and another called s in a second class then try to use both those classes as part of a program you will run into problems with them overwriting each other.
I think maybe you are misunderstanding. This will not happen unless you do it intentionally like yshavit points out in your comments. A member of a class named S in the class Cat, will not point to a member named S in the Dog class. You would have to go out of your way to do this.
In short, this will not happen by accident most of the time if you are instantiating your classes without passing references between them when you do.
What if one wanted to create a unique array on-demand for an infinite number of sets of user input.
You may want to use an ArrayList
ArrayList<String[]> myList = new ArrayList<String[]>();
Or a hashmap
Map<Integer,String[]> myMap = new HashMap<Integer,String[]>();
Which one you use depends on what you are using it for. If you need faster access to arbitrary elements use a map. If you plan to access them iteratively, an ArrayList will work fine.
is it possible to have the user enter a string value for use as the array name or have a generic value that then gets a number or letter appended to it. This is more a theoretical issue (there being other ways to accomplish the same thing) but any insight would be greatly appreciated.
In this case you want to use the hashmap solution, You can choose the key type of a map in java quite easily.
You will want to read this
http://docs.oracle.com/javase/6/docs/api/java/util/Map.html
or this, to get started.
http://docs.oracle.com/javase/6/docs/api/java/util/ArrayList.html
Two different class you're talking about is ClassOne & ClassTwo in my example. As you told, there is some kind of conflict while keeping the field name same. I've used arr for both classes. The reason to make MyArray super class is just code reuse. Why I used abstract MyArray class & why I used public static field isn't our matter of discussion. In TestApp, I've used arr of both classes ClassOne & ClassTwo without any problem.is it possible to have the user enter a string value for use as the array nameIMHO it may be possible using Reflection API or Dynamically Typed Language can do it. I'm not much sure about that.
class ClassOne extends MyArray {
public static int[] arr = new int[5];
}
class ClassTwo extends MyArray {
public static int[] arr = new int[5];
}
abstract class MyArray {
public static void setValue(int arr[], int index, int value) {
arr[index] = value;
}
public static void printArray(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
}
public class TestApp {
public static void main(String[] args) {
ClassOne.setValue(ClassOne.arr, 1, 30);
ClassTwo.setValue(ClassTwo.arr, 1, 50);
ClassOne.printArray(ClassOne.arr);
ClassOne.printArray(ClassTwo.arr);
ClassTwo.printArray(ClassOne.arr);
ClassTwo.printArray(ClassTwo.arr);
}
}

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.

Calling a method from outside a class in Java

This seems to be a common question on here but for all the ones I read, they seem to deal with different things.
I'm writing a program with a main class that manages an array of objects of a different class, and I'm having difficulty calling a print() method from this second class, from within the main class.
The Main class attempts to call print(), which is in the Unit class. The Unit class looks something like this:
public class Unit{
static int numOfUnits = 0;
public Unit[] units = new Unit[8];
private int unitID;
//constructors are here
public void print(){
for (int i = 0; i < units.length; i++)
System.out.print(units[i].unitID);
}
public void add(Unit unit){
mobs[numbofUnits] = unit;
numOfUnits++;
}
}
So what I'd like to happen is, through the Main class, I add new Unit objects to the units array. When I'm done adding them (using the call unitToAdd.add(unitToAdd) in the Main class) I would like to call Unit's print() method from within Main.
What I don't know is, whether or not, and where, to use the static modifier, how to refer to the variables in the print() method itself (that is, do I use this.unitID, units[i].unitID, etc) and so on.
What is confusing me is simply the nature of the print() method. I have setters and getters that work just fine since I completely understand that calling specificUnit.setID() is changing a specific variable for that specific object, but I don't know how to get methods like print() to work.
Thanks!
Simple answer - you need a Unit instance to invoke print(). I strongly recommend that you go back to the basics - Learning the Java Language.
You should probably avoid implementing a list of Units in Unit. You can avoid static state altogether by creating a UnitList class to store your list of units, maybe in an ArrayList, and then creating a UnitList instance that is local to your main method.
public static void main(String[] argv) {
UnitList myUnitList = new UnitList();
myUnitList.add(new Unit(...));
myUnitList.print();
}
That separates out the concern of tracking a set of units from the units themselves and avoids global mutable state which is hard to debug and unit test.
To answer your question though, below is the minimal set of changes with some explanation as to why they should be static or not.
public class Unit{
// static here since every unit does not need to have a number of units.
static int numOfUnits = 0;
// static here since every unit does not need to contain other units.
static Unit[] units = new Unit[8];
// no static here since every unit does need its own ID.
private int unitID;
//constructors are here
// static here since every unit does not need to know how
// to print a particular 8 units.
public static void print(){
for (int i = 0; i < numOfUnits; i++)
System.out.print(units[i].unitID);
}
// static here since every unit does not need to know how
// to add to a global list.
public static void add(Unit unit){
mobs[numbofUnits] = unit;
numOfUnits++;
}
}

Categories