Java: Inheritance, Exeptions and super keyword - java

I have a class X that saves ints in an array:
public class X{
public int[] a;
public boolean[] allocated;
//constructor
public X(int len){
this.a = new a[len];
this.a = new allocated[len];
}
public void save(int tosave) throws ArrayStoreException{
int pos = 0;
for(int i=0; i<allocated.length; i++){
if(allocated[i] == true){
pos++;
}
}
if(pos == allocated.length){
throw new ArrayStoreExeption("no free space left");
}
a[pos] = tosave;
allocated[pos] = true;
}
}
And the class Y with save2 that I still need to implement...
public class Y extends X{
public void save2(int tosave){
// to be implemented
}
}
For save2 I want it to do the same as save with the exception, that if there is no more free space left or the ArrayStoreException occurs then I want the array to be doubled the size and then the parameter inserted to the array.
So if I do:
try{
super.save(tosave); // If no exception is thrown, does it save 'tosave'?
}catch(ArrayStoreExeption e){
System.out.println("noe free sapce left");
}
My first question is: if the try block does not trigger an exeption, will the code after catch block execute?
I don't know where to put the piece of code savely which doubles the array size if there is no more space left or the exeption is thrown.
Can someone help?
EDIT:
Can I place the code, that double the array inside the catch block?

the code you have posted has a number of syntax errors. I suggest you get those fixed and repost if this answer doesn't satisfy you.
yes you can implement your code to expand the array inside the catch block of the subclass. It will need to call the superclass's save method
your subclass should probably override the save method rather than create a new save2 method
using a boolean array doesn't make a lot of sense. Given you are not leaving any gaps wouldn't it be easier just to keep a single index of the first unallocated spot?
wherever possible keep your member variables private or protected. In this case if the subclass is going to expand the array then it will likely need to be protected. Better would be to make it private and have a protected method in the superclass to expand it.
Arrays.copyOf will do the expansion for you
So putting all that together:
class Fixed {
private int size;
private int[] store;
private int index = 0;
public Fixed(int size) {
this.size = size;
store = new int[size];
}
public void save(int value) throws ArrayStoreException {
if (index == size)
throw new ArrayStoreException();
store[index++] = value;
}
protected void expand() {
size *= 2;
store = Arrays.copyOf(store, size);
}
}
class Expandable extends Fixed {
public void save(int value) {
try {
super.save(value);
} catch (ArrayStoreException x) {
expand();
save(value);
}
}
}
If you prefer to avoid the recursion then you could use:
public void save(int value) {
try {
super.save(value);
} catch (ArrayStoreException x) {
expand();
try {
super.save(value);
} catch (ArrayStoreException x) {
throw new IllegalStateException("Cannot save after expansion");
}
}
}

You can put the code in finally block.
Regardless there is an exception or not, finally block do execute. (Exception : if called System.exit(0); in the try block.)
Conceptually, let's begin with
Try Block - You put the code here where you think there may be an ArrayStoreException.
Catch Block - This Block runs only if there is any exception thrown from try block.
You put the code, how it should handle. As per requirement, you can throw a message to console telling about the details of error, as in your case ArrayStoreException message and can prompt the user that you are going to double the capacity of ArrayList and can hence write the code for increasing the size of ArrayList
Finally Block - This block runs regardless of any exception is thrown or not. You can write the code for increasing the size of ArrayList here also. But, it will run even if there is no ArrayStoreException and the ArrayList has the capacity.
Note : If there is an exception thrown by the code, and is not handled or declared, so the code will stop running and no further code will run. But, if there is a proper handling of errors, the rest of the code runs.
For your case, I will suggest definitely to leverage the use of try-catch-finally block and put the code for doubling the size in catch block.

Related

How do I fix Exception in thread "main" java.lang.IllegalStateException

I am having issues with my code regarding exception in thread main. This is the error that is popping up
Exception in thread "main" java.lang.IllegalStateException: Attempt to create a stack whose capacity exceeds allowed maximum of 10000
at ResizeableArrayStack.checkCapacity(ResizeableArrayStack.java:74)
at ResizeableArrayStack.ensureCapacity(ResizeableArrayStack.java:82)
at ResizeableArrayStack.push(ResizeableArrayStack.java:28)
at ResizeableArrayStack.evaluatePostfix(ResizeableArrayStack.java:98)
at ResizeableArrayStack.main(ResizeableArrayStack.java:157)
This is my code
import java.util.*;
public class ResizeableArrayStack<T> implements StackInterface<T>
{
private T[] stack;
private int topIndex;
private boolean integrityOK = false;
private static final int DEFAULT_CAPACITY = 50;
private static final int MAX_CAPACITY = 100000;
public ResizeableArrayStack()
{
this(DEFAULT_CAPACITY);
}
public ResizeableArrayStack(int initialCapacity)
{
integrityOK = false;
checkCapacity(initialCapacity);
// The cast is safe because the new array contains null entries
#SuppressWarnings("unchecked")
T[] tempStack = (T[])new Object[initialCapacity];
stack = tempStack;
topIndex = -1;
integrityOK = true;
}
public void push(T newEntry) {
checkIntegrity();
ensureCapacity();
stack[topIndex + 1] = newEntry;
topIndex++;
}
private void checkCapacity(int capacity) {
if (capacity > MAX_CAPACITY) {
throw new IllegalStateException("Attempt to create a stack whose capacity exceeds allowed
maximum of " + MAX_CAPACITY);
}
} // end checkCapacity
private void ensureCapacity() {
if (topIndex >= stack.length - 1) {
// If array is full, double its size
int newLength = 2 * stack.length;
checkCapacity(newLength);
stack = Arrays.copyOf(stack, newLength);
}
} //end ensureCapacity
public static void main(String[] args) {
String input = "ab*ca-/de*+";
ResizeableArrayStack<String> astack = new ResizeableArrayStack<>(input.length());
int evaluation = astack.evaluatePostfix(input);
System.out.println("Evaluating Postfix Expressions");
System.out.println("The evaluation of the postfix expression is " + evaluation);
}
}
I'm pretty sure the issue is with how the capacity values are set and compared but I can't figure out why I am getting this error. I think the issues are within the constructors that involve capacity and main method. Please ignore the evaluatePostfix method in the main as the errors all say they come from the constructors and main. I can put the evaluatePostfix up if you think the problem is within it. I also deleted the methods that weren't brought up in the problem.
The code you posted is not a MCVE. It doesn't compile because it is missing methods including checkIntegrity and evaluatePostfix. Even after I work around the missing methods, the code you posted does not cause IllegalStateException to be thrown. At a guess, after looking through the code that you did post, as well as the stack trace, the culprit appears to be method ensureCapacity which contains the following line:
int newLength = 2 * stack.length;
The value assigned to newLength may be greater than MAX_CAPACITY.
After you assign a value to newLength, you call method checkCapacity which explicitly throws a IllegalStateException.
private void checkCapacity(int capacity) {
if (capacity > MAX_CAPACITY) {
throw new IllegalStateException("Attempt to create a stack whose capacity exceeds allowed maximum of " + MAX_CAPACITY);
}
} // end checkCapacity
But as I wrote earlier, in the code that you posted capacity is never greater than MAX_CAPACITY and hence the code in your question never throws IllegalStateException.
I recommend that you run your code through a debugger. If you are using an IDE, then it should give you the option of running your code in "debug" mode. If you don't know how to use the debugger of the IDE then you should learn because knowing how to debug code is an essential skill for a programmer and a debugger helps a lot when it comes to debugging your code.

Final variable might already have been assigned [duplicate]

Because I believe it is a good programming practice, I make all my (local or instance) variables final if they are intended to be written only once.
However, I notice that when a variable assignment can throw an exception you cannot make said variable final:
final int x;
try {
x = Integer.parseInt("someinput");
}
catch(NumberFormatException e) {
x = 42; // Compiler error: The final local variable x may already have been assigned
}
Is there a way to do this without resorting to a temporary variable? (or is this not the right place for a final modifier?)
One way to do this is by introducing a (non-final) temporary variable, but you said you didn't want to do that.
Another way is to move both branches of the code into a function:
final int x = getValue();
private int getValue() {
try {
return Integer.parseInt("someinput");
}
catch(NumberFormatException e) {
return 42;
}
}
Whether or not this is practical depends on the exact use case.
All in all, as long as x is a an appropriately-scoped local variable, the most practical general approach might be to leave it non-final.
If, on the other hand, x is a member variable, my advice would be to use a non-final temporary during initialization:
public class C {
private final int x;
public C() {
int x_val;
try {
x_val = Integer.parseInt("someinput");
}
catch(NumberFormatException e) {
x_val = 42;
}
this.x = x_val;
}
}
No it is not the right place, imagine you got more then 1 Statement in your try and catch block, the first one says : x = 42. After some others Statements the try block fails, and it goes to the catch block, where your Saying x = 30. Now you defined x twice.

Print numbers sequentially using two threads

This an interview question and i don't think it has any relation with practical real life problems.
I have to print numbers 12345.... sequentially but the condition is i have to print it using two threads one responsible for printing odd numbers and one for even numbers.
till now i have come up with this solution.
package junk.concurrency;
public class PrintEvenOddTester {
public static void main(String... args) {
TaskEvenOdd t = new TaskEvenOdd(10);
Thread t1 = new Thread(t, "odd printer");
Thread t2 = new Thread(t, "even printer");
t1.start();
t2.start();
}
}
class TaskEvenOdd implements Runnable {
private int max;
private boolean isOdd = true;
private int number = 1;
TaskEvenOdd(int max) {
this.max = max;
}
synchronized void printEven(int number) { // sync on runnable itself
while (isOdd) { // if odd is to be printed, wait
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Even:" + this.number); // LINE-1
isOdd = true;
this.number++; // LINE-2
notifyAll();
}
synchronized void printOdd(int number) { // sync on runnable itself
while (!isOdd) { // if even is to be printed, wait
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Odd:" + this.number); // LINE-3
this.number++; // LINE-4
isOdd = false;
notifyAll();
}
#Override
public void run() {
while (number <= max) {
if (Thread.currentThread().getName().equals("even printer")) {
printEven(number);
} else {
printOdd(number);
}
}
}
}
1
while writing this code i observed one strange behaviour which i did not understand. If at LINE-1,2,3,4 in above code, i write number instead of this.number my number instance variable is not getting incremented and code just prints infinite number of 1s.
I assume both the printEven and printOdd method is called on runnable instance itself then why its value is not getting incremented. I tried making number volatile but still it resulted in same output.
2
Also i see numbers are getting printed till 11 not till 10. I understand why this is happening(as the last call to printOdd gets notified by last call of printEven(which is printing 10) thus prints 11 ), one way to avoid this is to check number every time before printing and see if it's under limit but i wanted to know what would be the best way to overcome this.
Thanks.
EDIT method parameter number is completely redundant and can be omitted. This if(this.max>=number) condition can be used before printing the number.
1
Your problem is that the parameter of your method is called number too. So it is shadowing the field of your class! So, when you omit, you inc the parameter; which simply doesn't have any real effect!
There are two solutions to this problem:
a) simply avoid doing it (so, by convention avoid using the same names as parameters and fields).
b) use tooling that spots such problems and tells you about. For example, findbugs has explicit rule to tell you about shadowing. And probably IDE's can be told to warn about this, too. See here.
2
Given the fact that this is just a "simple" assignment ... in my opinion a simple check for the "limit" of the overall class would be just fine.

How to determine the origin of a thrown exception without writing a try/catch for each statement?

I am wondering if this is possible to do without writing a try/catch block for every single call. I want to be able to tell which method threw the exception so I can handle them differently. Consider the following two (fairly identical) methods:
public void setBranchID(String ID) throws NumberFormatException{
if(ID.trim().length() != 0 && ID != null){
try{
branchID = Integer.parseInt(ID);
}catch(NumberFormatException ex){
OutputFunc.printError(ex); //Prints the stack trace to console
throw ex;
}
}
else{
branchID = null;
}
}
public void setCashOnHand(String cash) throws NumberFormatException{
if(cash.trim().length() != 0 && cash != null){
try{
cashOnHand = Double.parseDouble(cash);
}catch(NumberFormatException ex){
OutputFunc.printError(ex);
throw ex;
}
}
else{
cashOnHand = null;
}
}
What I want to do:
try{
setBranchID(String1);
setCashOnHand(String2);
//Other methods
}catch(NumberFormatException ex){
if(/*Exception came from setBranchID*/){
//Code
}
else if(/*Exception came from setCashOnHand*/){
//Code
}
}
You'll need to create a custom exception, which would have some sort of enumeration which would provide hints as to where the error took place:
public enum ErrorType {
BranchId,
CashOnHands
}
public class MyException extends Exception {
private ErrorType errorType;
public MyMyException(string message, ErrorType errorType) : super(message) {
this.errorType = errorType;
}
public ErrorType getErrorType() {
return this.errorType;
}
}
Then you create an exception like so: throw new MyException(..., ErrorType.Branch) and then, in your handling statement:
...
catch(MyException e) {
switch(e.getErrorType) {
case ErrorType.BranchId:...
}
}
you do not necessarily need to create a new exception (even though its probably nicer) but you can just change the message returns from the exception :
public void setBranchID(String ID) throws NumberFormatException{
if(ID.trim().length() != 0 && ID != null){
try{
branchID = Integer.parseInt(ID);
}catch(NumberFormatException ex){
OutputFunc.printError(ex); //Prints the stack trace to console
throw new NumberFormatException("setBranchID error : " + ex );
}
}
else{
branchID = null;
}
}
Then you can get the exception message if it starts with the setBranchId:
try{
t.setBranchID("xxx");
t.setCashOnHand("xxx");
//Other methods
} catch (NumberFormatException ex){
if (ex.getMessage().startsWith("setBranchID")) {
System.out.println("error from setBranchID method");
}
.....
}
You can also try something like this---
try {
setBranchID(String1);
setCashOnHand(String2);
} catch (Exception e) {
StackTraceElement se[] = e.getStackTrace();
String s = se[0].toString();
int startIndex = s.indexOf(".");
int endIndex = s.indexOf("(");
String newstr = s.substring(startIndex + 1, endIndex);
}
newstr will have the name of the function that throws the exception. You can compare it and do your desired processing.
I tried it and its working fine.
I hope it would help you.
You can avoid to write a try - catch block for every single method simply obtaining the method name directly from the stack trace like this:
public class TestClass {
public void testMethod1(){
int x = 1/0;
}
public void testMethod2(){
int x = 1/0;
}
public static void main(String[] args) {
TestClass c = new TestClass();
try {
c.testMethod2();
} catch (Exception e){
System.out.println(e.getStackTrace()[0].getMethodName());
}
}
}
The main method above prints testMethod2
The answer to your question is quite simple, don’t re-throw and exception. But maybe you want to do this, so then probably your custom exception is the easiest way because you can enforce that it has the information about the original method. But can I just make some remarks, don’t read if not interested but please consider.
This code you have written looks very similar to the code I wrote when I first started doing GUI programming, I thought using this functionality from checked exceptions is a good idea for validating user input but it’s not. I even stuck checked exceptions in the data objects themselves, for instance in the setters of an employee class.
Eventually what you’ll find that methods, which have nothing to do with exceptions generated by methods nested deep in your control structure are having to handle exceptions or throw an exception which has nothing to do with them, soon every method in your code will be doing this, for many different exceptions.
What is the answer then? You’ll find that preventing exceptions will be your best attack. Use components which enforce the correct data, such as formatted text fields. Then in your code you can know with certainty that methods are not going to have exceptions. If you have complex validation going on, then just think about how you can design your code, look at some GUI patterns such as the MVC pattern (there are at least 2 versions of this pattern by the way). Then there are alternatives, I found returning an enumeration value then using a switch statement for each case can be a nice solution too. Or another idea is that each error message you can merely append to a string and then output as well, anything but throwing exceptions, and if you are going to throw an exception, don’t throw a checked one unless someone is going to die if you don’t.
I think it’s a fine art to know when it is a good idea to throw an exception, but shouldn’t be your first choice.

Final variable assignment with try/catch

Because I believe it is a good programming practice, I make all my (local or instance) variables final if they are intended to be written only once.
However, I notice that when a variable assignment can throw an exception you cannot make said variable final:
final int x;
try {
x = Integer.parseInt("someinput");
}
catch(NumberFormatException e) {
x = 42; // Compiler error: The final local variable x may already have been assigned
}
Is there a way to do this without resorting to a temporary variable? (or is this not the right place for a final modifier?)
One way to do this is by introducing a (non-final) temporary variable, but you said you didn't want to do that.
Another way is to move both branches of the code into a function:
final int x = getValue();
private int getValue() {
try {
return Integer.parseInt("someinput");
}
catch(NumberFormatException e) {
return 42;
}
}
Whether or not this is practical depends on the exact use case.
All in all, as long as x is a an appropriately-scoped local variable, the most practical general approach might be to leave it non-final.
If, on the other hand, x is a member variable, my advice would be to use a non-final temporary during initialization:
public class C {
private final int x;
public C() {
int x_val;
try {
x_val = Integer.parseInt("someinput");
}
catch(NumberFormatException e) {
x_val = 42;
}
this.x = x_val;
}
}
No it is not the right place, imagine you got more then 1 Statement in your try and catch block, the first one says : x = 42. After some others Statements the try block fails, and it goes to the catch block, where your Saying x = 30. Now you defined x twice.

Categories