获取调用类和调用方法名-转贴

RK3568适配MIPI屏幕触摸,触摸延时很大 我用的是系统,接了一个,设备树已经正确配置,evtest测试坐标值和触摸位置都是准确的。但是出现了一个:我在屏幕上点一下,要等大约 2 秒才能在evtest里看到坐标事件打印。这种现象在 Goodix 系列触摸驱动里比较少见,一般意味着。 阅读详情

关键字: 企业应用     

恰好看到关于log的讨论。想起以前调查的一个问题。整理出来,希望对大家能有所帮助。

Sun JDK 源代码下载 http://wwws.sun.com/software/communitysource/
先注册并登录到“Sun Community Source Licensing”,然后下载J2SE(几十兆)或者J2EE(几百兆)。

Log能够把代码运行时间,类名,方法名,还有信息,全部都打印出来。
一个直观的例子,每次启动Tomcat(缺省配置)的时候。一般可以看到
Jul 9, 2004 11:22:29 AM org.apache.struts.util.PropertyMessageResources <init>
INFO: Initializing, config='org.apache.webapp.admin.ApplicationResources', returnNull=true
Jul 9, 2004 11:22:41 AM org.apache.coyote.http11.Http11Protocol start
INFO: Starting Coyote HTTP/1.1 on port 8080

时间,类名,方法名,信息都打印了出来。
那么,log是如何获取调用自身的这个类和这个方法名的呢?

后面给出的代码是JDK1.4的源代码,和Log4J的源代码。说明其实现原理。
获得调用类,和方法名,就是需要获得当前运行栈的结构。
new Throwable().getStackTrace() 会返回当前运行栈的结构层次。
利用这种原理,可以获得整个运行栈的调用关系。

JDK1.4的java.util.logging包, 通过Throwable.getStackTrace()方法实现的。
// Get the stack trace.
StackTraceElement stack[] = (new Throwable()).getStackTrace();

完整的代码在JDK1.4的源代码里面,java.util.logging.LogRecord类的inferCaller方法。
代码

   1. // Private method to infer the caller's class and method names
   2. private void inferCaller() {
   3. needToInferCaller = false;
   4. // Get the stack trace.
   5. StackTraceElement stack[] = (new Throwable()).getStackTrace();
   6. // First, search back to a method in the Logger class.
   7. int ix = 0;
   8. while (ix < stack.length) {
   9. StackTraceElement frame = stack[ix];
  10. String cname = frame.getClassName();
  11. if (cname.equals("java.util.logging.Logger")) {
  12. break;
  13. }
  14. ix++;
  15. }
  16. // Now search for the first frame before the "Logger" class.
  17. while (ix < stack.length) {
  18. StackTraceElement frame = stack[ix];
  19. String cname = frame.getClassName();
  20. if (!cname.equals("java.util.logging.Logger")) {
  21. // We've found the relevant frame.
  22. setSourceClassName(cname);
  23. setSourceMethodName(frame.getMethodName());
  24. return;
  25. }
  26. ix++;
  27. }
  28. // We haven't found a suitable frame, so just punt. This is
  29. // OK as we are only commited to making a "best effort" here.
  30. }

Log4j有异曲同工之妙。
org.apache.log4j.spi.LocationInfo类。
先用Throwable.printStackTrace()方法把Exception信息打印到一个字符串里。
然后按行分析这个字符串。抽出调用类和方法。参见LocationInfo类的构造函数。

代码

   1. /**
   2. Instantiate location information based on a Throwable. We
   3. expect the Throwable <code>t</code>, to be in the format
   4. 
   5. <pre>
   6. java.lang.Throwable
   7. ...
   8. at org.apache.log4j.PatternLayout.format(PatternLayout.java:413)
   9. at org.apache.log4j.FileAppender.doAppend(FileAppender.java:183)
  10. at org.apache.log4j.Category.callAppenders(Category.java:131)
  11. at org.apache.log4j.Category.log(Category.java:512)
  12. at callers.fully.qualified.className.methodName(FileName.java:74)
  13. ...
  14. </pre>
  15. 
  16. <p>However, we can also deal with JIT compilers that "lose" the
  17. location information, especially between the parentheses.
  18. 
  19. */
  20. public LocationInfo(Throwable t, String fqnOfCallingClass)

e.printStackTrace()把Exception发生当时的整个运行栈结构展开,打印出来。
Log4J就是分析这个打印结果,获得所有的调用层次。

关于直接获取调用类名的方法。
我们来看sun.reflect.Reflection的getCallerClass()方法的说明。

代码

   1. /** Returns the class of the method <code>realFramesToSkip</code>
   2. frames up the stack (zero-based), ignoring frames associated
   3. with java.lang.reflect.Method.invoke() and its implementation.
   4. The first frame is that associated with this method, so
   5. <code>getCallerClass(0)</code> returns the Class object for
   6. sun.reflect.Reflection. Frames associated with
   7. java.lang.reflect.Method.invoke() and its implementation are
   8. completely ignored and do not count toward the number of "real"
   9. frames skipped. */
  10. public static native Class getCallerClass(int realFramesToSkip);

这是一个native方法。原理也是根据StackFrame(运行栈)获取相应类的信息。
这个方法直接返回一个Class名字,直接有效。参数realFramesToSkip用来
选取你所需要的Stack层次,所以,你可以用这个方法获得任何层次的上的调用类名。

Throwable.getStackTrace()也是一个native方法。原理也是根据StackFrame
(运行栈)获取相应类的信息。返回一个StackTraceElement[]。
StackTraceElement类在JDK1.4的java.lang的包里面。里面包含丰富的信息,非常适合Debug。
StackTraceElement类有如下方法:
getFileName(),getLineNumber(), getClassName(), getMethodName()。
18:36  |   永久链接  |   浏览 (3445)  |   评论  (3)  | my blog   |   进入论坛  |
永久链接
http://buaawhl.javaeye.com/blog/6450
评论    共 3 条   
agilejava    2004-07-27 10:05

非常好:)
lllyq    2004-07-27 10:51

以前作unit test时,我也写过一个类似,主要就是getTrueMethod() 这个方法,
其中还包括jdk1.3的方法
可以直接使用。只要在类初始化时MethodTrace methodTrace = new MethodTrace();
,然后在方法中methodTrace.getTrueMethod()
代码

   1. /*
   2.  * Created on Feb 27, 2003 12:00:04 PM
   3.  *
   4.  */
   5. package com.bba96.util;
   6. 
   7. import java.io.PrintWriter;
   8. import java.io.StringWriter;
   9. 
  10. /**
  11.  * @author Leon
  12.  */
  13. public class MethodTrace {
  14.     // for jdk 1.4
  15.     private StackTraceElement elements[] ;
  16.     
  17.     StringWriter sw = new StringWriter();
  18.     PrintWriter out = new PrintWriter(sw);
  19.     private String trueMethodName = null;
  20.     private String methodName = null;
  21.     private String methodNameExTest = null;
  22.     private String e = null;
  23.     private int a[] = new int[2];
  24.     private int b;
  25.     private String cutStr = "test";
  26.     private int cutLength = cutStr.length();
  27.     private char[] line = null;
  28.     private StringBuffer buf = new StringBuffer();
  29.     public MethodTrace() {
  30.     }
  31.     private String cutTestStr(String str) {
  32.         if (str == null) {
  33.             return null;
  34.         }
  35.         String strLowerCase = str.toLowerCase();
  36.         int i = strLowerCase.indexOf(cutStr);
  37.         int j;
  38.         if (i != -1) {
  39.             line = str.toCharArray();
  40.             buf.setLength(str.length());
  41.             buf.append(line, 0, i);
  42.             i += cutLength;
  43.             j = i;
  44.             i = strLowerCase.indexOf(cutStr, i);
  45.             while (i != -1) {
  46.                 buf.append(line, j, i - j);
  47.                 i += cutLength;
  48.                 j = i;
  49.                 i = strLowerCase.indexOf(cutStr, i);
  50.             }
  51.             buf.append(line, j, line.length - j);
  52.             str = buf.toString();
  53.             buf.setLength(0);
  54.         }
  55.         return str;
  56.     }
  57.     public String getTrueMethod() {
  58.         trueMethodName = null;
  59.         try {
  60.             b = a[4];
  61.         } catch (ArrayIndexOutOfBoundsException aioobe) {
  62.             // jdk 1.3
  63.             /*
  64.             aioobe.printStackTrace(out);
  65.             out.flush();
  66.             e = sw.toString();
  67.             try {
  68.                 out.close();
  69.                 sw.close();
  70.             } catch (IOException e) {
  71.                 // Do nothing, this should not happen as it is StringWriter.
  72.             }
  73.             out = null;
  74.             sw = null;
  75.             boolean logError = false;
  76.             int pos = e.indexOf("at ");
  77.             for (int i = 0; i < 3; i++) {
  78.                 if (pos == -1) {
  79.                     logError = true;
  80.                     break;
  81.                 }
  82.                 e = e.substring(pos + 3, e.length());
  83.                 pos = e.indexOf("at ");
  84.             }
  85.             if (logError) {
  86.                 trueMethodName = "UnknownClass.unknownMethod()";
  87.             } else {
  88.                 trueMethodName = e.substring(0, e.indexOf('('));
  89.             }
  90.             */
  91.             
  92.             // for jdk 1.4
  93.             
  94.             elements = aioobe.getStackTrace();
  95.             if (elements.length < 3) {
  96.                 return "UnknownClass.unknownMethod()";
  97.             }
  98.             trueMethodName = elements[2].getClassName() + "." + elements[2].getMethodName();
  99.             
 100.         }
 101.         return trueMethodName;
 102.     }
 103.     public String getMethod() {
 104.         return methodName;
 105.     }
 106.     public String getMethodExTest() {
 107.         methodNameExTest = cutTestStr(getTrueMethod());
 108.         int index = methodNameExTest.lastIndexOf('.');
 109.         methodNameExTest =
 110.             methodNameExTest.substring(0, index + 1)
 111.                 + methodNameExTest.substring(index + 1, index + 2).toLowerCase()
 112.                 + methodNameExTest.substring(index + 2, methodNameExTest.length());
 113.         return methodNameExTest;
 114.     }
 115. }

buaawhl    2004-07-27 11:48

lllyq 写道
以前作unit test时,我也写过一个类似,主要就是getTrueMethod() 这个方法,其中还包括jdk1.3的方法
可以直接使用。只要在类初始化时MethodTrace methodTrace = new MethodTrace();,
然后在方法中methodTrace.getTrueMethod()

非常棒的代码。
for jdk1.3 的部分,和log4j的思路一样。在这方面,你和log4j大师有一比。
for jdk1.4 的部分也和JDK 1.4 Log的实现方法一样。

我以前怎么也不明白log4j是如何实现的。只有看了源代码才明白。
JDK1.4后来为了支持log才加入了StackTraceElement。
JDK1.3的时候,确实只能用分析Throwable StackTrace字符串这个方法实现。 

198、影像系统设计评审流程:从需求评审到 EVT、DVT、PVT 各阶段的关注重点 本文详细介绍了影像系统从需求评审到EVT、DVT、PVT各阶段的设计评审流程及关键点。作者通过实际案例(如IMX766模组偏紫问题)强调硬件工艺的重要性,指出影像系统是功能定义与物理实现的反复拉锯过程。文章分阶段解析:需求评审需将模糊需求转化为物理参数;架构评审要明确接口定义和时序约束;EVT阶段重点关注模组一致性和基础链路;DVT阶段需平衡算法调优与硬件验证;PVT阶段则以量产一致性为核心。最后提出建立"边界条件确认表"和"健康度看板"等实用建议,强调工程师需具备从表象追溯硬件根源的物理直觉。全文贯穿实战 阅读详情

相关推荐

NXP S32K3xx 多次复位(reset)后MCU跑死、崩溃、出错分析

s32k3出现多次复位后死机的情况

HeFlyYoung的博客 9513

Java反射机制——调用方法、获取父类和父接口

1、反射机制去调用方法(重点) 反射机制。让代码具有通用性,可变化的内容都是写到配置文件里面去,将来修改配置文件之后,创建的对象不一样,调用的方法也不同。但是Java源代码不需要做任何的改动。这就是反射机制的魅力。 2、利用反射机制获取父类和父接口(重点)...... 3、反射Method方法...

Best_Basic的博客 4616

从零到一:Abaqus与Matlab联合仿真的自动化流程构建指南

本文详细介绍了如何构建Abaqus与Matlab联合仿真的自动化流程,涵盖基础架构设计、关键接口技术实现、结果提取与处理技术以及高级参数化优化流程。通过Python脚本作为桥梁,实现数据传递和任务控制,帮助工程师提升仿真效率。特别强调了版本兼容性、异常处理和性能监控等实用技巧。

weixin_29090089的博客 611

java中获取调用类及调用方法

StackTraceElement stack[] = Thread.currentThread().getStackTrace(); 用运行环境:jdk1.6 package com.test;public class B { public static void main(String[] args) { A.test(); }}class A { static void tes

风语落尘 2694

anaconda安装-超详细版

文章目录一、anaconda安装1.1 anaconda安装地址1.2 安装详细步骤检验安装是否成功更改conda源(后续安装第三方库可以加快速度) 一、anaconda安装 Anaconda 是一个用于科学计算的 Python 发行版,支持 Linux, Mac, Windows, 包含了众多流行的科学计算、数据分析的 Python 包。装anaconda,就不需要单独装python了。 anaconda优点: 1、anaconda里面集成了很多关于python科学计算的第三方库,主要是安装方便,而p

in546的博客 25万+

SOC Boot学习(二)——JTAG Debug介绍

JTAG(Joint Test Action Group ,联合测试行动小组 ) 是一种国际标准测试协议,主要用于芯片内部测试及对系统进行仿真、调试。JTAG 技术是一种嵌入式调试技术,它在芯片内部封装了专门的测试电路 TAP ( Test Access Port ,测试访问口),通过专用的 JTAG 测试工具对内部节点进行测试。如今大多数比较复杂的器件都支持 JTAG 协议,如 ARM 、 DSP 、 FPGA 器件等。

yttt的博客 1605

得到当前方法的名字Thread.currentThread().getStackTrace()[1].getMethodName();

一个thread就是一个线程,当你编程使用多线程的时候,用currentthread()这个method来获取当前运行线程,以便对其进行操作。 简单来说就是 Tthread类(线程类) 中的一个方法 Thread.currentThread() 是指获取当前运行的线程对象 例如: Thread.currentThread().getName() 就是获取当前运行的线程的名称

u011159607的博客 5632

On the convergence of FedAvg on non-iid data

On the convergence of FedAvg on non-iid data

Lyn_S的博客 7081

java 获得调用者类名_如何在Java中获得调用者类

您可以生成堆栈跟踪并使用StackTraceElements中的信息。例如,一个实用程序类可以返回您的调用类名称:public class KDebug { public static String getCallerClassName() { StackTraceElement[] stElements = Thread.currentThread().getStackTrace(); for ...

weixin_30070339的博客 1110

滑模观测器与锁相环结合应用:让电机“无感”也能精准旋转的奥秘

本文介绍了永磁同步电机无传感器控制中的滑模观测器(SMO)结合锁相环(PLL)技术。SMO通过创建虚拟电机模型,利用电流误差产生控制信号来估计反电动势;PLL则从反电动势中解码转子位置和速度信息。该组合方案兼具SMO的鲁棒性和PLL的高精度,计算量小且硬件要求低。文章详细阐述了原理、数学模型、参数整定方法及实际实现技巧,包括离散化处理、符号函数替代等优化手段,并分析了低速性能限制、抖振问题等常见挑战及解决方案。最后指出该技术未来将与人工智能、多观测器融合等方向结合发展。

汽车软件开发 193

ESP32-IDF开发之旅 网络篇⑩ Web配网

本文介绍了基于ESP32S3的Web配网实现方案。作者通过移植开源项目,在ESP32S3上实现了WiFi配置功能,包括AP模式创建、HTTP服务器搭建、NVS存储读写等核心功能。文章详细解析了代码结构,包含WiFi初始化、事件处理、NVS存储管理和HTML页面服务等关键模块。实现方案采用AP+STA双模式,支持通过网页扫描WiFi并保存配置信息,适用于物联网设备的网络配置场景。代码中使用了FreeRTOS任务、ESP-IDF事件组等技术,并提供了完整的错误处理和日志记录功能。

单片机菜鸟哥的博客 350

Java获取调用当前方法的类名或方法名(栈堆信息)的4种方式

在java代码中,是可以在运行时通过某种方式获取到当前方法被谁调用了(调用链路)。目前我所知道的有四种方式(通过Thread、Throwable、SecurityManager获取)

星月昭铭的博客 6599

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Log信息获取调用类和调用方法名的实现原理

    Sun JDK 源代码下载 http://wwws.sun.com/software/communitysource/  先注册并登录到“Sun Community Source Licensing”,然后下载J2SE(几十兆)或者J2EE(几百兆)。    Log能够把代码运行时间,类名,方法名,还有信息,全部都打印出来。        一个直观的例子,每次启动Tomcat(缺省配置

Marvin 1584

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

java 获取调用者方法_Java 运行时获取调用类和调用方法名的几种方式

最近在封装一个Java报警的SDK,期望应用程序在调用SDK报警API方法时能调用类和调用方法名并通过邮件和短信的方式通知给开发者。大致有两种方式,总结一下。1. 通过Throwable.getStackTrace()StackTraceElement[] arr = (new Throwable()).getStackTrace();for(int i=0; iStackTraceElement...

weixin_32950005的博客 2784

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

java 获取调用类的类名和方法名

转自http://yxwang0615.iteye.com/blog/998452String classname = new Exception().getStackTrace()[1].getClassName(); //获取调用者的类名 String method_name = new Exception().getStackTrace()[1].getMethodName(); //获取调

高飞的专栏 1万+

java获取当前类的类名和方法名

获取当前类的类名

二木成林 1万+
上一篇: 关于LOG的输出
下一篇: Log4j日志管理系统简单使用说明
java_user
博客等级 码龄21年 11粉丝 40原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值