/xian-core/src/test/java/info/xiancloud/yy/TestGetCallerClassName.java

https://github.com/happyyangyuan/xian · Java · 120 lines · 75 code · 21 blank · 24 comment · 1 complexity · 51263d3f33c2ce41a511021fd497455e MD5 · raw file

  1. package info.xiancloud.yy;
  2. import org.apache.logging.log4j.util.StackLocatorUtil;
  3. /**
  4. * Test the speed of various methods for getting the caller class name
  5. */
  6. public class TestGetCallerClassName {
  7. /**
  8. * Abstract class for testing different methods of getting the caller class name
  9. */
  10. private static abstract class GetCallerClassNameMethod {
  11. public abstract String getCallerClassName(int callStackDepth);
  12. public abstract String getMethodName();
  13. }
  14. /**
  15. * Uses the internal Reflection class
  16. */
  17. private static class ReflectionMethod extends GetCallerClassNameMethod {
  18. public String getCallerClassName(int callStackDepth) {
  19. return sun.reflect.Reflection.getCallerClass(callStackDepth).getName();
  20. }
  21. public String getMethodName() {
  22. return "Reflection";
  23. }
  24. }
  25. /**
  26. * Get a stack trace from the current thread
  27. */
  28. private static class ThreadStackTraceMethod extends GetCallerClassNameMethod {
  29. public String getCallerClassName(int callStackDepth) {
  30. return Thread.currentThread().getStackTrace()[callStackDepth].getClassName();
  31. }
  32. public String getMethodName() {
  33. return "Current Thread StackTrace";
  34. }
  35. }
  36. /**
  37. * Get a stack trace from a new Throwable
  38. */
  39. private static class ThrowableStackTraceMethod extends GetCallerClassNameMethod {
  40. public String getCallerClassName(int callStackDepth) {
  41. return new Throwable().getStackTrace()[callStackDepth].getClassName();
  42. }
  43. public String getMethodName() {
  44. return "Throwable StackTrace";
  45. }
  46. }
  47. /**
  48. * Use the SecurityManager.getClassContext()
  49. */
  50. private static class SecurityManagerMethod extends GetCallerClassNameMethod {
  51. public String getCallerClassName(int callStackDepth) {
  52. return mySecurityManager.getCallerClassName(callStackDepth);
  53. }
  54. public String getMethodName() {
  55. return "SecurityManager";
  56. }
  57. /**
  58. * A custom security manager that exposes the getClassContext() information
  59. */
  60. static class MySecurityManager extends SecurityManager {
  61. public String getCallerClassName(int callStackDepth) {
  62. return getClassContext()[callStackDepth].getName();
  63. }
  64. }
  65. private final static MySecurityManager mySecurityManager =
  66. new MySecurityManager();
  67. }
  68. private static class Log4j2StackLocatorUtilMethod extends GetCallerClassNameMethod {
  69. @Override
  70. public String getCallerClassName(int callStackDepth) {
  71. return StackLocatorUtil.getCallerClass(callStackDepth).getName();
  72. }
  73. @Override
  74. public String getMethodName() {
  75. return "Log4j2StackLocatorUtil";
  76. }
  77. }
  78. /**
  79. * Test all four methods
  80. */
  81. public static void main(String[] args) {
  82. testMethod(new Log4j2StackLocatorUtilMethod());
  83. testMethod(new ReflectionMethod());
  84. testMethod(new ThreadStackTraceMethod());
  85. testMethod(new ThrowableStackTraceMethod());
  86. testMethod(new SecurityManagerMethod());
  87. }
  88. private static void testMethod(GetCallerClassNameMethod method) {
  89. long startTime = System.nanoTime();
  90. String className = null;
  91. for (int i = 0; i < 1000000; i++) {
  92. className = method.getCallerClassName(2);
  93. }
  94. printElapsedTime(method.getMethodName(), startTime);
  95. }
  96. private static void printElapsedTime(String title, long startTime) {
  97. System.out.println(title + ": " + ((double) (System.nanoTime() - startTime)) / 1000000 + " ms.");
  98. }
  99. }