I'm trying to construct a PackingCase object with a certain set of values. While the program shows no errors during coding, when running, I get this error;
Exception in thread "main" java.lang.StackOverflowError
at assignment.pkg2.PackingCase.<init>(PackingCase.java:59)
at assignment.pkg2.PackingCase.<init>(PackingCase.java:60)
My code is as follows;
public class PackingCase {
// private fields go here
int serialNumber;
int timesUsed;
int timeCreated;
int timeStored;
String name;
String description;
void setCase(int s, int TU, int TC, int TS){
serialNumber = s;
timesUsed = TU;
timeCreated = TC;
timeStored = TS;
}
double volume(){
return serialNumber*timesUsed*timeCreated*timeStored;
}
public PackingCase(){
PackingCase PC1 = new PackingCase();
double vol;
PC1.setCase(1, 2, 3, 4);
vol = PC1.volume();
System.out.println(""+vol);
}
Line 59 is "public PackingCase(){" , and Line 60 is "PackingCase PC1 = new PackingCase();". I have no idea what's going on, considering that an example I found uses virtually the same code structure, and compiles with no errors whatever. Any help would be appreciated.
Each creation of a new object leads to the creation of another new object (and so on...) until the stack is overflowed.
Instead, it should be look like that:
public PackingCase(){
this.setCase(1, 2, 3, 4);
vol = this.volume();
System.out.println(""+vol);
}
You have a recursive call in the constructor. Leave the constructor empty (simply delete it) and run this code from main method:
public static void main(String[] a){
PackingCase pc1 = new PackingCase();
pc1.setCase(1, 2, 3, 4);
double vol = pc1.volume();
System.out.println(""+vol);
}
public PackingCase(){ PackingCase PC1 = new PackingCase(); ...}
Constructor recursively calls itself, causing stackoverflow.
You are calling new within the handler for new, creating an infinite loop (and since the stack is finite, it eventually runs out of space). But public PackingCase() { ... } is a constructor. That means it is only called when someone has already used new PackingCase(). The code within the constructor doesn't have to create the object (allocate space), just initialize it (set values for its fields).
Related
Just for reference, I've taken like one high school class on Java, so this question should be super easy to respond to. I'm just having trouble figuring out a way to call a class method, the constructor, as a new object without putting in new values for the parameters. The constructor looks like this:
public Skills(int courage, int intelligence, int stamina, int crafting,
int blacksmithery, int herbalism, int slingSkill,
int bowSkill, int swordSkill, int armor, int stealth, int
lifeForceSkill){
this.courage = courage;
this.intelligence = intelligence;
this.stamina = stamina;
this.crafting = crafting;
this.blacksmithery = blacksmithery;
this.herbalism = herbalism;
this.slingSkill = slingSkill;
this.bowSkill = bowSkill;
this.swordSkill = swordSkill;
this.armor = armor;
this.stealth = stealth;
this.lifeForceSkill = lifeForceSkill;
}
And when I establish it it my main method I do this:
Skills skills = new Skills(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
To set all the levels to 1 and then I have the object skills to work with later. (Am I getting the terms constructors and objects mixed up? If it's wrong just switch them all in your mind I think I'm being consistent with it at least).
The problem is I have a toString() method in the Skills class that I want to call in a separate method in the main class.
else if (optionChoice.equalsIgnoreCase("View Skills")){
Skills skills = new Skills();
System.out.println(skills.toString());
break;
}
Of course the object I create here throws an error because I cannot just write Skills(); without putting in all twelve values for the parameter. So how do I call the method from the Skills class when I can't create an object for it? It's imperative to functionality that the values do not change, and since they are variable and change with the program, I can't put any value in for them.
I know it's probably a super basic question but that's the level I'm at so any super basic answers would be helpful. Shouldn't take too much of your time. Thanks in advance!
Why not just make your skills object a static field instead of creating it within the main method?
public class WhateverYourClassIsCalled {
static Skills skills = new Skills(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
public static void main(String[] args) {
// ...
}
void yourOtherMethod() {
// ...
else if (optionChoice.equalsIgnoreCase("View Skills")) {
System.out.println(skills.toString());
break;
}
}
}
I have looked at several posts to reach an answer, but none came close enough.
I have a Q that might sound very empirical, and I am sure the answer is staring me in the face, but I am blinkered, I suppose! I have a class named DrugExcretion with a constructor that has a parameter that is a reference to an array (named drugExcretionCode).
I can't seem to work out the SYNTAX to instantiate (i.e. create an object) in my main class named DrugExcretionApp. Both classes are below:-
If anyone can direct me to a simple way to do this, it would be much appreciated. Thanks in advance.
public class DrugExcretion implements CautionInterface{
int[] drugExcretionCode;
private String[] drug;
public DrugExcretion(String[] drug){
this.drug = drug;
}
public String determineDanger(int[] drugExcretionCode){
String site1 = "kidney";
String site2 = "liver";
String site;
if (drugExcretionCode = 1){
return "reduce dosage in elderly";
}
else{
return "reduce dosage in children";
}
}
}
x ----------------- o ----------------- x ----------------- o
public class drugExcretionApp {
public static void main(String[] args) {
// TODO Auto-generated method stub
final String drug1 = "enalapril";
final String drug2 = "captopril";
final String drug3 = "metoprolol";
final String drug4 = "amlodipine";
final String drug5 = "candesartan";
String drug[] = {drug1, drug2, drug3, drug4, drug5};
DrugExcretion listOne = new DrugExcretion(drug);
DrugExcretion.determineDanger(new int[]{1, 1, 2, 2, 1});
}
}
I get an error "DrugExcretion cannot be resolved to a type" which initially made me think that the project setup was incorrect so the DrugExcretion class could not be seen by the app class - I rearranged the classes to keep them in the same package, but the error persists.
It appears to be a problem with access modifiers - have I made something static inadvertently???
BTW, the interface simply contains a signature of the only method in the first class.
You have to call determineDanger like this:
listOne.determineDanger(new int[]{1, 1, 2, 2, 1]);
DrugExcretion.xxx would be for a static method xxx of DrugExcretion.
But determineDanger is an instance method, so needs to be invoked on an instance of the class, in this case listOne.
Since you are instantiating the DrugExcretion class, you need to call
listOne.determineDanger(new int[] { 1, 1, 2, 2, 1 });
Also, please check your code in the DrugExcretion class. It should be equals operator and not assignment.
if (drugExcretionCode == 1){
I have information like this:
xxx 0 1 2 ...
Name Fred0 Fred1 Fred2
Stamina 2 6 7
Intel 5 4 1
Heart 4 8 2
Speed 5 3 6
So, I was informed previously that creating a 2D ArrayList to store something like this is "archaic" and was provided with a different way to set my code up. The reason I was using ArrayList<> is because I want to be able to generate new racers as needed, rather than designating an array to a size. If I could just use a simple array this would have been done a week ago. Now I've been screwing with it for a week and I still don't get how it works.
public class test {
public String name;
private int stamina;
private int heart;
private int intel;
private int speed;
public ArrayList<String> racers = new ArrayList<String>();
private void racerInfo(String name) {
this.name = name;
this.stamina = (int) Math.floor(Math.random()*10);
this.heart = (int) Math.floor(Math.random()*10);
this.intel = (int) Math.floor(Math.random()*10);
this.speed = (int) Math.floor(Math.random()*10);
}
public void generate() {
for ( int i=0; i<=10; i++) {
String name = "Fred" + i;
System.out.println(name);
racerInfo(name);
racers.add(name);
}
}
public int getStamina() {
return this.stamina;
}
public int getHeart() {
return this.heart;
}
public int getIntel() {
return this.intel;
}
public int getSpeed() {
return this.speed;
}
}
public class main {
public static test test = new test();
public static void main(String[] args) {
test.generate();
//Put stuff here to pull stamina of Fred2 for example.
}
}
Now, in the main class. How would I do something that should be relatively simple like pulling the Stamina value for Fred2.
I've been following the exact directions I've been given by others here to write most of this code. But at this time, I'm getting to the point of just re-writing it all so that each stat (name, stamina, intel, speed, etc.) is just logged as a separate ArrayList<>. But I can't figure out how to make a 2D ArrayList containing the original ArrayLists ie.
ArrayList<String> name = new ArrayList<String>();
ArrayList<Integer> stamina = new ArrayList<Integer>();
ArrayList<ArrayList<Object>> arrayOfArray = new ArrayList<ArrayList<Object>>();
Yes, I know the arrayOfArray is probably done wrong, but, again, I just get told it's Archaic and nobody'll tell me how I can do it right so I can just go. arrayOfArray.get(2,1) and pull information that I want/need.
Sorry for the information overload here. but I'm trying to just find the best possible solution for what I want to do. If you can tell me how to correctly pull off either way I will be eternally grateful you you and all of your descendants.
First of you should refactor your class test to class Racer, which is a meaningful name and follows the convention to start classnames with an uppercase letter. Furthermore you should add Stamina, Intel, Heart and Speed to the constructor:
public Racer(String name, int stamina, int intel, int heart, int speed) {
this.name = name;
this.stamina = stamina;
this.intel = intel;
this.heart = heart;
this.speed = speed;
}
Now you can create your racer as following:
Racer fred2 = new Racer("Fred2", 7, 1, 2, 6);
You can store your values in a HashMap. HashMap is a collection consisting of key-value pairs. For the key you can use a string (the name of the racer) and as value you take an instance of your class Racer:
HashMap<String, Racer>() racerMap = new HashMap<>();
racerMap.put("Fred2", fred2);
This you can do in a for-loop for all of your racers. Now you can get the racer objects from your HashMap by calling the getMethod and putting the name as parameter in it. This will return an object of class Racer and you can call the getter methods on this object:
racerMap.get("Fred2").getSpeed();
or
racerMap.get("Fred2").getIntel();
Edit: I just saw your generate method. This method should return the HashMap of racers. In your main method you create a new HashMap:
HashMap<String, Racer> racerMap = generate();
Now you can use the map as described above.
I am trying to use Mockito to mock a "Reader" type class. Think of a data stream reader, it has methods to read various data types and advance the internal pointer after each read.
public interface Reader {
int readInt();
short readShort();
}
The class being tested reads in various data structures from the data stream. For example,
public class Somethings {
public List<Something> somethings;
public Somethings(Reader reader) {
somethings = new List<Something>();
int count = reader.readInt();
for (int i=0; i<count; i++) {
somethings.add(readSomething(reader));
}
}
private Something readSomething(Reader reader) {
int a = reader.readInt();
short b = reader.readShort();
int c = reader.readInt();
return new Something(a, b, c);
}
}
And finally, I have my test:
public class SomethingsTest {
#Test
public void testSomethings() {
Reader reader = Mockito.mock(Reader.class);
readCount(reader, 2);
readSomething(reader, 1, 2, 3);
readSomething(reader, 4, 5, 6);
Somethings somethings = new Somethings(reader);
Assert.assertEqual(2, somethings.size());
Assert.assertEquals(new Something(1, 2, 3), somethings.somethings.get(0));
Assert.assertEquals(new Something(4, 5, 6), somethings.somethings.get(1));
}
private void readCount(Reader reader, int count) {
when(reader.readInt()).thenReturn(count);
}
private void readSomething(Reader reader, int a, short b, int c) {
when(reader.readInt()).thenReturn(a);
when(reader.readShort()).thenReturn(b);
when(reader.readInt()).thenReturn(c);
}
}
Unfortunately, this does not work. reader.readInt() always returns 6 for every invocation. And I understand why it returns 6. That is not my question.
There are two options I can think of to fix the tests, but I don't particularly like either one.
The first option would be something like:
public class SomethingsTest {
#Test
public void testSomethings() {
Reader reader = Mockito.mock(Reader.class);
when(reader.readInt())
.thenReturn(2)
.thenReturn(1)
.thenReturn(3)
.thenReturn(4)
.thenReturn(6);
when(reader.readShort())
.thenReturn(2)
.thenReturn(5);
Somethings somethings = new Somethings(reader);
Assert.assertEqual(2, somethings.size());
Assert.assertEquals(new Something(1, 2, 3), somethings.somethings.get(0));
Assert.assertEquals(new Something(4, 5, 6), somethings.somethings.get(1));
}
}
This should work, but it's very monolithic and messy. It's difficult to see which return is for which piece of which structure, because they're all intermixed, with no structure.
The second option I can think of is something like:
public class SomethingsTest {
#Test
public void testSomethings() {
Reader reader = Mockito.mock(Reader.class);
NewOngoingStubbing readIntStub = when(reader.readInt());
NewOngoingStubbing readShortStub = when(reader.readShort());
readCount(readIntStub, 2);
readSomething(readIntStub, readShortStub, 1, 2, 3);
readSomething(readIntStub, readShortStub, 4, 5, 6);
Somethings somethings = new Somethings(reader);
Assert.assertEqual(2, somethings.size());
Assert.assertEquals(new Something(1, 2, 3), somethings.somethings.get(0));
Assert.assertEquals(new Something(4, 5, 6), somethings.somethings.get(1));
}
private void readCount(NewOngoingStubbing readIntStub, int count) {
readIntStub.thenReturn(count);
}
private void readSomething(NewOngoingStubbing readIntStub,
NewOngoingStubbing readShortStub, int a, short b, int c) {
readIntStub.thenReturn(a);
readShortStub.thenReturn(b);
readIntStub.thenReturn(c);
}
}
This at least maintains the structure of the original, but having to pass a separate object for each method call you want to make on the stubbed object is... ugh.
What would be the cleanest way to perform this test? Is there some option I'm missing here? Some functionality that I can leverage? I just started using Mockito tonight.. so I could very well be missing something.
Mockito does ongoing stubbing natively. Your first example is fine, but this should also work:
when(reader.readInt()).thenReturn(2, 1, 3, 4, 6);
The documentation for it is here.
If you have something handling particularly complex interaction, it's OK to roll out your own stub class. You may find that initialising some fake with realistic data, then using that, provides a clearer example of how the classes collaborate than Mockito can. If that's the case, go with clarity over convention. Mockito is IMO the best mocking framework out there, but sometimes I still roll my own.
When the standard methods for Mockito don't provide a mechanism to simulate your behavior, you can resort to implementing your own Answer. This is more work but provides extra flexibility.
Depending on your precise requirements, you could for instance create an Answer that returns a new element from a list of numbers, regardless of the request type (int or short). The variable readList can be a member that you can access from all the functions you use to set up your results.
final List<Integer> readList = new ArrayList<>();
// ... Fill readList with answers
Answer answerFromList = new Answer() {
Object answer(InvocationOnMock invocation) {
// Remove and return first element
return readList.remove(0);
}
}
when(reader.readInt()).thenAnswer(answerFromList);
when(reader.readShort()).thenAnswer(answerFromList);
Note that this Answer is a lot like the provided ReturnElementsOf, so you could use that directly as well.
You may create a class to deal with it, e.g.
private static class ReaderStubber {
private final Reader reader = Mockito.mock(Reader.class);
private final NewOngoingStubbing readIntStub = when(reader.readInt());;
private final NewOngoingStubbing readShortStub = when(reader.readShort());;
public Reader getReader() {
return reader;
}
private void readCount(int count) {
readIntStub.thenReturn(count);
}
private void readSomething(int a, short b, int c) {
readIntStub.thenReturn(a);
readShortStub.thenReturn(b);
readIntStub.thenReturn(c);
}
}
But then the question is, do you really need to do this with Mockito? Not everything should be mocked. Maybe just implementing a stub Reader for the test with some List<Integer> inside is better.
(Edit)
Also, if this is possible, maybe you should redesign the Reader to make it immutable and return some NewOngoingReading. Frequently (but not always) things that are hard to test are better to redesign. Also, you will not need to deal with synchronization.
I am getting the following error:
Exception in thread "main" java.lang.NullPointerException
at BallContainerImage.update(BallContainerImage.java:101)
at BallContainer.addBall(BallContainer.java:93)
at Game.ejectBall(Game.java:92)
at LotteryTestB.main(LotteryTestB.java:19)
Line 19 contains:
dramaticGame1.ejectBall();
the Dramatic Game class contains the following:
public class DramaticMachine extends Machine
{
// Constructor is given the person's name.
public DramaticMachine(String name, int length)
{
super(name, length);
}
public Ball ejectBall()
{
if (getNoOfBalls() >= 0)
return null;
else
{
//Math.random() * getNoOfBalls yields a number
//which is >=0 and < number of balls.
int ejectedBallIndex = (int) (Math.random() * getNoOfBalls());
for (int selectedBallIndex = 0; selectedBallIndex < ejectedBallIndex; selectedBallIndex++)
{
Ball selectedBall = getBall(selectedBallIndex);
selectedBall.flash(4, 5);
}
Ball ejectedBall = getBall(ejectedBallIndex);
ejectedBall.flash(4, 5);
swapBalls(ejectedBallIndex, getNoOfBalls() -1);
removeBall();
return ejectedBall;
}//else
}//ejectBall
public String getType()
{
return "Dramatic Lottery Machine";
}//getType
}//dramaticMachine
How can i fix this?
This is the code for the DramaticGame class:
public class DramaticGame extends Game
{
// Constructor is given the person's name.
public DramaticGame(String machineName, int machineSize, String rackName, int
rackSize)
{
super(machineName,machineSize,rackName,rackSize);
}
public Machine makeMachine(String machineName, int machineSize)
{
return new DramaticMachine(machineName, machineSize);
}//makeMachine
}
This is the code for LotteryTestB:
public class LotteryTestB
{
public static void main (String args[])
{
SpeedController speedController
= new SpeedController(SpeedController.HALF_SPEED);
LotteryGUI gui = new LotteryGUI("TV Studio", speedController);
Worker worker = new TraineeWorker("Jim",0);
DramaticGame dramaticGame1 = new DramaticGame("Lott O'Luck Larry", 49,
"Slippery's Mile", 7);
gui.addGame(dramaticGame1);
worker.fillMachine(dramaticGame1);
for (int count = 1; count <=dramaticGame1.getRackSize(); count++)
{
dramaticGame1.ejectBall();
speedController.delay(40);
}//for
}//main
}//LotteryTestB
NullPointerException is one of the easier problems to chase down. It means that some reference wasn't initialized properly. It should be easy to figure out by stepping through your code with a debugger.
If you are incapable of using a debugger, the stack trace makes this easy for you. There are only four places to look, and it says exactly where they are.
at BallContainerImage.update(BallContainerImage.java:101)
at BallContainer.addBall(BallContainer.java:93)
at Game.ejectBall(Game.java:92)
at LotteryTestB.main(LotteryTestB.java:19)
It's not the bottom one. The reference to dramaticGame is the only one on that line, and you call new to initialize it. Go on to the next one. Add a log or print statement to prove where the null reference is, then go and initialize it properly.
I don't think your code is layered properly. You'll never get this working unless you can decompose the problem into smaller chunks, unit test them until they work, and then use that code to build up the complex solution.
Separate UI from the game itself. Get the game working, then worry about display issues.