📄 ctbehavior.java
字号:
/* * Javassist, a Java-bytecode translator toolkit. * Copyright (C) 1999-2006 Shigeru Chiba. All Rights Reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. Alternatively, the contents of this file may be used under * the terms of the GNU Lesser General Public License Version 2.1 or later. * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. */package javassist;import javassist.bytecode.*;import javassist.compiler.Javac;import javassist.compiler.CompileError;import javassist.expr.ExprEditor;/** * <code>CtBehavior</code> represents a method, a constructor, * or a static constructor (class initializer). * It is the abstract super class of * <code>CtMethod</code> and <code>CtConstructor</code>. */public abstract class CtBehavior extends CtMember { protected MethodInfo methodInfo; protected CtBehavior(CtClass clazz, MethodInfo minfo) { super(clazz); methodInfo = minfo; } /** * @param isCons true if this is a constructor. */ void copy(CtBehavior src, boolean isCons, ClassMap map) throws CannotCompileException { CtClass declaring = declaringClass; MethodInfo srcInfo = src.methodInfo; CtClass srcClass = src.getDeclaringClass(); ConstPool cp = declaring.getClassFile2().getConstPool(); map = new ClassMap(map); map.put(srcClass.getName(), declaring.getName()); try { boolean patch = false; CtClass srcSuper = srcClass.getSuperclass(); CtClass destSuper = declaring.getSuperclass(); String destSuperName = null; if (srcSuper != null && destSuper != null) { String srcSuperName = srcSuper.getName(); destSuperName = destSuper.getName(); if (!srcSuperName.equals(destSuperName)) if (srcSuperName.equals(CtClass.javaLangObject)) patch = true; else map.put(srcSuperName, destSuperName); } methodInfo = new MethodInfo(cp, srcInfo.getName(), srcInfo, map); if (isCons && patch) methodInfo.setSuperclass(destSuperName); } catch (NotFoundException e) { throw new CannotCompileException(e); } catch (BadBytecode e) { throw new CannotCompileException(e); } } protected void extendToString(StringBuffer buffer) { buffer.append(' '); buffer.append(getName()); buffer.append(' '); buffer.append(methodInfo.getDescriptor()); } /** * Returns the MethodInfo representing this method/constructor in the * class file. */ public MethodInfo getMethodInfo() { declaringClass.checkModify(); return methodInfo; } /** * Returns the MethodInfo representing the method/constructor in the * class file (read only). * Normal applications do not need calling this method. Use * <code>getMethodInfo()</code>. * * <p>The <code>MethodInfo</code> object obtained by this method * is read only. Changes to this object might not be reflected * on a class file generated by <code>toBytecode()</code>, * <code>toClass()</code>, etc in <code>CtClass</code>. * * <p>This method is available even if the <code>CtClass</code> * containing this method is frozen. However, if the class is * frozen, the <code>MethodInfo</code> might be also pruned. * * @see #getMethodInfo() * @see CtClass#isFrozen() * @see CtClass#prune() */ public MethodInfo getMethodInfo2() { return methodInfo; } /** * Obtains the modifiers of the method/constructor. * * @return modifiers encoded with * <code>javassist.Modifier</code>. * @see Modifier */ public int getModifiers() { return AccessFlag.toModifier(methodInfo.getAccessFlags()); } /** * Sets the encoded modifiers of the method/constructor. * * <p>Changing the modifiers may cause a problem. * For example, if a non-static method is changed to static, * the method will be rejected by the bytecode verifier. * * @see Modifier */ public void setModifiers(int mod) { declaringClass.checkModify(); methodInfo.setAccessFlags(AccessFlag.of(mod)); } /** * Returns the annotations associated with this method or constructor. * * @return an array of annotation-type objects. * @see #getAvailableAnnotations() * @since 3.1 */ public Object[] getAnnotations() throws ClassNotFoundException { return getAnnotations(false); } /** * Returns the annotations associated with this method or constructor. * If any annotations are not on the classpath, they are not included * in the returned array. * * @return an array of annotation-type objects. * @see #getAnnotations() * @since 3.3 */ public Object[] getAvailableAnnotations(){ try{ return getAnnotations(true); } catch (ClassNotFoundException e){ throw new RuntimeException("Unexpected exception", e); } } private Object[] getAnnotations(boolean ignoreNotFound) throws ClassNotFoundException { MethodInfo mi = getMethodInfo2(); AnnotationsAttribute ainfo = (AnnotationsAttribute) mi.getAttribute(AnnotationsAttribute.invisibleTag); AnnotationsAttribute ainfo2 = (AnnotationsAttribute) mi.getAttribute(AnnotationsAttribute.visibleTag); return CtClassType.toAnnotationType(ignoreNotFound, getDeclaringClass().getClassPool(), ainfo, ainfo2); } /** * Returns the parameter annotations associated with this method or constructor. * * @return an array of annotation-type objects. The length of the returned array is * equal to the number of the formal parameters. If each parameter has no * annotation, the elements of the returned array are empty arrays. * * @see #getAvailableParameterAnnotations() * @see #getAnnotations() * @since 3.1 */ public Object[][] getParameterAnnotations() throws ClassNotFoundException { return getParameterAnnotations(false); } /** * Returns the parameter annotations associated with this method or constructor. * If any annotations are not on the classpath, they are not included in the * returned array. * * @return an array of annotation-type objects. The length of the returned array is * equal to the number of the formal parameters. If each parameter has no * annotation, the elements of the returned array are empty arrays. * * @see #getParameterAnnotations() * @see #getAvailableAnnotations() * @since 3.3 */ public Object[][] getAvailableParameterAnnotations(){ try { return getParameterAnnotations(true); } catch(ClassNotFoundException e) { throw new RuntimeException("Unexpected exception", e); } } Object[][] getParameterAnnotations(boolean ignoreNotFound) throws ClassNotFoundException { MethodInfo mi = getMethodInfo2(); ParameterAnnotationsAttribute ainfo = (ParameterAnnotationsAttribute) mi.getAttribute(ParameterAnnotationsAttribute.invisibleTag); ParameterAnnotationsAttribute ainfo2 = (ParameterAnnotationsAttribute) mi.getAttribute(ParameterAnnotationsAttribute.visibleTag); return CtClassType.toAnnotationType(ignoreNotFound, getDeclaringClass().getClassPool(), ainfo, ainfo2, mi); } /** * Obtains parameter types of this method/constructor. */ public CtClass[] getParameterTypes() throws NotFoundException { return Descriptor.getParameterTypes(methodInfo.getDescriptor(), declaringClass.getClassPool()); } /** * Obtains the type of the returned value. */ CtClass getReturnType0() throws NotFoundException { return Descriptor.getReturnType(methodInfo.getDescriptor(), declaringClass.getClassPool()); } /** * Returns the method signature (the parameter types * and the return type). * The method signature is represented by a character string * called method descriptor, which is defined in the JVM specification. * If two methods/constructors have * the same parameter types * and the return type, <code>getSignature()</code> returns the * same string (the return type of constructors is <code>void</code>). * * @see javassist.bytecode.Descriptor */ public String getSignature() { return methodInfo.getDescriptor(); } /** * Obtains exceptions that this method/constructor may throw. * * @return a zero-length array if there is no throws clause. */ public CtClass[] getExceptionTypes() throws NotFoundException { String[] exceptions; ExceptionsAttribute ea = methodInfo.getExceptionsAttribute(); if (ea == null) exceptions = null; else exceptions = ea.getExceptions(); return declaringClass.getClassPool().get(exceptions); } /** * Sets exceptions that this method/constructor may throw. */ public void setExceptionTypes(CtClass[] types) throws NotFoundException { declaringClass.checkModify(); if (types == null || types.length == 0) { methodInfo.removeExceptionsAttribute(); return; } String[] names = new String[types.length]; for (int i = 0; i < types.length; ++i) names[i] = types[i].getName(); ExceptionsAttribute ea = methodInfo.getExceptionsAttribute(); if (ea == null) { ea = new ExceptionsAttribute(methodInfo.getConstPool()); methodInfo.setExceptionsAttribute(ea); } ea.setExceptions(names); } /** * Returns true if the body is empty. */ public abstract boolean isEmpty(); /** * Sets a method/constructor body. * * @param src the source code representing the body. * It must be a single statement or block. * If it is <code>null</code>, the substituted * body does nothing except returning zero or null. */ public void setBody(String src) throws CannotCompileException { setBody(src, null, null); } /** * Sets a method/constructor body. * * @param src the source code representing the body. * It must be a single statement or block. * If it is <code>null</code>, the substituted * body does nothing except returning zero or null. * @param delegateObj the source text specifying the object * that is called on by <code>$proceed()</code>. * @param delegateMethod the name of the method * that is called by <code>$proceed()</code>. */ public void setBody(String src, String delegateObj, String delegateMethod)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -