I am very rusty in java and trying to relearn it again in a youtube tutorial, the code is as follows: This is Person.java
package com.gurmeet.javacourse.lesson2;
import com.gurmeet.javacourse.lesson3.Name;
public class Person {
private Name personName;
private static int personCounter;
public Person()
{
personCounter++;
/*
* empty on purpose - default constructor
*/
}
public Person(Name personName) {
this.personName = personName;
}
public String helloWorld() {
// TODO Auto-generated method stub
return "Hello World";
}
public String hello(String name) {
// TODO Auto-generated method stub
return "Hello " + name;
}
public static int numberOfPersons() {
// TODO Auto-generated method stub
return personCounter;
}
}
And this is PersonTest.java
package com.gurmeet.javacourse.lesson2;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class PersonTest {
#Test
public void shouldReturnHelloWorld() {
Person marcus = new Person();
assertEquals("Hello World", marcus.helloWorld());
}
#Test
public void shouldReturnHelloMarcus() {
Person person = new Person();
assertEquals("Hello Marcus", person.hello("Marcus"));
}
#Test
public void shouldReturnNumberOfPersons() {
Person person1 = new Person();
Person person2 = new Person();
Person person3 = new Person();
Person person4 = new Person();
assertEquals(4, Person.numberOfPersons() - 1);
}
}
these two above are in the same package but I created another package in the same project like below:
package com.gurmeet.javacourse.lesson3;
public class Name {
}
I am using JUnit to test my code, but in the for the last testing in my code I keep getting an error, you see the number of persons is supposed to be 4, but the result keeps showing 5. The youtube guy got the correct answer and I didnt even though I followed his coding correctly. What I came to understand in the tutorial is that the static is a global, at class level and since I have two classes created in the same package, the personCounter is not at 1 but 2 at default, therefore the it keeps showing 5 instead of 4. I solved it by subtracting 1 in the method but I dont think that is the correct way. Is my reasoning correct? or is there another explanation. And above all else, how do I solve this? Go easy on me if I made any mistake.
I guess the main problem is that when you run the first two tests, the static variable personCounter becomes 2 as you are creating two objects. Then when you run the third test, it starts from the 3 and goes upto 6.
I guess if you add another method to set the person counter to zero and call this method before creating the objects in the third test, you would get 4 as your output.
Add this in you class as a function
public static void setNumberOfPersons(int value) { personCounter = value; }
And then call Person.setNumberOfPersons(0); first in the third test
Edit:
Thanks to seelenvirtuose(see comment) for pointing out the random order part for tests. As said, I suppose the problem would go away by setting the value to 0 in the third test. This way the order would not matter.
Related
I'm currently learning Java from this tutorial, and while the nomenclature sometimes confuses me (heavily with this chapter, actually), I'm good enough at figuring out why the code works. Except in this case, it doesn't, and it's not my code not working, it's the tutorial's.
This is the snippet giving me problems:
public class Chapter6 {
public void bar2(Student s1, Student s2) {
Student joe = new Student("joe");
Student jack = new Student("jack");
bar2(joe, jack);
}
}
Eclipse complains that for line 3, Student cannot be resolved to a type (twice). I can fix this by creating a class called Student, but then it still complains for lines 4 and 5 that the constructor Student(string) is undefined. As my final attempt at solving it, I put this code in the Student class file (and changed the class in the first line from Chapter6 to Student), but that didn't solve anything.
I'm happy for any help, and happier still if you could ELI5, because as I said, the nomenclature of functions really confuses me.
First you need to create a class Student, the errors that you are getting are because when the program compiles, tries to find the Student class. And it's not imported.
public class Student {
private String name;
// This is the constructor, it will get called when you do: new Student("joe")
public Student(String name) {
this.name = name;
}
}
Then in the class chapter6.
public class Chapter6 {
public static void main(String [] args) {
Student joe = new Student("joe");
Student jack = new Student("jack");
bar2(joe, jack);
}
public void bar2(Student s1, Student s2) {
// Do stuff here
}
}
Be aware that if you leave the method call bar2 in the method bar2 how it is now, you will get an error StackOverFlow, because the method is calling itself indefinitely
You need to create a class Student with a constructor with a String parameter.
Then, don't forget to import it in the Chapter6 class
#Ezequiel Falcon answer is right.
You need to create a Student Class first then import Student class in Chapter6. Also, you need to modify your bar2 method in Chapter6 Class.
public class Student {
private String name;
public Student (String name) {
this.name = name;
}
}
This question already has answers here:
What does the 'static' keyword do in a class?
(22 answers)
Closed 3 years ago.
I'm currently learning polymorphism in Java, and part of the assignment was to create a program that will print out various subclasses using inheritance and polymorphism. I have tried looking for solutions but I couldn't seem to find anyone else experiencing this issue.
Below is a piece of code that is supposed to print Alex and Alexa respectively. However, the output is, instead, Alexa Alexa.
I have tried debugging by stepping through using Eclipse, but I can't pinpoint what is the mistake. I am truly stumped at this point, I've been trying this question for the past week but to no avail. Please forgive me if this is a simple question but I can't figure out what went wrong. I would truly appreciate any assistance!
import java.util.ArrayList;
public class Human {
protected static String name;
public Human(String name) {
System.out.println("In human constructor");
this.name = name;
}
void greetings() {}
static void print(Human human) {
System.out.println(name);
}
public static void main(String[] args) {
ArrayList<Human> human = new ArrayList<Human>();
human.add(new Man("Alex"));
human.add(new Woman("Alexa"));
for (int i = 0; i < human.size(); i++) {
print(human.get(i));
}
}
}
class Man extends Human {
public Man(String name) {
super(name);
// TODO Auto-generated constructor stub
}
}
class Woman extends Human {
public Woman(String name) {
super(name);
// TODO Auto-generated constructor stub
}
}
There are a couple things wrong here:
name should not be static. You want an instance of name for each instance (object) created.
You are printing the wrong name. You want to print the name of the instance passed into print(). So you would want something like this (you would create a getter method for name):
static void print(Human human) {
System.out.println(human.getName());
}
every Human has his own name, no matter if Man or Woman.
so remove the static keyword from
protected static String name;
This is because you've defined name as a static field. so in every object it will have the same value. just remove the static from name.
protected String name;
when a variable, method, ... is defined static, you can have access to it without creating objects. meanwhile it will have the same value in each object. so if you are modifying a static variable, it will keep the last modification.
take a look at this link for more information.
Do some research on the static context. Here is part of your problem:
protected static String name;
Making name static means that it belongs to the Human class. That means every object of class Human will have the same name.
If you want Human objects to have different names, remove that static modifier.
Next, Human should probably be a POJO, instead of your main class. Something like this:
public class Test {
public static void main(String[] args) {
Human human = new Human("Steve");
System.out.println(human.getName());
}
}
class Human {
private String name;
Human(String s) {
this.name = s;
}
public String getName() {
return this.name;
}
}
edit: I apologize if the post has been considered too confusing, i'll edit it and leave only the parts regarding my problem...
I have written a class named "ArithmeticNode" which implements an interface containing the following methods:
public void turnOn() {
arithmeticServer.start();
}
public void turnOff(){
arithmeticServer.stop();
}
and contains also a private method:
private void negotiatePort(NodeManifest nodeManifest, ThriftServer arithmeticServer) {
while(true) {
int proposedPort = arithmeticServer.start();
int returnedPort = managementClient.registerNode(nodeManifest, proposedPort);
if(proposedPOrt != returnedPort) {
arithnemticServer.stop();
}
else
break;
}
}
What I'm trying to do is to write a test in which I create a number of these arithmetic nodes and make them register to a management node that I've already written and use as server. Then there will be a second part of my project where I'll make those nodes interact, but that's not part of the actual problem.
I have already written a working junit test:
#Test
public void testArithmeticServer() throws Exception {
List<NodeManifest> nodeManifests = new ArrayList<>();
nodeManifests.add(new NodeManifest("localhost", Arrays.asList(new String[]{"addition"})));
nodeManifests.add(new NodeManifest("localhost", Arrays.asList(new String[]{"subtraction","multiplication"})));
nodeManifests.add(new NodeManifest("localhost", Arrays.asList(new String[]{"addition","multiplication","division"})));
nodeManifests.add(new NodeManifest("localhost", Arrays.asList(new String[]{"addition","division"})));
List<ThriftServer> arithmeticServers = new ArrayList<>();
for (NodeManifest nodeManifest : nodeManifests) {
ThriftServer arithmeticServer = new ThriftServer(ArithmeticServiceHandler.class);
arithmeticServers.add(arithmeticServer);
negotiatePort(nodeManifest,arithmeticServer);
}
private void negotiatePort() {
while(true) {
int proposedPort = arithmeticServer.start();
int returnedPort = managementClient.registerNode(nodeManifest, proposedPort);
if(proposedPOrt != returnedPort) {
arithnemticServer.stop();
}
else
break;
}
}
I need to write a test where i don't have to put the negotiatePort method directly inside the test code, but I call for each node the private negotiatePort method I have inside my arithmeticNode class; I'm not sure if it's possible to do that and how. I hope I've been less confusing than the previous version of the post :-)
You can make the negotiatePort method package local. Then you would be able to call it within your test (which should reside in the same package). And nobody outside the package would be able to use it
For my programming class in first year engineering I have to make a D-game in Java, with only very little knowledge of Java.
In one class I am generating a random integer via
public int rbug = (int)(Math.random() * 18);
every so many ticks. I have to use this integer in another class (in the requirements for an if-loop), and apparently it needs to be static. But when I change the variable to public int static, the value doesn't change any more.
Is there an easy way to solve this problem?
Edit: part of code added:
public int rbug = (int)(Math.random() * 18);
which is used in
public void render(Graphics g){
g.drawImage(bugs.get(rbug), (int)x, (int)y, null);
And in another class:
if(Physics.Collision(this, game.eb, i, BadBug.rbug)){
}
As error for BadBug.rbug I get the message
Cannot make a static reference to a non-static field
Using static to make things easier to access is not a very good ideal for design. You would want to make variables have a "getter" to access them from another class' instance, and possibly even a "setter". An example of this:
public class Test {
String sample = 1337;
public Test(int value) {
this.sample = value;
}
public Test(){}
public int getSample() {
return this.sample;
}
public void setSample(int setter) {
this.sample = setter;
}
}
An example of how these are used:
Test example = new Test();
System.out.println(example.getSample()); // Prints: 1337
example = new Test(-1);
System.out.println(example.getSample()); // Prints: -1
example.setSample(12345);
System.out.println(example.getSample()); // Prints: 12345
Now you might be thinking "How do I get a string from the class that made the instance variable within the class?". That's simple as well, when you construct a class, you can pass a value of the class instance itself to the constructor of the class:
public class Project {
private TestTwo example;
public void onEnable() {
this.example = new TestTwo(this);
this.example.printFromProject();
}
public int getSample() {
return 1337;
}
}
public class TestTwo {
private final Project project;
public TestTwo(Project project) {
this.project = project;
}
public void printFromProject() {
System.out.println(this.project.getSample());
}
}
This allows you to keep single instances of classes by passing around your main class instance.
To answer the question about the "static accessor", that can also be done like this:
public class Test {
public static int someGlobal = /* default value */;
}
Which allows setting and getting values through Test.someGlobal. Note however that I would still say that this is a horrible practice.
Do you want to get a new number every time that you want BadBug.rbug? Then convert it from a variable to a method.
I am testing Java app with JUnit. The following is the source code of a specific method:
public class Surgery {
Vector<Patient> patients;
String name;
public Surgery(String name) {
patients = new Vector<Patient>();
this.name = name;
}
public Patient findPatient(String name) {
Iterator<Patient> patientIt = patients.iterator();
while(patientIt.hasNext()) {
Patient next = patientIt.next();
if (next.getName().equals(name))
return next;
}
return null;
}
This is JUnit test method:
public class SurgeryTest {
private Vector<Patient> vector;
Surgery surgery_N =new Surgery("Teddy");
ByteArrayOutputStream ans = new ByteArrayOutputStream();
final String separator = System.getProperty("line.separator");
#Test
public void testFindPatient() {
surgery_N.findPatient("Teddy");
}
}
I need to test each statement in the source code method. I stuck, don't know what else to do. Any solution?
Your Surgery class contains no way to add patients to it from the code sample you have given us, so your unit test should be finding nothing.
To test each statement in the source code method you should create multiple tests that cover each one of the possible paths in your code. That means, in your tests you will want to test for the scenario where you return a patient name if it exists, and one for where the patient doesn't exist (returning null).
Here's some example methods for you to work from:
public void testFindPatientWherePatientExists() {
Patient thePatient = surgery.findPatient("Teddy");
assertEquals("Teddy", thePatient.getName());
}
public void testFindPatientWherePatientDoesntExist() {
assertNull(surgery.findPatient("I dont exist"));
}
What is the expected result when you call findPatient(...)? You can compare the expected result with the actual result using assertEqual(...)
public class SurgeryTest {
Surgery surgery;
#Before
public void setUp() {
surgery = new Surgery("Teddy");
}
#Test
public void testFindPatient() {
Patient p = ...; // expected result
assertEquals(p, surgery.findPatient("Teddy"));
}
}
The method with #Before annotation will be called before each method with #Test annotation. Therefore, the new surgery object is tested every time.
First, note that the name you pass to the Surgery constructor does NOT get placed into the patients Vector. It is a field of Surgery. Suggest you rename the arg to "surgeryName" and then you'll need a new method, addPatient(String patientName);, and call addPatient("Teddy").
That said, in general, you should test for both the name present and name absent case. e.g.
(exact name of the assert methods might vary)
assertNotNull(surgery.findPatient("Teddy"));
assertNull(surgery.findPatient("A Name I did not add"));
(first line would be more precise if it were assertEquals() like wannik suggested.