如何通过实用方法在Java中检索类的名称?

huangapple go评论65阅读模式
英文:

How to retrieve name of the class in java through Utility methods?

问题

我正在尝试减少我的应用程序中的代码行数。出于日志记录的目的,我有一个方法,我之前在每个类中创建了这个方法来获取类和方法的名称。

public String currentClassAndMethod() {
    // getStackTrace()[1] 方法返回实现方法名称的第一个索引
    return "在类中: " + getClass().getSimpleName() + " 在方法中的名称: "
            + new Throwable().getStackTrace()[1].getMethodName();
}

当上述方法在实现类(Controller、Service 等)中时,它可以正常工作,但当我将其放在 Util 类中时,它会给我返回 Util 类的名称。

@GetMapping("/products")
public List<Product> getProducts() {
    logger.info(ecommUtils.currentClassAndMethod());
    List<Product> productList = productService.getProducts();
    return productList;
}

我无法将这个方法设置为静态的。我想要实现的目标是在一个地方定义这个方法,然后从每个类中调用这个方法。

英文:

I am trying to reduce the line of codes in my application. For logging purpose, I have a method which I created earlier in every class to retrieve the name of class and method.

	public String currentClassAndMethod() {
	// getStackTrace()[1] method return implementing method name at 1st index
	return &quot;Inside class: &quot; + getClass().getSimpleName() + &quot; in method name: &quot;
			+ new Throwable().getStackTrace()[1].getMethodName();

}

The above method works fine when it is inside the implementing class(Controller, Service classes etc) but when I put it inside a Util class it gives me the name of the Util class.

	@GetMapping(&quot;/products&quot;)
    public List&lt;Product&gt; getProducts() {
	logger.info(ecommUtils.currentClassAndMethod());
	List&lt;Product&gt; productList = productService.getProducts();
	return productList;

}

I can't make this method static. What I want to achieve is to define this method in a single place and then call this method from every class.

答案1

得分: 1

你有一些严重的问题:

  1. 调用 getStackTrace() 的速度确实很慢。
  2. 你正在错误的位置进行工作;通常情况下,你希望日志记录系统自己来处理这个问题。你的代码应该只关心需要记录的字符串内容和记录的级别。日志框架的任务是如何呈现这些信息的(例如,日志框架可以添加日志语句的位置和当前时间,等等)。
  3. getClass() 总是返回包含 currentClassAndMethod() 方法的类,因此不是你想要的。以下代码可以解决这个问题:
int nestingLevel = 1;
StackTraceElement elem = new Throwable().getStackTrace()[nestingLevel];
return elem.getFileName() + "::" + elem.getMethodName() + "::" + elem.getLineNumber();
// 如果你更喜欢的话,也可以使用 elem.getClassName()。

所以,这就是你应该这样做的方式... 如果你想这样做的话。我建议你不要这样做。如果你必须这样做,注意如果你将这个“获取位置”的代码调用放在日志基础设施内部,比如日志处理程序中(我不知道你使用的是什么日志框架,所以我只能说得比较笼统)-这样,如果你以一个你忽略的级别进行日志记录,你就不需要花费昂贵的时间来获取堆栈跟踪,只为了让生成的字符串通过日志基础设施并因为在配置的“在这个级别记录”下方而被完全忽略。

英文:

You've got some serious issues here:

  1. Calling getStackTrace() is really quite slow.
  2. You're doing the job in the wrong place; as a rule, you want the logging system itself to take care of this. Your code should just be worried about what string needs to be logged, and at what level. Your logging framework's job is how to render this information (for example, it's up to the logging framework to add the location of the log statement and the current time, for example.
  3. getClass() is always returning the class that your currentClassAndMethod() method is in, and therefore not what you want. This would work:
int nestingLevel = 1;
StackTraceElement elem = new Throwable().getStackTrace[nestingLevel];
return elem.getFileName() + &quot;::&quot; + elem.getMethodName() + &quot;::&quot; + elem.getLineNumber();
// there is elem.getClassName() too if you prefer that.

So, that's how you'd do it.. if you want to do it. I advise you don't. If you must, note that you can speed things up quite a lot if you move the invocation of this 'get me the location' code inside the logging infrastructure, for example in a log handler (I don't know what logging framework you use, so I have to be vague about it) – that way, if you log at a level that you're ignoring, you don't need to spend the expensive time fetching a stack trace just for the generated string to make its way through the logging infrastructure and get completely ignored because it's below the configured 'log at this level'.

huangapple
  • 本文由 发表于 2020年9月11日 21:35:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/63848180.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定