java获取静态类_从Java中的静态方法获取类名

因此,我们有一种情况需要静态获取类对象或类完整/简单名称而不需要明确使用MyClass.class语法。

在某些情况下它可以非常方便,例如kotlin上层函数的logger实例(在这种情况下,kotlin创建了一个无法从kotlin代码访问的静态Java类)。

我们有一些不同的变体来获取此信息:

new Object(){}.getClass().getEnclosingClass();

Tom Hawtin 指出- 强调

getClassContext()[0].getName();从SecurityManager

所指出克里斯托弗

new Throwable().getStackTrace()[0].getClassName();

通过计数路德维希

Thread.currentThread().getStackTrace()[1].getClassName();

来自Keksi

最后

MethodHandles.lookup().lookupClass();

来自Rein的精彩

我已为所有变体准备了jmh基准,结果如下:

# Run complete. Total time: 00:04:18

Benchmark                                                      Mode  Cnt      Score     Error  Units

StaticClassLookup.MethodHandles_lookup_lookupClass             avgt   30      3.630 ±   0.024  ns/op

StaticClassLookup.AnonymousObject_getClass_enclosingClass      avgt   30    282.486 ±   1.980  ns/op

StaticClassLookup.SecurityManager_classContext_1               avgt   30    680.385 ±  21.665  ns/op

StaticClassLookup.Thread_currentThread_stackTrace_1_className  avgt   30  11179.460 ± 286.293  ns/op

StaticClassLookup.Throwable_stackTrace_0_className             avgt   30  10221.209 ± 176.847  ns/op

结论

最好的变种,相当干净,怪异的快速。

仅在Java 7和Android API 26之后可用!

MethodHandles.lookup().lookupClass();

如果您需要Android或Java 6的此功能,您可以使用第二个最佳变体。它也相当快,但在每个使用地点创建一个匿名类 :(

new Object(){}.getClass().getEnclosingClass();

如果你在很多地方需要它并且不希望你的字节码由于大量的匿名类而膨胀 - SecurityManager是你的朋友(第三个最佳选择)。

但你不能只是打电话getClassContext()- 它在SecurityManager课堂上受到保护。你需要一些像这样的助手类:

// Helper class

public final class CallerClassGetter extends SecurityManager

{

private static final CallerClassGetter INSTANCE = new CallerClassGetter();

private CallerClassGetter() {}

public static Class> getCallerClass() {

return INSTANCE.getClassContext()[1];

}

}

// Usage example:

class FooBar

{

static final Logger LOGGER = LoggerFactory.getLogger(CallerClassGetter.getCallerClass())

}

您可能根本不需要使用基于getStackTrace()from例外的最后两个变体Thread.currentThread()。非常低效,只能返回类名String,而不是Class实例。

PS

如果你想为静态kotlin utils创建一个logger实例(比如我:),你可以使用这个帮助器:

import org.slf4j.Logger

import org.slf4j.LoggerFactory

// Should be inlined to get an actual class instead of the one where this helper declared

// Will work only since Java 7 and Android API 26!

@Suppress("NOTHING_TO_INLINE")

inline fun loggerFactoryStatic(): Logger

= LoggerFactory.getLogger(MethodHandles.lookup().lookupClass())

用法示例:

private val LOGGER = loggerFactoryStatic()

/**

* Returns a pseudo-random, uniformly distributed value between the

* given least value (inclusive) and bound (exclusive).

*

* @param min the least value returned

* @param max the upper bound (exclusive)

*

* @return the next value

* @throws IllegalArgumentException if least greater than or equal to bound

* @see java.util.concurrent.ThreadLocalRandom.nextDouble(double, double)

*/

fun Random.nextDouble(min: Double = .0, max: Double = 1.0): Double {

if (min >= max) {

if (min == max) return max

LOGGER.warn("nextDouble: min $min > max $max")

return min

}

return nextDouble() * (max - min) + min

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值