How to use a user defined exceptions in java inside another method - java

I want to create a set method to insert maximum temperature for a specific place and I want that temperature to be of type Double,the method will check if the entered number is >= to 100 or <= to 100
if yes then it will be inserted in the maximum temperature field..
else I have to throw a user defined exception that will tell me that the number I entered is out of the supposed limits!
I wrote the Exception and the method this way:
public class OutOfSensibleLimits extends Exception
{
private Double max;
public OutOfSensibleLimits(Double max)
{
this.max = max;
}
public Double getMax()
{
return max;
}
public String toString()
{
return "The maximum Tempreture you entered: '" + maxTemp +
"' is out of sensible limits.";
}
}
public void setMaxTemp(Double max){
if ( max >= -100 || max <= 100)
{
maxTemp = max;
}
else throw new OutOfSensibleLimits();
}
and it gives me an error, what am I doing wrong?

Problems:
This is not how exceptions work -- you need to call the appropriate super constructor with the appropriate String if you want it to show a String, and
You're not calling your own exception's constructor properly. You've written it to accept a Double, and you're not passing in a Double (you're passing in nothing).
the toString method is unnecessary and confusing since it will never be called and the String will never be seen.
You state, "and it gives me an error,...", but don't show us any error message. I'm guessing that the compiler is complaining that you're not calling your class's constructor correctly, but please don't leave us guessing -- show the complete unabridged error message.
Your setMaxTemp uses the wrong boolean operator: if ( max >= -100 || max <= 100). This is always true. You want to use && instead.
Suggestions:
Yes, pass in a double the constructor
And then use that double to create an appropriate error/exception message that is passed into the super's constructor.
Get rid of your exception class's fields and toString() method.
Most important, I urge you to first read the Exception tutorial before trying anything else.
Also simplify as you're making things overly complex. Your Exception class could easily be nothing more than a constructor and that's it.
Make sure that the method that might throw the exception declares that it throws this exception.
For example:
public class TestSensibleLimits {
private Double maxTemp;
public void setMaxTemp(double max) throws OutOfSensibleLimits {
if (max >= -100 && max <= 100) { // use && not ||
maxTemp = max;
} else
throw new OutOfSensibleLimits(max);
}
public Double getMaxTemp() {
return maxTemp;
}
public static void main(String[] args) {
TestSensibleLimits test = new TestSensibleLimits();
try {
test.setMaxTemp(200);
} catch (OutOfSensibleLimits e) {
e.printStackTrace();
}
}
}
#SuppressWarnings("serial")
public class OutOfSensibleLimits extends Exception {
private static final String FORMAT = "The maximum Temperature you "
+ "entered: %.2f is out of sensible limits.";
public OutOfSensibleLimits(Double max) {
super(String.format(FORMAT, max));
}
}

Related

Object as parameter

Hi im a newbie in java programmer also a freshman in our university. I am currently practicing my java program and ran into a problem which is i dont know how to put up the code in which I have an object as parameter and wanting to have a value.
public int transferTo(Account another, int amount)
{
if (amount<=balance)
// I dont know how to use the object another to have the value of amount put into the object.
// another = amount; it causes a compiler error
}
hoping for the insightful responds <3
Your transferTo(Account another, int amount) method will do something like this.
public int transferTo(Account another, int amount) throws Exception{
if(another==null){
throw new NullPointerException("To Account Cannot be Null");
}
if(this.getBal()> amount){
this.setBal(this.getBal() - amount);
another.setBal(another.getBal() + amount);
}else{
throw new InsufficientFundsException("Insufficient funds! for " + this.id + ": " + this.name );
}
return this.getBal(); // return total balance of account;
}
You can create a class called InsufficientFundsException.class and declare is like this
class InsufficientFundsException extends Exception {
public InsufficientFundsException(String msg){
super(msg);
}
}
You use the parameter object just like you would a local object. You should check if the parameter is null before using it.
public int transferTo(Account another, int amount) {
if (another == null) {
return 0;
}
if (another.hasEnough(amount)) {
another.subtractFromBalance(amount);
}
....
}

Java method taking 0 arguments and returning a double using if else statements with strings

I am trying to write a method which does not take any arguments and then returns a double variable. It is a postcode identifier so when a cost code is entered certain post codes need to return a double.
In my example below i need post codes that start with either "GH6 TXX" or "NC4 LXX". (X stands for any random character or digit) to return 50.0.
If any other postcode is entered then return 100.0.
However i am not getting any results back and just finding errors. I'm sure i have gone massive wrong somewhere as im not great with If Else statements within methods. Any help or knowledge on this would be great!
public class multiPostcodeRange {
//Declaring Variables
String pcode;
public multiPostcodeRange()
{
pcode = "XXX XXX";
}
public void multiPostcodeRange()
{
if (pcode("GH6 TXX", "NC4 LXX")) {
return 100.0; }
else {
return 50.0;}
} }
public class MultiPostcodeRange {
private String pcode;
public MultiPostcodeRange() {
pcode = "XXX XXX";
}
public double multiPostcodeRange() {
if (pcode.equals("GH6 TXX") || pcode.equals("NC4 LXX")) {
return 100.0;
}
else {
return 50.0;
}
}
}
To return double from a function you need to define a return type for the function.
public double multiPostcodeRange
You created a class with his methods (which btw you shouldn't name as the class, but give them unique names).
Then you have to create a new instance object of that class and call the method on a main function.
For example, at the end of your code:
`public static void main(String args[]){
multiPostcodeRange Obj = new
multiPostcodeRange();
Obj.meth1();
Obj.meth2();}`
NB remember to give those methods unique names!
Also change 2nd method body and type as AndyMan's answer

Make the variable not overwrite to null and check if the codes are correct

I'm new to Java and I have created a class which is based on the question from this exercise.
I've tried my best to follow it and I think the reason why my variables are 0 or null is that I didn't write anything in the constructor. The question didn't say anything about what to write in the constructor.
I'm printing everything out because I want to see the result, but all I get from getCardNumber is null, getBalance is 0, coffee is 0. redeemFreeCoffee and isFreeCoffeeAvailable does work, simply because there are no variables that override them.
Here's the full question:
a. Each loyalty card stores the card number, current balance (the number of points) and the number of coffees on the card. Implement a
constructor with the card number (of type String) as its argument and
method getCardNumber() and getBalance().
b. Implement a method collectRewards(double amount, int coffees) that takes the amount spent (in pounds) and the number of coffees
bought and increases the balance (by one point for every pound spent)
as well as the number of coffees on the card.
c. Implement a method isFreeCoffeeAvailable() that checks whether a free coffee is available, that is, whether the number of coffees on
the card is greater than or equal to 9.
d. Implement a method redeemFreeCoffee() that first checks whether a free coffee is available. If this is the case then it reduces the
number of coffees by 9 and returns true, otherwise false.
I've tried changing the variables from private to public but I still get the same result.
I've even tried putting my main in a different class but the result is still the same.
public String cardNumber;
public int balance;
public int coffee;
public double amount;
public String getCardNumber () {
return cardNumber;
}
public int getBalance () {
return balance;
}
public double collectRewards(double amount, int coffees) {
if (amount > 0) {
coffee++;
balance++;
}
return amount;
}
public int isFreeCoffeeAvailable(){
if (coffee >= 9) {
return coffee;
}
return coffee;
}
public boolean redeemFreeCoffee() {
if (coffee > 9) {
coffee-=9;
return true;
}
else {
return false;
}
}
public LoyaltyCard (String cardNumber){
}
public static void main (String[] args) {
String cardNumber = "0987654321";
LoyaltyCard LoyaltyCardOne = new LoyaltyCard(cardNumber);
System.out.printf("%s%n%s%n%s%n%s%n%s",LoyaltyCardOne.getCardNumber(),LoyaltyCardOne.getBalance(),LoyaltyCardOne.collectRewards(6.0,5),LoyaltyCardOne.redeemFreeCoffee(),LoyaltyCardOne.isFreeCoffeeAvailable());
}
I'd like to see the result for getCardNumber(), getBalance() and the amount of coffee.
all I get from getCardNumber is null
You never initialized it
public LoyaltyCard (String cardNumber){
this.cardNumber = cardNumber;
}
because there are no variables that override them.
I think you might be confused about what "override" means, but that isn't the problem.
getBalance is 0, coffee is 0
You're calling those before you ever "collect rewards"
You will need to collect before printing the invidiual values, and read the logic again - increase by one point for every pound spent. So, focus on changing this block to fix that.
if (amount > 0) {
coffee++;
balance++;
}
Note that the instructions don't say the collectRewards returns anything. Also coffee should be increased by the input parameter, maybe than just 1.
Otherwise, you would need to call collectRewards at least 9 times before the redeem and isAvailable methods would work.
And once those are, you could do this, rather than rewrite coffee > 9
if (this.isFreeCoffeeAvailable()) {
} else {
}
Note: isFreeCoffeeAvailable should probably return coffee > 9; rather than return the amount
In Java all non-local variables are initialized to 0, or null. So far in the code you don't set variables to your desired values. You can either create a constructor which takes values, e,g:
LoyaltyCard(int balance, int coffee, double amount) {
this.balance = balance;
this.coffee = coffee;
// ... and other fields
or create setters for each field:
public setBalance(int balance) {
this.balance = balance;
}

"Exception in thread "main" java.lang.Error

I don't know why it says I have an error but this is the exact error message "Exception in thread "main" java.lang.Error: Unresolved compilation problem:
at org.com1027.cw1.rc00182.Salary.main(Salary.java:8)"
Here is the code:
package org.com1027.cw1.rc00182;
public class Salary {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
}
public double salary; //this is the field I have created within the Salary class with type double
public Salary() { //this is the default constructor
}
public double getsalary() { //Here is the getter for salary class with a return
return salary;
}
public double setsalary() { //Here is setter for the salary class with a return
return salary;
}
public int calculateTax()
{
int salary = 16475; //here I am stating the salary using an integer because it is number related
int taxSalary = 7035; //here I am declaring the result so I can use it later
int personalAllowance = 9440; //here I am declaring the personal allowance is equal to 9440
int taxThreshold = 32010; //this is the tax threshold value I have put in for later use when continuing the if statement
int lowerTax = 20; //this is the lower tax and because the value holds a decimal I have used a type double. this will come to use when continuing the if statement calculating the tax
int higherTax = 40; //this is the higher tax and again used a type double due to the use of a number holding a decimal
// above are the 6 variables I have created for the if statement below
if (salary > personalAllowance){ //here I am saying if the salary is more than 9440 (personal allowance) then..
taxSalary = salary-personalAllowance; //this is saying the salary (16475) minus personal allowance gives the result (7035) which is the taxable salary
taxSalary = 0;
}
if (taxSalary < taxThreshold) {
taxSalary = taxSalary * lowerTax;
}
else {
taxSalary = (taxSalary - taxThreshold) * higherTax + taxThreshold;
}
}
Also says I have an error on the brace right at the bottom saying I need to put another one in there but I cant find where it is missing from.
Is your setSalary() supposed not to do anything or is there additional code, which you forgot to include?
In general a setter should be as follows, though obviously you could make it return a value or a boolean:
public void setsalary(double salary) { // setSalary would have been more readable
this.salary = salary;
}
EDIT: As others pointed out, you are missing a class bracket. I have provided a possible location for it.
else {
taxSalary = (taxSalary - taxThreshold) * higherTax + taxThreshold;
}
return taxSalary; // <--- missing a return statement here
}
} // <--- Missing a class closing bracket here.
Your code contains bugs. You forced the compiler to compile it. However it cannot. So when you try to run it. It will stop and say that the compiled Java file is not valid. I'm not going to search for your errors in the code. Use an IDE like Eclipse, it will tell you where your errors are and what the problem is.

Java: index in array exists, ArrayIndexOutOfBoundsException: 0

Sorry if this is answered somewhere due to me missing something obvious, but I've been googling this for days now and it just doesn't seem to make any sense. I've got 3 years of experience in Javascript and am getting into Java now, so I'm not behind on the basic concepts of anything and such.
I'm using IntelliJ for this, but it fails to point out the problem. The communication (access rights and instantiations) between my classes is fine, the code syntax and variable types are as well, etc, so I really can't tell what it is.
I have a Data class, which just holds "read-only" data for the other classes to use.
public class Data {
// snip
public static int[][] specs = {
{6,1,6,40},
{5,2,5,30},
{5,3,4,40},
{4,4,3,60}
};
}
There's another class that has to read this data when it's initialized.
public class Soldier {
// snip
public int range;
public Soldier() {
int x = ...; // user input
range = Data.specs[x][1];
}
}
The specs array itself contains its data as defined (ie the array is not empty), x is valid as an index of the specs array (ie 0 <= x <= 3), its type is int and Test has read access to the specs array (all confirmed with debug output statements). And yet, when it tries to set the value of range (then and only then, at that exact point), I get the "Index out of bounds" error.
Can someone please tell me what's going wrong when trying to read the array? Or am I right in saying that this is really weird and I need to post the entire code?
Note: a small new test also shows that, if I change the code to first output a manually chosen value from the array and then set the value of range, the console prints the error statement (and exits the program) and follows it up by printing the manually picked value, but assigning the value and then asking to output range only throws the error... That makes absolutely no sense at all!
Edit: I've edited the code above. The class called Test is called Soldier in my code (I'm making a text-based game...). Below's the stack trace, if it's any good without the full code (which is way long). The basic structure of my program is this:
1) Boot contains the main method and instantiates a new Game
2) Game instantiates x Teams
3) each Team instantiates an Army
4) each Army instantiates x Soldiers
Each instance of the classes is set as an attribute of the instantiating class (public Army army; and an Army instantiation in the Team constructor, for example). It's essentially a cascade of constructors instantiating subsequent classes and assigning them as their attributes.
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at Army.<init>(Army.java:13)
at Team.<init>(Team.java:19)
at Game.<init>(Game.java:22)
at Boot.main(Boot.java:15)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)5
Edit edit: here's the semi-full code (I'm leaving out the stuff that has absolutely nothing to do with it, including the imports). It's in no particular order and the classes are in separate .java files within the IntelliJ project. The game continues up to the point where a new Soldier asks for its type to be designated (the function performing the user input is working fine and validating the input as proven by a technically identical other part of the game).
public class Boot {
public static void main(String[] args) {
Object[] games = new Object[] {};
if (Lib.userConfirmPrompt("Start the game?") == true) {
do {
games[games.length] = new Game();
}
while (Lib.userConfirmPrompt("Do you want to play again?") == true);
}
System.exit(0);
}
}
public class Game {
public Object[] teams = new Object[] {};
public Game() {
for (int i = 0;i < settings.xbots + 1;i++) {
teams[teams.length] = new Team(this);
}
}
}
public class Team {
public Game game;
public Army army;
public Team(Game p) {
game = p;
army = new Army(this);
}
}
public class Army {
public Team team;
public static Object[] soldiers = new Object[] {};
public Army(Team p) {
team = p;
for (int i = 0;i < team.game.settings.xsoldiers;i++) {
soldiers[soldiers.length] = new Soldier(this);
}
}
}
public class Soldier {
private Army army;
public int sight;
public int range;
public int distance;
public int damage;
public Soldier(Army p) {
army = p;
int type = Lib.userTxtIntOptionsPrompt(Data.isoldiertypes);
// HERE is where it crashes, type is assigned and valid but the array access fails
sight = Data.isoldierspecs[type][0];
range = Data.isoldierspecs[type][1];
distance = Data.isoldierspecs[type][2];
damage = Data.isoldierspecs[type][3];
}
}
public class Data {
public static List isoldiertypes = Arrays.asList("Scout","Private","Machinegunner","Grenadier");
public static int[][] isoldierspecs = {
{6,1,6,40},
{5,2,5,30},
{5,3,4,40},
{4,4,3,60}
};
}
public class Lib {
private static Scanner input = new Scanner(System.in);
// output
// default: 1 query string to print
public static void outBase(String query) {
System.out.print(query);
}
public static void outStd(String query) {
outBase(query + "\n");
}
// end of output
// input
// default: 1 query string to print,
// query and input are in-line (exception: userConfirmPrompt prints query block-wise and default instruction in-line before input),
// keeps user hostage until valid input is given (exception: userPrompt returns blindly)
public static String userPrompt(String query) {
outBase(query);
return input.nextLine();
}
public static String userTxtPrompt(String query) {
String menuinput = null;
do {
if (menuinput != null) {
userHostage();
}
menuinput = userPrompt(query);
} while (menuinput.length() == 0);
return menuinput;
}
public static int userIntPrompt(String query) {
String menuinput = null;
do {
if (menuinput != null) {
userHostage();
}
menuinput = userTxtPrompt(query);
} while(menuinput.matches("^-?\\d+$") == false);
return new Integer(menuinput);
}
// end of input
// options input
// default: takes a List of options as argument,
// prints an enumerated list of these options string-wise,
// prompts for a numeral selection of the desired option and returns the number if valid
public static int userTxtIntOptionsPrompt(List options) {
int choice = 0;
Boolean chosen = false;
do {
if (chosen == true) {
userHostage();
} else {
chosen = true;
}
chosen = true;
for (int i = 0;i < options.size() - 2;i++) {
outStd((i + 1) + ") " + options.get(i) + ",");
}
outStd((options.size() - 1) + ") " + options.get(options.size() - 2) + "\nand " + options.size() + ") " + options.get(options.size() - 1) + ".");
choice = userIntPrompt("Enter the number of the option you'd like to select: ") - 1;
} while(choice < 0 || choice >= options.size());
return choice;
}
// end of options input
// miscellaneous
public static void userHostage() {
outStd("Invalid operation. Please try again.");
}
}
The problem is in your Army class:
public static Object[] soldiers = new Object[] {};
You initialize an empty (length == 0) array named soldiers, but later you access:
soldiers[soldiers.length] = new Soldier(this);
This causes the failure.
By definition, soldiers.length is out of the bound of the array (since the bound is from 0 to soldiers.length-1)
To overcome it - make sure you allocate enough space in the array soldiers or use a dynamic array (ArrayList) instead. You can append elements to an ArrayList using ArrayList.add(), and you don't need to know the expected size before filling it up.
The x should be greater than -1 and less than 4.
The stacktrace does not mention the Solder class, its in the conctructor of the Army class.
Any how, only knowing that the index should be within a range is not enough. As a programmer its your duty to validate the index before trying to access an element at that index.
if(index > 0 && index < array.length) {
//then only acess the element at index
Problem is the array soldiers is of size 0.
This line int x = ...; // user input implies that you are taking input in some fashion from the user and accessing the array with it. Are you checking this value to see that is in range (i.e., between 0 and 3)? If not, this may be why your testing works.
Edit: something like this might solve it for you:
public class Army {
public Team team;
public Vector<Soldier> soldiers;
public Army(Team p) {
soldiers = new Vector<Soldier>()
team = p;
for (int i = 0;i < team.game.settings.xsoldiers;i++) {
soldiers.add(new Soldier(this));
}
}
}
Judging by your other code, this sort of pattern will be useful in your Game object as well.

Categories

Resources