I'm new to Java and we have to make this little project. So i have 3+ classes.
MY code is in pastebin
http://pastebin.com/GEq9DLiP
etc. etc.
Problem is, that in 3rd class it sais
"kangelane cannot be resolved"
but kangelane is already "defined" in Main.java and they are in same package.
Oh and Eclipse also wants to add "open bracet" after
int sook = 4; or
int dam;
and also "clode bracket" to the end
even though all open brackets are closed and vice versa
I have Getters and Setters in "Voitleja.java", so that works.
It also worked, when i only had 2 classes not 3 (Voitlus was in Main)
The problem is that main is a static class, if you want to use a variable in both main and in an oter class, you have to defined it as a static variable, for your example you should do :
public class Main {
static Voitleja kangelane;
public static void main(String[] args) {
String nimi = JOptionPane.showInputDialog("Sisestage võitleja nimi");
kangelane = new Voitleja(nimi, 55, 12);
}
}
Then in your other class (assuming the import are correct)
public class Voitlus{
Random generator = new Random();
int dam;
int sook = 4;
while (true) {
Main.kangelane.setElud(kangelane.getElud() + 7);
}
}
public static void main(String[] args) {
String nimi = JOptionPane.showInputDialog("Sisestage võitleja nimi");
Voitleja kangelane = new Voitleja(nimi, 55, 12);
}
(later)
while (true) {
kangelane.setElud(kangelane.getElud() + 7);
}
The variables are in a different scope. You have to declare kangelane right after your public class declaration so both methods can "see" it.
Related
I need help I cannot figure out how to fix the scope of my variables. I want this to be an example for my notes but have been on it for almost 2 hours.
public class methodPractice{
String streetName;
int streetNum;
public static void streetName()
{
String streetName = "Pope Ave.";
}
public static void streetNum()
{
int streetNum = 11825;
}
public static void main(String[] args)
{
streetName();
streetNum();
System.out.println("This is your home adress: " + streetNum +
streetName);
}
}
Thank you for your help.
You are shadowing the fields. Use this to make sure you get the fields, or a compile error.
public static void streetName()
{
this.streetName = "Pope Ave.";
}
public static void streetNum()
{
this.streetNum = 11825;
}
Here is your main method, with line numbers added:
1. public static void main(String[] args) {
2. streetName();
3. streetNum();
4. System.out.println("This is your home adress: " + streetNum + streetName);
5. }
A few points...
When line 2 runs, "streetName()" calls the static method below. The static keyword says you are free to call the method by itself – that is, you don't need an object; you don't need to call new methodPractice() first.
public static void streetName() {
String streetName = "Pope Ave.";
}
When line 3 runs, it's the same thing: "streetNum()" calls a different static method – again, totally fine to call this by itself.
public static void streetNum() {
int streetNum = 11825;
}
Line 4 is different, there are a few things going on. Your expectation is that "streetNum" finds the int that you declared on the class, but it doesn't work. Why? Because you defined that member with "int streetNum" – without "static". So what? Without being declared static, it means "streetNum" belongs to an object instance. What does that look like? Here's an example showing object creation, followed by setting the object member "streetNum" to 1.
methodPractice object = new methodPractice();
object.streetNum = 1;
You could work around this by declaring both of the non-static members to be static (static String streetName, and static int streetNum). Or you could leave them as is, and interact with them through an object instance (after doing new ..).
Several Java textbooks state that member inner classes cannot have static members except for static final fields. However, I have been able to create such classes that compile and run successfully. For example:
class Swimmer{
class SwimmerAssistant{
static int count = 0;
SwimmerAssistant(){
count++;
}
public static void assist(){
System.out.println("I am helping the Swimmer");
}
}
public static void main(String[] args) {
SwimmerAssistant.assist(); // prints "I am helping the Swimmer"
System.out.println(SwimmerAssistant.count); // prints 0
Swimmer swimmer1 = new Swimmer();
Swimmer.SwimmerAssistant swimmerAssistant = swimmer1.new SwimmerAssistant();
Swimmer swimmer2 = new Swimmer();
Swimmer.SwimmerAssistant swimmerAssistant2 = swimmer2.new SwimmerAssistant();
System.out.println(SwimmerAssistant.count); // prints 2
}}
How is this possible?
Many thanks.
I am currently trying to write a little game in java lwjgl/OpenGL.
When running the code i get the value NULL when reading from some ConcurrentHashMap.
I've written a simple program to reproduce the same issue and sure enough, i could.
Let me show the code to you:
The Program consists of three classes.
The Main class:
package main;
public class Main {
private MapContainer con = new MapContainer();
public static void main(String[] args) {
new Main();
}
public Main() {
ValueContainer vc = new ValueContainer(1, 2, 3);
this.con.set(vc, "Just a String");
System.out.println(this.con.get(vc));
}
}
Then there's the MapContainer class.
It's basically a class that contains a ConcurrentHashMap and two methods to access it:
package main;
import java.util.concurrent.ConcurrentHashMap;
public class MapContainer {
private ConcurrentHashMap<ValueContainer, String> map = new ConcurrentHashMap<>();
public void set(ValueContainer key, String value) {
this.map.put(key, value);
}
public String get(ValueContainer key) {
return this.map.get(key);
}
}
At last, there's the ValueContainer.
This class just contains the three Integers x, y and z, and a Constructer to set these values.
package main;
public class ValueContainer {
public ValueContainer(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
public int x, y, z;
}
So when i run the main class, i create a new ValueContainer with the values 1, 2, 3 and put it into the map Container, along with the String "Just a String".
Then i read the String with that exact Value container and print it out.
Sure enough the program works and i get "Just a String" printed in the Console.
So now there's my game:
In my game i have to access a similar ConcurrentHashMap, but i cant use the same ValueContainer to access the String, but i have to create a new one with new ValueContainer(1, 2, 3);
So obviously the ConcurrentHashMap can't give "Just a String" back, because it's not the same ValueContainer, so it gives NULL.
Here's the code of the Main class with this little modification:
package main;
public class Main {
private MapContainer con = new MapContainer();
public static void main(String[] args) {
new Main();
}
public Main() {
this.con.set(new ValueContainer(1, 2, 3), "Just a String");
System.out.println(this.con.get(new ValueContainer(1, 2, 3)));
}
}
Now my question:
Is there any way for me to use the version in the second main class, but without the issue, so that i
get printed out "Just a String" in Console?
Thank you.
Yes, quite simple.
You have to override the two methods Object.hashCode() and Object.equals() in your class ValueContainer.
Please take a look add the API-documentation of the two methods.
API
Maybe you use a IDE like Ecplise oder IntelliJ which will help you with the details.
I'm kind of mediocre at Java at the moment, and new to JUnit, but I can't find the answer to this question elsewhere.
I want to use a constant variable defined within the class I am testing, within the Junit test case itself, but since it's a static final, it's not available.
The class I'm testing is as follows:
public class MyClass {
private static final int HSIZE = 7;
private static final int NUM_LOCS = 3;
.
.
.
void generateRandomLocations() {
Random rand = new Random();
String[] hPos = new String[NUM_LOCS];
for (int i=0; i<NUM_LOCS; i++) {
hPos[i] = Integer.toString(rand.nextInt(HSIZE));
}
setLocations(hPos);
}
}
Simple enough, and it seems to work OK, but I'd like to add a test case in JUnit - something like the following:
#Test
void testGenerateRandomLocations() {
MyClass mc = new MyClass();
mc.generateRandomLocations();
String[] check = mc.getLocations();
assertEquals(sadc.NUM_LOCS, check.length);
}
(The getter is defined, I just haven't included it here for brevity)
However (of course) sadc.NUM_LOCS is not available because it's only visible in MyClass.
How can I access this from a JUnit (5) test case?
I've used #VisibleForTesting annotation which annotates why normally private variables and methods are protected instead. They're not fully visible, but can be accessed for testing purposes. I've used this with what were private static final variables.
The example I've seen/worked with used a file called VisibleForTesting.java that contained:
package your.pkg.here;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.SOURCE;
/**
* Indicates that the class, method or field has greater
* visibility than otherwise needed to enhance testability.
*/
#Retention(SOURCE)
public #interface VisibleForTesting {
}
Then within the class you want to test you set the method or variable to protected, and use the #VisibleForTesting annotation:
public class MyClass {
private static final int HSIZE = 7;
#VisibleForTesting
protected static final int NUM_LOCS = 3;
void generateRandomLocations() {
Random rand = new Random();
String[] hPos = new String[NUM_LOCS];
for (int i=0; i<NUM_LOCS; i++) {
hPos[i] = Integer.toString(rand.nextInt(HSIZE));
}
setLocations(hPos);
}
}
This allows the tests to see it, but the variable is not available to the public, and there is an explanation for why it's not private. #VisibleForTesting can also be found in Google's Guava library, so you could include that instead of adding VisibleForTesting.java, but I haven't used that.
Have you try using Powermockito. Whitebox has getInternalState.
see if it helps
https://github.com/powermock/powermock/wiki/Bypass-Encapsulation
Simple answer
Make variable NUM_LOCS public. However, this is a poor design.
Better answer
Instead of static variable, pass NUM_LOCS through constructor:
public class MyClass {
private final int numLocs;
public MyClass(int numLocs) {
this.numLocs = numLocs;
}
//default ctor with default numLocs value
public MyClass() {
this.numLocs = 3;
}
//methods
}
Now, your test looks like this:
#Test
void testGenerateRandomLocations() {
int expectedNumLocs = 7;
MyClass mc = new MyClass(7);
mc.generateRandomLocations();
String[] check = mc.getLocations();
assertEquals(expectedNumLocs, check.length);
}
and you can make a test to check default value is 3, too:
#Test
void testGenerateRandomLocations() {
int expectedNumLocs = 3;
MyClass mc = new MyClass(); //no args
mc.generateRandomLocations();
String[] check = mc.getLocations();
assertEquals(expectedNumLocs, check.length);
}
When I run this code i get 2 numbers (which is good) but the numbers generated are the same (which is bad) and I dont want the numbers to be the same. I've done this as an experiment for a rpg I was going to make so I thought it would be beter if each weapon had a different class.
The main class:
package battlesimMK2;
public class Main {
public static void main(String Arg[]) {
String WeponEquiped = "BasicAxe";
System.out.print(BasicAxe.Str);
System.out.print(BasicAxe.Str);
}
}
The basic axe class:
package battlesimMK2;
import java.util.Random;
public class BasicAxe {
static Random rnd = new Random();
static int Str = rnd.nextInt(4)+5;
}
This line:
static int Str = rnd.nextInt(4)+5;
declares a static variable and initializes it once. If you want the code to run each to you access Str, you should make it a method:
public static int getStrength() {
return rnd.nextInt(4)+5;
}
Then call it with this code in Main.main:
System.out.print(BasicAxe.getStrength());
System.out.print(BasicAxe.getStrength());
An alternative which would probably be more object-oriented would be to make the strength an instance field, so that each axe created had a possibly-different (but persistent) strength:
public class BasicAxe {
private static final Random rnd = new Random();
private final int strength;
public BasicAxe() {
strength = rnd.nextInt(4)+5;
}
public int getStrength() {
return strength;
}
}
Then in Main.main:
BasicAxe axe1 = new BasicAxe();
BasicAxe axe2 = new BasicAxe();
System.out.println(axe1.getStrength());
System.out.println(axe2.getStrength());
System.out.println(axe1.getStrength());
Here, the first and third lines of output will be the same - but the second will (probably) be different.
You're generating a single random number and printing it twice. Try something like this instead:
package battlesimMK2;
public class Main {
public static void main(String Arg[]) {
String WeponEquiped = "BasicAxe";
System.out.print(BasicAxe.Str());
System.out.print(BasicAxe.Str());
}
}
package battlesimMK2;
import java.util.Random;
public class BasicAxe {
static Random rnd = new Random();
static int Str() { return rnd.nextInt(4)+5; }
}
This because this line
static int Str = rnd.nextInt(4)+5;
runs just one time in whole the lifecycle of your application. It's static value, you should use static method instead.
Because you define the Str variable as static, only a single copy of that variable is shared between all your BasicAxe classes.
The way to get a different answer each time you ask for the int value is, to use the example posted by the previous poster,
String WeponEquiped = "BasicAxe";
System.out.print(BasicAxe.getStrength());
System.out.print(BasicAxe.getStrength());
But, if you want to create an actual instance of the class BasicAxe, which keeps it's value so that each time you ask for the strength you get the same value, you'll need something different.