10

Is there any way to get the line number of the caller of a method in Java? I don't want to have to throw an exception. Do I have to work with stack traces? Is there any way to do this in a cheap way?

EDIT: To clarify, I don't want the line number of the caller's class. I want the exact line where the method was called.

nulldev
  • 555
  • 6
  • 16

2 Answers2

22

The answer that Aasmund provided works, but you're better using

Thread.getStackTrace() than Exception.getStackTrace(), because you're not actually interested in the exception.

In practical terms, it won't make much difference, but your code will reflect your intention more clearly.

int callersLineNumber = Thread.currentThread().getStackTrace()[1].getLineNumber();
Nathan Brown
  • 1,193
  • 1
  • 11
  • 19
Tim
  • 6,406
  • 22
  • 34
  • Another practical reason your answer is better is that it avoids creation of a new Exception object. – Nathan Brown Aug 10 '16 at 10:56
  • 8
    Note that this will show the line number of the current method. If you want the line number where the method was called, you need to use `getStackTrace()[2]`. – Nathan Brown Aug 10 '16 at 11:05
  • @NathanBrown - actually, no it doesn't. Take a look at the implementation of `Thread.getStackTrace()`. – Doradus Jan 28 '23 at 16:10
2

You don't need to actually throw the exception; it is sufficient to create one:

int callersLineNumber = new Exception().getStackTrace()[1].getLineNumber();

Note that this requires neither try/catch nor a throws declaration.

Aasmund Eldhuset
  • 37,289
  • 4
  • 68
  • 81
  • 1
    Isn't this expensive? (It's for logging so I would rather have it be as cheap as possible) – nulldev Jun 30 '15 at 01:26
  • 1
    It's not a trivial operation, but I'm pretty sure the information needed to construct the stacktrace is readily available to the JVM at any time. However, you're the only one who can tell whether or not it's too expensive for _you_: try it and measure it. (Also, even if this makes the time to execute a log statement go from 10 to 100 microseconds, consider how much those extra 90 microseconds matter relative to the operations your application is performing.) – Aasmund Eldhuset Jun 30 '15 at 01:28
  • @nulldev Yes, it is, but it's also the only choice have, and it also assumes that the previous code was compiled with the debug flag enabled ;) – MadProgrammer Jun 30 '15 at 01:28
  • Ok, then thanks anyways :), I was hoping not to have to use this method since everybody is always telling me that exceptions are expensive and stuff. – nulldev Jun 30 '15 at 01:30
  • 1
    @nulldev: "Expensive" is such a relative word (hence the measurement advice): creating and throwing an exception are both slower than incrementing an `int`, but faster than reading from a file. So it depends on what you're doing, and don't shy away from the intended way of doing things unless you have the measurements to prove that it's too slow. – Aasmund Eldhuset Jun 30 '15 at 01:36