Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
__Java中的行_uuu等价物?_Java_Logging_Portability - Fatal编程技术网

__Java中的行_uuu等价物?

__Java中的行_uuu等价物?,java,logging,portability,Java,Logging,Portability,我正在寻找一种方法,将\uuuu LINE\uuu作为编译时常量包含在输出的消息中 各种解决方案似乎都存在,但如和中所建议的,运行时代价很大。它们通常总是基于运行时对象StackFrame作为log4j 在需要的基础上使用log4j启用/禁用的可能性也不是一个选项,因为通常在发生错误时,启用行号为时已晚,并且内联代码似乎不再有任何行号。 . 是否可以: 在编译之前对java源文件进行预处理,最好是与Eclipse1集成,这样也可以在开发平台上对其进行测试 能够在加载时预处理类。通过摊销,间接费用

我正在寻找一种方法,将
\uuuu LINE\uuu
作为编译时常量包含在输出的消息中

各种解决方案似乎都存在,但如和中所建议的,运行时代价很大。它们通常总是基于运行时对象
StackFrame
作为log4j

在需要的基础上使用log4j启用/禁用的可能性也不是一个选项,因为通常在发生错误时,启用行号为时已晚,并且内联代码似乎不再有任何行号。 . 是否可以:

  • 在编译之前对java源文件进行预处理,最好是与Eclipse1集成,这样也可以在开发平台上对其进行测试
  • 能够在加载时预处理类。通过摊销,间接费用可以忽略不计

  • 一,。事实上,我确实使用了一个丑陋的黑客:在构建服务器上通过ANT技巧签出后调用自定义预处理器,不可能获得C中编译时发生的
    \uu行的效果

    您可以通过在运行时调用这样的函数来获取行号

    public static int lineNumber() {
        return Thread.currentThread().getStackTrace()[2].getLineNumber();
    }
    

    如果使用
    debug=line
    选项编译,则行信息存在于类文件中,但VM可以在运行时将其丢弃。这取决于启动Java程序时可以指定的一些选项。通常,使用调试信息运行的性能损失约为5%,再加上perm gen空间中多一点内存。由于这些信息非常宝贵,我认为没有理由剥夺这些信息

    您的评论(
    Util.java(内联编译代码)
    )表明您正在使用积极的优化。如果可以的话,把它们关掉。这样,您可以简单地:

    // For Java 1.4, use new Exception().getStackTrace()
    int line = Thread.currentThread().getStackTrace()[0].getLineNumber();
    
    当您需要它时(即
    catch
    if(log.isInfoEnabled())
    的内部)


    至于
    \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
    ,Java编译器不支持这一点。您唯一的选择是使用一些黑客来过滤源代码。我建议在某个地方定义一个变量
    int\uuuuu LINE\uuuu
    ,并在需要时将其设置为某个随机值(0是足够随机的)。然后编写一个过滤器,用当前行号替换
    \uuuuuuuuu行中的数字。这允许将行号固定在适当的位置。

    开箱即用,我不认为Java提供了您所需要的

    然而,如果您要编写自己的注释处理器并使用Java6.0,我认为您可以解决这个问题。我不想猜测这样做需要做多少工作


    请注意,Eclipse允许您在其构建机制中包含自己的注释处理。

    我不知道Java编译器中有这样的事情。但是,您可以编写一个简单的程序,用文件中的行号替换像
    \uuuuu LINE\uuuu
    这样的标记,并配置您的构建过程以在编译之前执行此工具。某种类型的预处理器。

    我会为此使用日志框架,让它处理混乱的细节。java.util.logging和logback都可以很容易地显示调用方的信息,类似于LINE可以提供的信息


    主要的好处是,只在必要时计算信息,因此不输出意味着没有开销。

    这是真的,即开箱即用,这些宏不可用。 但是,使用检测和调试信息,您可以实现它。
    检查

    我发现如果您正在寻找“到达这里,到达这里”类型的日志记录,这个类会使事情变得简单。我在项目中添加了一个文件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”。

    只是出于好奇:为什么需要日志中的行号?当发生错误时,您有完整的stacktrace,它指示行号…有时在异常中,我有类似于
    Util.java(内联编译代码)
    的行号,而不是行号。有时我没有任何例外,只是记录信息:“在这里”,“在这里”,我不想麻烦有唯一的消息(行号使它们是唯一的),JVM应该能够处理这种情况。您使用什么版本的Java?要回答romaintaz的问题:我们创建GWT应用程序,它是从Java编译的Javascript。在编译过程中,类名和行号丢失,所以堆栈跟踪提供了无用的信息。它向我指出了已编译的Javascript代码,但很难或不可能从中找到相应的Java代码。注意-从2016年起,Java的现代版本在内联时不会丢弃行号信息。为什么
    new Exception().getStackTrace()
    而不是
    Thread.currentThread().getStackTrace())
    ?没有理由,但事实是,我没有费心搜索Thread类以了解如何获取当前堆栈,并且我知道存在一个异常:)+1用于a解决方案,该解决方案也可以在我的开发环境中使用(只需在构建过程中用行号搜索并替换
    Thread…
    Thread.currentThread().getStackTrace()
    在1.4.2中似乎不存在<代码>新异常()。getStackTrace()
    然后就会出现。并在生成时替换为实际生产行号。为什么说
    Thread.currentThread().getStackTrace()[0].getLineNumber()而下面的答案是
    Thread.currentThread().getStackTrace()[2].getLineNumber()和下面的另一个答案使用
    getStackTrace()[3]
    ?另外,我在代码中尝试了这一点,得到一条消息,显示行号=1503,而实际上是源文件中的第20行。这是为什么?关于该行的调试信息必须编译到类文件中,才能访问这些信息。这正是w