/** * Returns the default value for the annotation member represented by this {@code Method} * instance. If the member is of a primitive type, an instance of the corresponding wrapper type * is returned. Returns null if no default is associated with the member, or if the method * instance does not represent a declared member of an annotation type. * * @return the default value for the annotation member represented by this {@code Method} * instance. * @throws TypeNotPresentException if the annotation is of type {@link Class} and no definition * can be found for the default class value. * @since 1.5 */ public Object getDefaultValue() { if (annotationDefault == null) return null; Class<?> memberType = AnnotationType.invocationHandlerReturnType(getReturnType()); Object result = AnnotationParser.parseMemberValue( memberType, ByteBuffer.wrap(annotationDefault), sun.misc.SharedSecrets.getJavaLangAccess().getConstantPool(getDeclaringClass()), getDeclaringClass()); if (result instanceof sun.reflect.annotation.ExceptionProxy) throw new AnnotationFormatError("Invalid default: " + this); return result; }
/** * Read the method table * * @param data * @param rejectNatives * @param cls * @param cp * @param statics * @param cl */ private static void readMethods( ByteBuffer data, boolean rejectNatives, VmType cls, VmCP cp, VmStatics statics, VmClassLoader cl) { final int mcount = data.getChar(); if (mcount > 0) { final VmMethod[] mtable = new VmMethod[mcount]; for (int i = 0; i < mcount; i++) { final int modifiers = data.getChar(); final String name = cp.getUTF8(data.getChar()); final String signature = cp.getUTF8(data.getChar()); final boolean isStatic = ((modifiers & Modifier.ACC_STATIC) != 0); final VmMethod mts; final boolean isSpecial = name.equals("<init>"); // final int staticsIdx = statics.allocMethod(); if (isStatic || isSpecial) { if (isSpecial) { mts = new VmSpecialMethod(name, signature, modifiers, cls); } else { mts = new VmStaticMethod(name, signature, modifiers, cls); } } else { mts = new VmInstanceMethod(name, signature, modifiers, cls); } // statics.setMethod(staticsIdx, mts); mtable[i] = mts; // Read methods attributes final int acount = data.getChar(); VmAnnotation[] rVisAnn = null; VmAnnotation[] rInvisAnn = null; for (int a = 0; a < acount; a++) { String attrName = cp.getUTF8(data.getChar()); int length = data.getInt(); if (VmArray.equals(CodeAttrName, attrName)) { mts.setBytecode(readCode(data, cls, cp, mts)); } else if (VmArray.equals(ExceptionsAttrName, attrName)) { mts.setExceptions(readExceptions(data, cls, cp)); } else if (VmArray.equals(RuntimeVisibleAnnotationsAttrName, attrName)) { byte[] buf = new byte[length]; data.slice().get(buf); mts.setRawAnnotations(buf); // todo will get obsolate with openjdk based annotation support // rVisAnn = readRuntimeAnnotations(data, cp, true, cl); rVisAnn = readRuntimeAnnotations2(data, cp, true, cl, cls); } else if (VmArray.equals(RuntimeInvisibleAnnotationsAttrName, attrName)) { rInvisAnn = readRuntimeAnnotations(data, cp, false, cl); } else if (VmArray.equals(RuntimeVisibleParameterAnnotationsAttrName, attrName)) { byte[] buf = new byte[length]; data.slice().get(buf); mts.setRawParameterAnnotations(buf); // todo will get obsolate with openjdk based annotation support readRuntimeParameterAnnotations(data, cp, true, cl); } else if (VmArray.equals(RuntimeInvisibleParameterAnnotationsAttrName, attrName)) { readRuntimeParameterAnnotations(data, cp, false, cl); } else if (VmArray.equals(AnnotationDefaultAttrName, attrName)) { // todo will get obsolate with openjdk based annotation support byte[] buf = new byte[length]; data.slice().get(buf); mts.setRawAnnotationDefault(buf); Class r_class; VmType vtm = mts.getReturnType(); if (vtm.isPrimitive()) { r_class = getClassForJvmType(vtm.getJvmType()); } else { try { r_class = Class.forName(vtm.getName(), false, vtm.getLoader().asClassLoader()); } catch (ClassNotFoundException cnf) { throw new RuntimeException(cnf); } } Object defo = AnnotationParser.parseMemberValue( r_class, data, new VmConstantPool(cls), VmUtils.isRunningVm() ? cls.asClass() : cls.asClassDuringBootstrap()); mts.setAnnotationDefault(defo); } else { skip(data, length); } } mts.setRuntimeAnnotations(rVisAnn); if (rVisAnn != null) { mts.addPragmaFlags(getMethodPragmaFlags(rVisAnn, cls.getName())); } if (rInvisAnn != null) { mts.addPragmaFlags(getMethodPragmaFlags(rInvisAnn, cls.getName())); } if ((modifiers & Modifier.ACC_NATIVE) != 0) { final VmByteCode bc = getNativeCodeReplacement(mts, cl, rejectNatives); if (bc != null) { mts.setModifier(false, Modifier.ACC_NATIVE); mts.setBytecode(bc); } else { if (rejectNatives) { throw new ClassFormatError("Native method " + mts); } } } } cls.setMethodTable(mtable); } }
/** * Read a single annotation structure. * * @param data * @param cp */ private static VmAnnotation readAnnotation2( ByteBuffer data, VmCP cp, boolean visible, VmClassLoader loader, VmType vmType) { final String typeDescr = cp.getUTF8(data.getChar()); final int numElemValuePairs = data.getChar(); final VmAnnotation.ElementValue[] values; if (numElemValuePairs == 0) { values = VmAnnotation.ElementValue.EMPTY_ARR; } else if (visible) { values = new VmAnnotation.ElementValue[numElemValuePairs]; for (int i = 0; i < numElemValuePairs; i++) { final String elemName = cp.getUTF8(data.getChar()); Object defo = null; // readElementValue(data, cp); try { VmType annType = new Signature(typeDescr, loader).getType(); VmMethod mts = null; int dmc = annType.getNoDeclaredMethods(); for (int v = 0; v < dmc; v++) { VmMethod m = annType.getDeclaredMethod(v); if (elemName.equals(m.getName())) { mts = m; break; } } Class r_class; VmType vtm = mts.getReturnType(); if (vtm.isPrimitive()) { r_class = getClassForJvmType(vtm.getJvmType()); } else { try { r_class = vtm.getLoader().asClassLoader().loadClass(vtm.getName()); } catch (ClassNotFoundException cnf) { throw new RuntimeException(cnf); } } Class container; try { container = annType.getLoader().asClassLoader().loadClass(annType.getName()); } catch (ClassNotFoundException cnf) { throw new RuntimeException(cnf); } defo = AnnotationParser.parseMemberValue( r_class, data, new VmConstantPool(vmType), container); if (defo instanceof ExceptionProxy) throw new RuntimeException( "Error parsing annotation parameter value (annotation= " + annType.getName() + ", parameter=" + mts.getName() + ')'); } catch (Exception e) { throw new RuntimeException(e); } final Object value = defo; // readElementValue(data, cp); values[i] = new VmAnnotation.ElementValue(elemName, value); } } else { values = VmAnnotation.ElementValue.EMPTY_ARR; for (int i = 0; i < numElemValuePairs; i++) { data.getChar(); // Skip name ref skipElementValue(data, cp); } } return new VmAnnotation(typeDescr, values); }