Constructor handling exception and using this keyword Java - java

I have two constructors for my class, one that takes File object and the other takes a String object, and I want to use the this keyword. The function with the implementation is the one with File as parameter, and the one with String will call this. Now I want to check for exception in the constructor that takes String but I get error, that this should be the first line. How can I check for errors then call this.
Here is my code:
public Test (String filename) {
if (filename == null)
throw new NullPointerException("The String you entered is null.");
if (filename.isEmpty())
throw new IllegalArgumentException("The String you entered is empty.");
this(new File(filename)); // error
}
public Test (File f) {
/* implementation here */
}
This is the exact error: Constructor call must be the first statement in a constructor

Unfortunately, this is impossible in Java thanks to their arbitrary restrictions. You have two main possibilities.
The more idiomatic Java technique is to wrap everything in a factory function so you can catch the exception. Factory functions are also useful because they let you create objects polymorphically, and help hide the details of what object is actually created.
public static Test create(String filename){
if (filename == null)
throw new NullPointerException("The String you entered is null.");
if (filename.isEmpty())
throw new IllegalArgumentException("The String you entered is empty.");
return new Test(filename);
}
private Test (String filename) {
this(new File(filename));
}
public Test (File f) {
/* implementation here */
}
The other option is to write the constructor in bytecode, where there are no such restrictions present. Unfortunately, bytecode is less readable and maintainable, so you'll probably want to minimize the amount of bytecode in a primarily Java app. You might also be able do this in a non Java language like AspectJ.
Edit: If you're not actually trying to catch the exceptions, then there's a third possibility. You can insert arbitrary code before the super constructor call by creating a separate function which performs the checks and then passing it as a dummy argument to the super constructor call. Since arguments are evaluated first, your code will run first, but this is a bit of a hack.
public Test (String filename) {
this(doChecks(filename), new File(filename));
}
private static Void doChecks(String filename){
if (filename == null)
throw new NullPointerException("The String you entered is null.");
if (filename.isEmpty())
throw new IllegalArgumentException("The String you entered is empty.");
return null;
}
public Test (Void dummy, File f) {
this(f);
}
public Test (File f) {
/* implementation here */
}

In case we use this or super in constructor, either this or super should be the first statement in the constructor. It is better, if you throw exception from a particular constructor.
public Test (String filename) {
this(new File(filename));
}
Let the second constructor handle any exception, caused by passing null.
public Test (File file) {
// exception handling code
// or new instance creation
}

No, you cannot check for errors before call this. It's forbidden by the specification. In fact, you didn't need it. Let new File(filename) to throw exceptions.
edit: I saw aizen92's comment: Actually that is what my constructor with the implementation has, it catches the exception may be thrown by file, so I just add the null exception and use this directly in my second constructor?
public Test (String filename) {
this((filename == null || filename.isEmpty()) ? null : new File(filename));
}

Related

Who throws AssertionError in JAVA? JVM or by API developer/Programmer?

I learning exception handling in JAVA, I found that exceptions/errors can also be classified on the basis of who throws or raises it.
Exceptions raised by JVM
Exceptions raised by API developer/programmer
My question is who is responsible for raising AssertionError?
The responsibility lies at the programmer regardless of whether they use, e.g.
throw new AssertionError("unreachable code");
or
assert condition;
Note that the assert statement is so called “syntactic sugar”.
When you write
class ClassWithAssert {
public ClassWithAssert() {
assert toString() != null;
}
}
It gets compiled to the equivalent of
class ClassWithAssert {
static final boolean $assertionsDisabled
= !ClassWithAssert.class.desiredAssertionStatus();
public ClassWithAssert() {
if(!$assertionsDisabled && toString() == null)
throw new AssertionError();
}
}
So the implicit throwing is not different to the explicit one, technically.

Where to check for values and throw an exception

Let's say I have a class like the following one:
public class Parameter {
private double[] parameterValues;
public Parameter(double[] parameterValues) throws BadElementInitializationException {
checkParameterValues(parameterValues);
this.parameterValues = parameterValues;
}
public double[] getParameterValues() {
return parameterValues;
}
public void setParameterValues(double[] parameterValues) throws BadElementInitializationException {
checkParameterValues(parameterValues);
this.parameterValues = parameterValues;
}
private void checkParameterValues(double[] parameterValues) throws BadElementInitializationException {
if(parameterValues == null)
throw new BadElementInitializationException("Parameter values cannot be null");
if(parameterValues.length == 0)
throw new BadElementInitializationException("Parameter values cannot be empty");
}
public int noOfValues(){
return parameterValues.length;
}
}
And the array is later used to perform some calculations.
My question is, where should I check that parameterValues is not null, nor empty? Should I do that in the Parameter class, like I did, or should I do that in the class which performs calculations?
Moreover, should I throw an exception here, or in the Calculation class? And what would be the reason to throw checked and what to throw unchecked exception? My goal is to make a stable application that won't crash easily.
You should do it in all places where getting an null or empty array is not valid. If you do it just in your Parameter class and rely on this having done the check in your Calculator class, then what if you start to use your Calculator class somewhere else? Who are you going to rely on to do the checks there? If you do it in the Calculator class and then refactor the Parameters class to use something else in the future, then your check will go away.
If its also invalid to have a null or empty array in your Calculator class then you need to check there as well.
Alternatively pass an object to both which cannot be empty and then you only need to make the null check.
Should I do that in the Parameter class, like I did, or should I do
that in the class which performs calculations?
In my opinion, better to check in Parameter class then any other classes. You could see how it do in google guava , for example, in most class they use:
public static boolean isPowerOfTwo(BigInteger x) {
checkNotNull(x);
return x.signum() > 0 && x.getLowestSetBit() == x.bitLength() - 1;
}
or
public static int log2(BigInteger x, RoundingMode mode) {
checkPositive("x", checkNotNull(x));
...
Moreover, should I throw an exception here, or in the Calculation
class?
If you check your parameters in Parameter class, better throw in Parameter class also. In addition to, you may use some standart function to check and throw exception, for example from google guava:
com.google.common.base.Preconditions.checkNotNull
com.google.common.base.Preconditions.checkArgument
com.google.common.math.MathPreconditions.checkPositive
And what would be the reason to throw checked and what to throw
unchecked exception?
A checked exception is good if you think that you must catch and working this exception later. In most case, for wrong parameters quite enough unchecked exception, like standart IllegalArgumentException in Java. Also, a checked exception need to say other programmers (who use this API) that this exception could be happened, and they need to working with it. Working with an unchecked exception is quite easy for programmer (and often reduce your source code), however a checked exception become your code is more reliable.
A more info about checked and uncheked exceptions, you could find in this post

Catching the NumberFormatException

Below is the class somebody else wrote.
The problem that I am facing is that when it get's into the parse method with null as the rawString, it is throwing NumberFormatException.
So what I was thinking to do is, I should catch that NumberFormatException and set the value itself as null. So the way I did is right?
public class ByteAttr {
#JExType(sequence = 1)
private Byte value;
public static ByteAttr parse(String rawString) {
ByteAttr attr = new ByteAttr();
try {
attr.setValue(Byte.valueOf(rawString));
} catch (NumberFormatException nfEx) {
attr.setValue(null);
}
return attr;
}
public Byte getValue() {
return this.value;
}
public void setValue(Byte value) {
this.value = value;
}
}
The correct approach depends on what you want to accomplish in the program.
If it makes sense for ByteAttr.getValue() to return null later in your program, then your approach could work.
However, you need to consider whether you should be throwing an exception if parse is called with an indecipherable argument (including null). An alternative is to catch the NumberFormatException and throw a different exception that has semantic meaning in your program.
public static ByteAttr parse(String rawString) throws BadAttributeException {
ByteAttr attr = new ByteAttr();
try {
attr.setValue(Byte.valueOf(rawString));
} catch (NumberFormatException nfEx) {
throw new BadAttributeException(nfEx); // wrap original exception
}
return attr;
}
Another technique is to pass a default value to parse for those cases when rawString is indecipherable:
public static ByteAttr parse(String rawString, Byte defaultValue) {
ByteAttr attr = new ByteAttr();
try {
attr.setValue(Byte.valueOf(rawString));
} catch (NumberFormatException nfEx) {
attr.setValue(default);
}
return attr;
}
You need to do four things:
Decide what an unparsable number string means in the context in which you will be using the method. Does it mean an internal problem in the program? A corrupt file? A user typo? Nothing wrong but that string needs to be handled differently?
Decide the best way to handle it, taking that into account. Almost always, if the error is triggered by external input you need to report it back. Substituting null may be a good way of handling it.
Document what you decide to do. If a method is going to return null with some specific meaning, that needs to be written down as comments, preferably Javadoc commments.
Implement your decision.
I get the impression, perhaps unfairly, that you have jumped straight to step 4, without thinking through the possible causes and proper reporting of the problem.
You can add an early exit with a condition like:
if (rawString != null) {
return attr; // or other value you prefer
}
You can also make sure the caller of the parse method test for null value and avoid calling parse when it is.
It depends on the tolerance to null values in your application. If you expect the users to not pass null string to the parse() method, then you should do a defensive null check and throw an exception.
if (null == rawString) {
throw new CustomException("rawString cannot be null");
}
The same would apply to the catch block for NumberFormatException, where instead of silently setting the value of Byte attribute to null, you should throw an exception with appropriate message.
But if null is perfectly acceptable, then you should perform a defensive null check and set the Byte attribute to null. The NumberFormatException should certainly be NOT suppressed, IMHO.

How would I go about throwing an "optional" exception?

I've got this method I'm working on (I think that's the name) and it essentially tries to match a part of a string and then return the proceeding part of the string - that part I've got, easy stuff. The method is of type String.
When my method fails to find the pattern in the string I want it to return an empty string. I also want to send something along with the empty string to go "hey, I didn't find your key" but I want this to be optional.
This is essentially what I want the method to do:
public static String getKey(String key) throws KeyNotFoundException {
if (key.equals("something")) {
return "great";
} else {
throw new KeyNotFoundException();
return "";
}
}
But the problem with this code is that the return ""; is obviously unreachable due to throw new KeyNotFoundException();.
If I was going to call this method I'd have to use the try {} catch(KeyNotFoundException knf) {} block. It's this block that I want to make optional however.
If I choose to be oblivious to the fact the key was not found (e.g. don't use try catch) then I just want to be given the empty string on return.
But I also want to be able to surround it with a try-catch block if I need to know whether the key was found for my operation to complete correctly.
I think I'm going about this the wrong way but I can't seem to figure out an alternative (new to Java), could anyone shred some light on this please?
The usual way to do this would be to write two methods, one which returns a default value, and one which throws an exception. You can have one of these call the other, to avoid duplication:
public static String getKey(String key) throws KeyNotFoundException {
String value = getOptionalKey(key);
if (value.equals("")) throw new KeyNotFoundException(key);
return value;
}
public static String getOptionalKey(String key) {
if (key.equals("something")) {
return "great";
} else {
return "";
}
}
The caller can then choose which one to call, based on their needs:
String value = getOptionalKey("uma"); // oblivious
try {
String value = getKey("uma"); // cognisant
}
catch (KeyNotFoundException e) {
// panic
}
You should either use return values or exceptions to denote an error condition, but not both.
Generally, if you anticipate that something can go wrong, use a return value, and if the error is exceptional, throw an exception (as the name suggests).
By definition, an exception disrupts the normal program flow. The exception "bubbles up" until someone catches it or the thread terminates.
You can't do exactly what you're trying, but you have a couple options. You could write a "safe" version of the method that returns a default value if the key isn't found, like you're trying to do, and have a separate method that will throw the exception if the key isn't found.
Another option, if you've defined KeyNotFoundException yourself, would be to derive from RuntimeException instead of simply Exception. Then, you could remove the throws declaration from your method signature and not publish the fact that the method could throw an exception.
You can't, however, throw an exception from the method AND return a value from the method.
Another way you could deal with optional return values is to use Java 8's Optional class, and let the caller decide what to do when the value is not present:
public static Optional<String> getOptionalKey(String key) {
if (key.equals("something")) {
return Optional.of("great");
} else {
return Optional.empty();
}
}
You could combine it with the multiple methods approach discussed in other answers:
public static String getKey(String key) throws KeyNotFoundException {
return getOptionalKey(key).orElseThrow(() -> new KeyNotFoundException(key));
}
What about if you create your own Exception (extend Exception) which will have a constructor that takes a String or whatever you want to send to it (like error code or statement)?
Then you can have a getter method within your Custom Exception that will be used to "get" whatever the error message was.
nope. a method can only end with returning a value/end or return; if it is void OR throw an exception.
From what I understand of what you want to achieve, you could use a void returning method and provide a reference of a special object in argument. you would then set a field of this object to the result you want to 'return' and throw the exception.
Something like
class final ResultHoder {
String result;
public void setResult(String result) {
this.result = result;
}
public String getResult() {
return this.result;
}
}
public static void getKey(String key, ResultHolder result) throws KeyNotFoundException {
if (key.equals("something")) {
result.setResult("great");
return;
} else {
result.setResult("");
throw new KeyNotFoundException();
}
}

Exception Handling in java error in the following code

import java.io.*;
public class Mainclassexec
{
public static void main(String[] args)
{
String input = null;
try
{
String capitalized = capitalize(input);
System.out.println(capitalized);
} catch (NullPointerException e)
{
System.out.println(e.toString());
}
}
public static String capitalize(String s) throws NullPointerException
{
System.out.println("Enter a string");
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
s=br.readLine(); //--->error here IOException must be caught
// or declared to be thrown
if (s == null)
{
throw new NullPointerException("You have passed a null argument");
}
Character firstChar = s.charAt(0);
String theRest = s.substring(1);
return firstChar.toString().toUpperCase() + theRest;
}
}
How should i clear this error? Also, please suggest me some links on learning exception handling. I am very confused with this topic.
Here you go,
public class Mainclassexec {
public static void main(String[] args) {
String input = null;
try {
String capitalized = capitalize(input);
System.out.println(capitalized);
} catch (IOException e) {
System.out.println(e.toString());
}
}
public static String capitalize(String s) throws IOException {
System.out.println("Enter a string");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
s = br.readLine();
Character firstChar = s.charAt(0);
String theRest = s.substring(1);
return firstChar.toString().toUpperCase() + theRest;
}
}
One advice, NullPointerException is a RuntimeException. You don't have to throw it explicitly. The best practice is to handle Nullpointers wherever possible instead of throwing it. It makes the code nasty and it has no added value during compile time.
You can refer this link for a detailed tutorial on Exception handling in Java.
Add "IOException" to the list of exceptions that the capitalize method throws
i.e.
public static String capitalize(String s) throws NullPointerException, IOException
...
This way it tells any piece of code calling the capiatlize method that it must be able to handle both types of exception.
EXception tutorials
http://www.javabeginner.com/learn-java/understanding-java-exceptions
http://onjava.com/pub/a/onjava/2003/11/19/exceptions.html
http://www.sap-img.com/java/java-exception-handling.htm
BufferedReader.readLine() is a method that throws IOException, meaning your program should handle that error itself. It is written that way so that you can do any measure that you need (e.g. to make it clear to the user that the string entered is null, which is the best practice on java and not try to catch the value using s==null).
Add IOException to the throws clause. You can also use just Exception. You can also use try-catch to handle the IOException differently - consume it (not recommended) or throw some other Exception.
The NullPointerException is non checked, so you don't need to add to the throws clause.
#Bragboy's answer is enough to fix the compilation error and get the program working. The problem that this fixes is that the BufferedReader.readLine() method can throw IOException, and that is a checked exception. Java insists that when a checked exception is thrown within a method (or some other method that the method calls), it must EITHER be caught in the method using a try / catch OR declared as thrown by the method. #Bragboy's answer does the latter in the capitalize, and then catches the IOException in the main method.
However, there are other important issue too.
Currently capitalize does not do what the method name and signature clearly implies. The signature implies that the method capitalizes its argument. In fact, it totally ignores its argument and reads (and capitalizes) a String from stand input instead.
A better design would be to read the input String into input in the main method, and pass it as the s argument. Then change capitalize to just capitalize the argument String.
Two other points of style:
The class name should be MainClassExec ... not Mainclassexec; refer to the Java Style Guide for an explanation of the Java naming conventions.
The way that your application is dealing with missing input is ugly. Assuming that you've fixed capitalize as I suggested, then the main method should test that the input variable is not null before calling capitalize.
Finally, in my opinion, there is rarely any point doing something like this:
if (x == null) {
throw new NullPointerException(...);
}
x.something();
Instead you should simply do this:
x.something();
This will automatically throw an NullPointerException if x is null. Besides, it is a bad idea to use the message of NullPointerException to contain a user error message. Most NPEs happen as a result of programming errors somewhere. If you start using NPEs to report errors resulting from (for example) bad input from the user, you'll end up with a mess.

Categories

Resources