__LINE__ эквивалент в Java?
Я ищу способ включить __LINE__
в качестве константы времени компиляции в выводимых сообщениях.
Существуют различные решения, но с большим штрафом за выполнение, предложенным в __LINE__
в JS и __LINE__
в С#. Обычно они всегда основаны на объекте времени выполнения StackFrame
как log4j.
Использование log4j Возможность включения/выключения по необходимости не является вариантом, поскольку обычно, когда происходит ошибка, слишком поздно, чтобы включить номера строк, а встроенный код, похоже, не имеет номеров строк Больше.
, Было бы возможно:
- Предварительно обрабатывайте исходные файлы java перед компиляцией, в идеале, с чем-то интегрированным с Eclipse 1 поэтому его можно также протестировать на платформе разработки.
- Уметь предварительно обрабатывать класс во время загрузки. Накладные расходы тогда были бы незначительными, если были амортизированы.
<суб > 1. На самом деле я использую уродливый хак: вызов пользовательского препроцессора сразу после проверки на сервере сборки с помощью ANT трюков
Ответы
Ответ 1
Если вы компилируете параметр debug=line
, информация о строке существует в файле класса, но виртуальная машина может выбросить ее во время выполнения. Это зависит от некоторых параметров, которые вы можете указать при запуске программы Java. Как правило, ограничение производительности для работы с информацией об отладке составляет около 5% плюс немного больше памяти в пространстве perm gen. Поскольку эта информация настолько бесценна, я не вижу причин лишать эту информацию.
Ваш комментарий (Util.java(Inlined Compiled Code)
) предполагает, что вы используете агрессивную оптимизацию. Если можете, отключите их. Таким образом, вы можете просто:
// For Java 1.4, use new Exception().getStackTrace()
int line = Thread.currentThread().getStackTrace()[0].getLineNumber();
когда вам это нужно (т.е. внутри catch
или if (log.isInfoEnabled())
).
Что касается __LINE__
, компилятор Java не поддерживает этого. Ваш единственный вариант - использовать некоторые хаки для фильтрации источника. Я предлагаю где-то определить переменную int __LINE__
и установить ее для некоторого случайного значения (0 достаточно случайным), когда вам это нужно. Затем напишите фильтр, который заменяет число в __LINE__ = \d+
текущим номером строки. Это позволяет исправить номер строки на месте.
Ответ 2
Невозможно получить эффект __LINE__
в C, который происходит во время компиляции.
Вы можете получить номер строки, вызвав такую функцию во время выполнения,
public static int lineNumber() {
return Thread.currentThread().getStackTrace()[2].getLineNumber();
}
Ответ 3
Это правда, что из коробки эти макросы недоступны.
Однако с помощью инструментария и отладочной информации вы можете ее реализовать.
проверьте http://www.gallot.be/?p=85
Ответ 4
Я нашел, что этот класс упрощает работу, если вы ищете регистрацию типа "добрались сюда, добрались досюда". У меня есть файл Here.java, который я добавляю к моим проектам, который содержит только следующее определение класса:
public class Here {
public static String at () {
StackTraceElement ste = Thread.currentThread().getStackTrace()[3];
String where = ste.getClassName() + " " + ste.getMethodName() + " " + ste.getLineNumber() + " ";
return where;
}
}
Чтобы использовать его в своей простейшей форме:
Log.v(TAG, Here.At());
Или, если вы хотите увидеть другие вещи:
Log.v(TAG, Here.At() + String.format("interesting value = %d", my_val));
Это дало бы "com.otherpackagenamestuff.MyClass myMethod 225" в первом случае и то же самое, но с "интересным значением = 123", добавленным во втором случае.
Ответ 5
Я использовал бы фреймворк для регистрации, и пусть это будет иметь дело с беспорядочными деталями. Как java.util.logging, так и logback могут легко отображать информацию о вызывающем абоненте, которая похожа на LINE.
Основным преимуществом является то, что информация вычисляется только при необходимости, поэтому не выводить накладные расходы нет.
Ответ 6
Из коробки я не думаю, что Java предлагает то, что вам нужно.
Однако, если вы должны написать свой собственный обработчик аннотаций и использовать API-интерфейс Java 6.0 я думаю, вы могли бы решить эту проблему. Я не хотел бы догадываться, сколько работы это будет для этого.
Обратите внимание, что Eclipse позволяет включать вашу собственную обработку аннотаций в свой механизм сборки.
Ответ 7
Я не знаю о такой вещи в Java-компиляторе. Но вы можете написать простую программу, которая заменяет токен типа __LINE__
на linenumber в файле и настраивает процесс сборки для выполнения этого инструмента перед компиляцией. Какой-то препроцессор.