当我们在记录日志时,每个类中会定义一个日志对象,然后利用这个对象去写日志,那么我们在处理日志时,如何能才能记录日志对象所在的类、方法和行号呢?log4j中已经实现了该功能,那么它是怎么实现的呢?

其实我们可以这样,在要写日志的代码时获得当前的线程信息,这样我们就可以获得上个线程的信息了(即对象写日志所在类的信息)。

先看以下列子。

新建Location类和Test类:

Location:

public class Location {
public void getInfo(){
String location="";
StackTraceElement[] stacks = Thread.currentThread().getStackTrace();
location = "类名:"+stacks[2].getClassName() + "\n函数名:" + stacks[2].getMethodName()
+ "\n文件名:" + stacks[2].getFileName() + "\n行号:"
+ stacks[2].getLineNumber() + "";
System.out.println(location);
}
}

Test:

public class Test {

	public static void main(String[] args) {
Location l = new Location();
l.getInfo();
} }

执行Test中的main函数,得到以下结果:

类名:thread.Test
函数名:main
文件名:Test.java
行号:10

是不是输出了Test类中调用的信息呢?那么有很多人就问了,为什么location类中调用的是stacts[2]而不是stacts[0]或其他的呢?

针对这个问题,我们可以将stacts数组里面的东西遍历输出一下就知道了:

StackTraceElement[] stacks = Thread.currentThread().getStackTrace();
for(int i=0;i<stacks.length;i++){
location = i+" at "+stacks[i].getClassName() + "." + stacks[i].getMethodName()
+ "(" + stacks[i].getFileName() + ":"
+ stacks[i].getLineNumber() + ")";
System.out.println(location);
}

再次执行,输出结果如下:

0  at java.lang.Thread.getStackTrace(Thread.java:1436)
1 at thread.Location.getInfo(Location.java:6)
2 at thread.Test.main(Test.java:7)

那么这就好理解了,线程是以栈形式存放的,

分析一下StackTraceElement[] stacks = Thread.currentThread().getStackTrace();

此代码中会创建2个线程,调用Thread.currentThread().getStackTrace()时底层会创建一个线程,我们调用它也会创建一个线程,然后test调用getInfo函数时会创建一个线程,这样总共就三个线程了,程序执行顺序是先test类中调用getInfo方法,然后getInfo方法中调用StackTraceElement[] stacks = Thread.currentThread().getStackTrace();调用StackTraceElement[] stacks = Thread.currentThread().getStackTrace();时底层还会创建一个线程,根据栈的原理先进后出规则,他们的排队顺序就是上面输出的结果了。

模拟log4j获取日志对象调用所在的类名、方法名及行号的更多相关文章

  1. Java: 获取当前执行位置的文件名/类名/方法名/行号

    在 JAVA 程序有时需要获取当前代码位置, 于是就利用 Thread.currentThread().getStackTrace() 写了下面这个工具类, 用来获取当前执行位置处代码的文件名/类名/ ...

  2. 通过supper()有参构造器,完成子类对象调用父类属性的方法,并完成赋值

    package com.Summer_0426.cn; /** * @author Summer * 通过supper()有参构造器,完成子类对象调用父类属性的方法,并完成赋值 * */ public ...

  3. java获取调用当前方法的方法名和行数

    java获取调用当前方法的方法名和行数String className = Thread.currentThread().getStackTrace()[2].getClassName();//调用的 ...

  4. WPF 异常其他信息: “对类型“BaseControl.KImgButton”的构造函数执行符合指定的绑定约束的调用时引发了异常。”,行号为“38”,行位置为“22”。

    引发的异常:“System.Windows.Markup.XamlParseException”(位于 PresentationFramework.dll 中) 其他信息: “对类型“BaseCont ...

  5. 获取LayoutInflater对象的方法和inflate方法的一些参数问题

    一.获取LayoutInflater的三种方法 1. LayoutInflater layoutInflater = (LayoutInflater) MainActivity.this.getSys ...

  6. 福利->KVC+Runtime获取类/对象的属性/成员变量/方法/协议并实现字典转模型

    我们知道,KVC+Runtime可以做非常多的事情.有了这个,我们可以实现很多的效果. 这里来个福利,利用KVC+Runtime获取类/对象的所有成员变量.属性.方法及协议: 并利用它来实现字典转模型 ...

  7. 反射的妙用-类名方法名做参数进行方法调用实例demo

    首先声明一点,大家都会说反射的效率低下,但是大多数的框架能少了反射吗?当反射能为我们带来代码上的方便就可以用,如有不当之处还望大家指出 1,项目结构图如下所示:一个ClassLb类库项目,一个为测试用 ...

  8. Java父类对象调用子类实体:方法重写与动态调用

    众所周知Java的handle和C++的ponter而不是object对应,我们很熟悉C++的父类pointer调用子类实体的例子,那么对于Java的handle是不是也可以这样呢? 这里我先给一个例 ...

  9. Asp.net .net(C#) 获取当前命名空间,类名,方法名的方法

    public static string GetMethodInfo() {     string str = "";      //取得当前方法命名空间     str += & ...

随机推荐

  1. TestNG中同一个类中执行多个test()方法如何配置testng.xml

    public class IndexInfo extends BaseTesting{ private IndexPage IndexPage1;// private AddEquipmentInfo ...

  2. Enter回车切换输入焦点方法兼容各大浏览器

    做项目时,客户要求能够用enter回车直接切换输入(焦点),当最后一个时候,直接提交信息. 第一想法就是,网上去copy一段代码直接用.但了百度.谷歌找了个遍,找到的代码80%以上都是一样的.有的代码 ...

  3. 数往知来C#之 正则表达式 委托 XML<六>

    C# 正则表达式篇 一.正则表达式 正则表达式就是一个字符串,不要想着一下子可以写出一个通用的表达式,先写,不正确再改 写正则表达式就是在找规律 关键字:Regex    -->引入命名空间  ...

  4. 捣蛋phpwind控制器注入

    在PwBaseController 里面,会有这个方法的存在 /** * action Hook 注册 * * @param string $registerKey 扩展点别名 * @param Pw ...

  5. Winsock IO模型之select模型

    之所以称其为select模型是因为它主要是使用select函数来管理I/O的.这个模型的设计源于UNIX系统,目的是允许那些想要避免在套接字调用上阻塞的应用程序有能力管理多个套接字. int sele ...

  6. WebApi参数传递

    c# webapi的参数传递方式:1.查询字符串(query string):2.内容主体(content body) 当然也有cookie或url部分或头部信息(header)等其它传方式,这里仅讨 ...

  7. Android4.4 耳机检测分析

    在ALSA架构中,ASOC是由3个部分组成:Platform.CODEC & Machine.而耳机检测一般是在Machine driver里实现,当然也可以在CODEC driver里实现. ...

  8. 基于gSOAP使用头文件的C语言版web service开发过程例子

    基于gSOAP使用头文件的C语言版web service开发过程例子 一服务端 1 打开VS2005,创建一个工程,命名为calcServer. 2 添加一个头文件calc.h,编辑内容如下: 1// ...

  9. SCAU 10893 Spiral

    10893 Spiral 时间限制:1000MS  内存限制:65535K 题型: 编程题   语言: 无限制 Description Given an odd number n, we can ar ...

  10. css 样式大全

    字体属性:(font) 大小 {font-size: x-large;}(特大) xx-small;(极小) 一般中文用不到,只要用数值就可以,单位:PX.PD 样式 {font-style: obl ...