从这里,我们就能看出,实际上 toString() 调用的是 java.lang.runtime.ObjectMethods
的 bootstap()
方法。其核心代码是: ObjectMethods.java
public static Object bootstrap(MethodHandles.Lookup lookup, String methodName, TypeDescriptor type, Class<?> recordClass, String names, MethodHandle... getters) throws Throwable { MethodType methodType; if (type instanceof MethodType) methodType = (MethodType) type; else { methodType = null; if (!MethodHandle.class.equals(type)) throw new IllegalArgumentException(type.toString()); } List<MethodHandle> getterList = List.of(getters); MethodHandle handle; //根据 method 名称,处理对应的逻辑,分别对应了 equals(),hashCode(),toString() 的实现 switch (methodName) { case "equals": if (methodType != null && !methodType.equals(MethodType.methodType(boolean.class, recordClass, Object.class))) throw new IllegalArgumentException("Bad method type: " + methodType); handle = makeEquals(recordClass, getterList); return methodType != null ? new ConstantCallSite(handle) : handle; case "hashCode": if (methodType != null && !methodType.equals(MethodType.methodType(int.class, recordClass))) throw new IllegalArgumentException("Bad method type: " + methodType); handle = makeHashCode(recordClass, getterList); return methodType != null ? new ConstantCallSite(handle) : handle; case "toString": if (methodType != null && !methodType.equals(MethodType.methodType(String.class, recordClass))) throw new IllegalArgumentException("Bad method type: " + methodType); List<String> nameList = "".equals(names) ? List.of() : List.of(names.split(";")); if (nameList.size() != getterList.size()) throw new IllegalArgumentException("Name list and accessor list do not match"); handle = makeToString(recordClass, getterList, nameList); return methodType != null ? new ConstantCallSite(handle) : handle; default: throw new IllegalArgumentException(methodName); } }
其中,toString() 方法 的核心实现逻辑,就要看case "toString"
这一分支了,核心逻辑是makeToString(recordClass, getterList, nameList)
:
private static MethodHandle makeToString(Class<?> receiverClass, //所有的 getter 方法 List<MethodHandle> getters, //所有的 field 名称 List<String> names) { assert getters.size() == names.size(); int[] invArgs = new int[getters.size()]; Arrays.fill(invArgs, 0); MethodHandle[] filters = new MethodHandle[getters.size()]; StringBuilder sb = new StringBuilder(); //先拼接类名称[ sb.append(receiverClass.getSimpleName()).append("["); for (int i=0; i<getters.size(); i++) { MethodHandle getter = getters.get(i); // (R)T MethodHandle stringify = stringifier(getter.type().returnType()); // (T)String MethodHandle stringifyThisField = MethodHandles.filterArguments(stringify, 0, getter); // (R)String filters[i] = stringifyThisField; //之后拼接 field 名称=值 sb.append(names.get(i)).append("=%s"); if (i != getters.size() - 1) sb.append(", "); } sb.append(']'); String formatString = sb.toString(); MethodHandle formatter = MethodHandles.insertArguments(STRING_FORMAT, 0, formatString) .asCollector(String[].class, getters.size()); // (R*)String if (getters.size() == 0) { // Add back extra R formatter = MethodHandles.dropArguments(formatter, 0, receiverClass); } else { MethodHandle filtered = MethodHandles.filterArguments(formatter, 0, filters); formatter = MethodHandles.permuteArguments(filtered, MethodType.methodType(String.class, receiverClass), invArgs); } return formatter; }
同理,hashcode()
实现是:
private static MethodHandle makeHashCode(Class<?> receiverClass, List<MethodHandle> getters) { MethodHandle accumulator = MethodHandles.dropArguments(ZERO, 0, receiverClass); // (R)I // 对于每一个 field,找到对应的 hashcode 方法,取 哈希值,最后组合在一起 for (MethodHandle getter : getters) { MethodHandle hasher = hasher(getter.type().returnType()); // (T)I MethodHandle hashThisField = MethodHandles.filterArguments(hasher, 0, getter); // (R)I MethodHandle combineHashes = MethodHandles.filterArguments(HASH_COMBINER, 0, accumulator, hashThisField); // (RR)I accumulator = MethodHandles.permuteArguments(combineHashes, accumulator.type(), 0, 0); // adapt (R)I to (RR)I } return accumulator; }
同理,equals()
实现是:
private static MethodHandle makeEquals(Class<?> receiverClass, List<MethodHandle> getters) { MethodType rr = MethodType.methodType(boolean.class, receiverClass, receiverClass); MethodType ro = MethodType.methodType(boolean.class, receiverClass, Object.class); MethodHandle instanceFalse = MethodHandles.dropArguments(FALSE, 0, receiverClass, Object.class); // (RO)Z MethodHandle instanceTrue = MethodHandles.dropArguments(TRUE, 0, receiverClass, Object.class); // (RO)Z MethodHandle isSameObject = OBJECT_EQ.asType(ro); // (RO)Z MethodHandle isInstance = MethodHandles.dropArguments(CLASS_IS_INSTANCE.bindTo(receiverClass), 0, receiverClass); // (RO)Z MethodHandle accumulator = MethodHandles.dropArguments(TRUE, 0, receiverClass, receiverClass); // (RR)Z //对比两个对象的每个 field 的 getter 获取的值是否一样,对于引用类型通过 Objects.equals 方法,对于原始类型直接通过 == for (MethodHandle getter : getters) { MethodHandle equalator = equalator(getter.type().returnType()); // (TT)Z MethodHandle thisFieldEqual = MethodHandles.filterArguments(equalator, 0, getter, getter); // (RR)Z accumulator = MethodHandles.guardWithTest(thisFieldEqual, accumulator, instanceFalse.asType(rr)); } return MethodHandles.guardWithTest(isSameObject, instanceTrue, MethodHandles.guardWithTest(isInstance, accumulator.asType(ro), instanceFalse)); }