예제 #1
0
  public static void main(String[] arg) throws Throwable {

    MethodHandles.Lookup lookup = MethodHandles.lookup();
    Class thisClass = lookup.lookupClass(); // (who am I?)

    MethodType methodType;
    MethodHandle methodHandle;

    Employee employee = new Employee();
    String name;

    Field fieldName = null;
    for (Field field : Employee.class.getDeclaredFields()) {
      if (field.getName().equals("name")) {
        fieldName = field;
        fieldName.setAccessible(true);
        break;
      }
    }

    // Lookup invoke dynamic
    methodType = MethodType.methodType(String.class);
    methodHandle = lookup.findVirtual(Employee.class, "getName", methodType);
    name = (String) methodHandle.invokeExact(new Employee());
    System.out.println("invoke dynamic " + name);

    // Lookup reflection
    Method method = Employee.class.getMethod("getName", new Class<?>[] {});
    name = (String) method.invoke(new Employee());
    System.out.println("reflection " + name);

    // Lookup Handle Field Direct
    MethodHandle methodHandleFieldDirect = lookup.unreflectGetter(fieldName);
    name = (String) methodHandleFieldDirect.invokeExact(new Employee());
    System.out.println("method handle for field direct " + name);

    long start = 0;
    long end = 0;
    long times = 10_000;
    long regularTime;
    long invokeDynamicTime;
    long reflectionTime;
    long count = 0;
    long invokeDynamicTimeUsingField;
    long fieldDirect;

    // warm up
    for (int index = 0; index < times; index++) {
      employee.getName();
      name = (String) methodHandle.invokeExact(employee);
      name = (String) method.invoke(employee);
      name = (String) methodHandleFieldDirect.invokeExact(employee);
    }

    // regular method call time
    start = System.nanoTime();
    for (int index = 0; index < times; index++) {
      name = employee.getName();
      count += name.hashCode();
    }
    count = 0;
    end = System.nanoTime();
    regularTime = end - start;
    System.out.printf("regular method call time        			= %d\n", regularTime / times);

    // invoke dynamic method call time
    start = System.nanoTime();
    for (int index = 0; index < times; index++) {
      name = (String) methodHandle.invokeExact(employee);
      count += name.hashCode();
    }
    count = 0;
    end = System.nanoTime();
    invokeDynamicTime = end - start;

    System.out.printf("invoke dynamic method call time 			= %d\n", invokeDynamicTime / times);

    // reflection method call time
    start = System.nanoTime();
    for (int index = 0; index < times; index++) {
      name = (String) method.invoke(employee);
      count += name.hashCode();
    }
    count = 0;
    end = System.nanoTime();
    reflectionTime = end - start;
    System.out.printf("reflection method call time     			= %d\n", reflectionTime / times);

    //
    start = System.nanoTime();
    for (int index = 0; index < times; index++) {
      name = (String) methodHandleFieldDirect.invokeExact(employee);
      count += name.hashCode();
    }
    count = 0;
    end = System.nanoTime();
    invokeDynamicTimeUsingField = end - start;
    System.out.printf(
        "field method invoke dynamic call time     		= %d\n", invokeDynamicTimeUsingField / times);

    //
    start = System.nanoTime();
    for (int index = 0; index < times; index++) {
      name = (String) fieldName.get(employee);
      count += name.hashCode();
    }
    count = 0;
    end = System.nanoTime();
    fieldDirect = end - start;
    System.out.printf("field method reflection call time     			= %d\n", fieldDirect / times);
  }
예제 #2
0
  static {
    Field charsField =
        AccessController.doPrivileged(
            new PrivilegedAction<Field>() {
              @Override
              public Field run() {
                Field charsField;
                try {
                  charsField = String.class.getDeclaredField("value");
                  charsField.setAccessible(true);
                } catch (NoSuchFieldException ex) {
                  LOG.info("char array stealing from String not supported", ex);
                  charsField = null;
                } catch (SecurityException ex) {
                  throw new RuntimeException(ex);
                }
                return charsField;
              }
            });
    MethodHandles.Lookup lookup = MethodHandles.lookup();
    if (charsField != null) {
      try {
        CHARS_FIELD_GET = lookup.unreflectGetter(charsField);
      } catch (IllegalAccessException ex) {
        throw new ExceptionInInitializerError(ex);
      }
    } else {
      CHARS_FIELD_GET = null;
    }

    // up until u45 String(int offset, int count, char value[]) {
    // u45 reverted to: String(char[] value, boolean share) {
    Constructor<String> prConstr =
        AccessController.doPrivileged(
            new PrivilegedAction<Constructor<String>>() {
              @Override
              public Constructor<String> run() {
                Constructor<String> constr;
                try {
                  constr = String.class.getDeclaredConstructor(char[].class, boolean.class);
                  constr.setAccessible(true);
                } catch (NoSuchMethodException ex) {
                  try {
                    constr =
                        String.class.getDeclaredConstructor(int.class, int.class, char[].class);
                    constr.setAccessible(true);
                  } catch (NoSuchMethodException ex2) {
                    ex2.addSuppressed(ex);
                    LOG.info("building String from char[] fast not supported", ex2);
                    constr = null;
                  } catch (SecurityException ex2) {
                    ex2.addSuppressed(ex);
                    throw new RuntimeException(ex2);
                  }
                } catch (SecurityException ex) {
                  throw new RuntimeException(ex);
                }
                return constr;
              }
            });

    if (prConstr == null) {
      PROTECTED_STR_CONSTR_PARAM_TYPES = null;
      PROTECTED_STR_CONSTR_HANDLE = null;
    } else {
      PROTECTED_STR_CONSTR_PARAM_TYPES = prConstr.getParameterTypes();
      try {
        PROTECTED_STR_CONSTR_HANDLE = lookup.unreflectConstructor(prConstr);
      } catch (IllegalAccessException ex) {
        throw new ExceptionInInitializerError(ex);
      }
    }
  }