2

I have a class for an object, and if a user attempts to supply a negative number to it's constructor I want to output a warning telling them that they have provided an invalid number in the form of

System.out.println("ERROR ON LINE " + Thread.currentThread().getStackTrace()[2].getLineNumber() + ": You have provided an invalid number.\nSetting to default.");

EDIT: I set the values to a default values in the system, I don't want the program to terminate.

What I really want to know is how I do automagically find the [2].

Cole Busby
  • 398
  • 6
  • 17
  • Why do you want to tell an end user a source line number? – bmargulies Sep 23 '13 at 00:34
  • @bmargulies It's also debugging. I generally use Line Numbers as Error Numbers. This is practice stuff for me so I keep track of the Problems personally. – Cole Busby Sep 23 '13 at 00:36
  • For debugging, use (e.g.) log4j and let it log the line numbers for you. – bmargulies Sep 23 '13 at 00:36
  • @ColeBusby If you're writing in Java, don't use "error numbers". Java uses exceptions, and you both gain nothing and lose lots by trying to invent your own error-handling ideas that run contrary to the entire language and JVM design. – chrylis -cautiouslyoptimistic- Sep 23 '13 at 00:40
  • @chrylis I use PHP at work so this is how I've come to error handle in logging. Thanks for the heads up. – Cole Busby Sep 23 '13 at 00:41

3 Answers3

4

In this case, instead of printing an error message, you should throw an exception. This has the bonus of including the line number in a report. You would use this line of code:

throw new IllegalArgumentException("You must provide a positive number");

If this happens, you will get an error report like this:

Exception in thread main: java.lang.IllegalArgumentException: You must provide a positive number
    at YourClass(YourFile.java:lineNumber)

If this is not a GUI application the program will also terminate. GUI applications and other types of apps will shrug this off with an error report and continue.

For more about exceptions, see the Java Tutorial on Exceptions.

tbodt
  • 16,609
  • 6
  • 58
  • 83
  • 1
    The program will only terminate if the exception isn't handled. It's quite common for GUIs and server frameworks to safely wall off a constructor exception and continue on. – chrylis -cautiouslyoptimistic- Sep 23 '13 at 00:39
  • I know, I know. I'll put that in. – tbodt Sep 23 '13 at 00:39
  • Can you throw the exception and grab the line number? – Cole Busby Sep 23 '13 at 00:43
  • 1
    @ColeBusby The exception stack trace contains all of the line numbers for the calls that got you to the point of the error. If for some reason you really need to get them programmatically (using a logging framework is usually a much easier choice, and since this is a core language feature, support is pervasive), you can use [`StackTraceElement#getLineNumber()`](http://docs.oracle.com/javase/7/docs/api/java/lang/StackTraceElement.html#getLineNumber()). – chrylis -cautiouslyoptimistic- Sep 23 '13 at 00:45
  • @chrylis Look at the edit in the question. I am using getLineNumber, If I try catch this argument can I use e.getLineNumber? – Cole Busby Sep 23 '13 at 00:51
  • @ColeBusby [Let's talk about what you're wanting to do in chat.](http://chat.stackoverflow.com/rooms/37843/handling-invalid-constructor-arguments) – chrylis -cautiouslyoptimistic- Sep 23 '13 at 00:54
3

Don't use a print statement for this; this is exactly the time to throw an IllegalArgumentException. Exception handling is semantically much clearer, if you have an invalid number passed to the constructor you don't want the construction to succeed anyhow, and if you go around manually writing messages to System.out, they'll get missed when running a graphical or server-based application. An exception will both have the line number where the error occurred and help the programmer figure out how the invalid number ended up passed to the constructor in the first place.

You can say something like this:

if(number < 0)
    throw new IllegalArgumentException("number must not be negative");

Even better, if you're writing an application that can use Bean Validation, you can write your constraint into your code in such a way that it's obvious to users and can be checked at compile-time:

public MyClass(@Min(0) int number) {
    // constructor
}
chrylis -cautiouslyoptimistic-
  • 75,269
  • 21
  • 115
  • 152
3

Are you familiar with java exceptions? You can throw exceptions eg in the constructor.

if(number<0){
   throw new IllegalArgumentException("Argument "+number+" is illegal. must be positive");
}

This will force the user to provide a legal argument making sure your program doesn't break or hang in a bad state. The exception will also provide a neat stacktrace that shows at exactly what line the error of providing a bad argument was made.

arynaq
  • 6,710
  • 9
  • 44
  • 74