📄 ctfield.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.SymbolTable;import javassist.compiler.CompileError;import javassist.compiler.ast.ASTree;import javassist.compiler.ast.IntConst;import javassist.compiler.ast.DoubleConst;import javassist.compiler.ast.StringL;/** * An instance of CtField represents a field. * * @see CtClass#getDeclaredFields() */public class CtField extends CtMember { static final String javaLangString = "java.lang.String"; protected FieldInfo fieldInfo; /** * Creates a <code>CtField</code> object. * The created field must be added to a class * with <code>CtClass.addField()</code>. * An initial value of the field is specified * by a <code>CtField.Initializer</code> object. * * <p>If getter and setter methods are needed, * call <code>CtNewMethod.getter()</code> and * <code>CtNewMethod.setter()</code>. * * @param type field type * @param name field name * @param declaring the class to which the field will be added. * * @see CtClass#addField(CtField) * @see CtNewMethod#getter(String,CtField) * @see CtNewMethod#setter(String,CtField) * @see CtField.Initializer */ public CtField(CtClass type, String name, CtClass declaring) throws CannotCompileException { this(Descriptor.of(type), name, declaring); } /** * Creates a copy of the given field. * The created field must be added to a class * with <code>CtClass.addField()</code>. * An initial value of the field is specified * by a <code>CtField.Initializer</code> object. * * <p>If getter and setter methods are needed, * call <code>CtNewMethod.getter()</code> and * <code>CtNewMethod.setter()</code>. * * @param src the original field * @param declaring the class to which the field will be added. * @see CtNewMethod#getter(String,CtField) * @see CtNewMethod#setter(String,CtField) * @see CtField.Initializer */ public CtField(CtField src, CtClass declaring) throws CannotCompileException { this(src.fieldInfo.getDescriptor(), src.fieldInfo.getName(), declaring); java.util.ListIterator iterator = src.fieldInfo.getAttributes().listIterator(); FieldInfo fi = fieldInfo; fi.setAccessFlags(src.fieldInfo.getAccessFlags()); ConstPool cp = fi.getConstPool(); while (iterator.hasNext()) { AttributeInfo ainfo = (AttributeInfo)iterator.next(); fi.addAttribute(ainfo.copy(cp, null)); } } private CtField(String typeDesc, String name, CtClass clazz) throws CannotCompileException { super(clazz); next = null; ClassFile cf = clazz.getClassFile2(); if (cf == null) throw new CannotCompileException("bad declaring class: " + clazz.getName()); fieldInfo = new FieldInfo(cf.getConstPool(), name, typeDesc); } CtField(FieldInfo fi, CtClass clazz) { super(clazz); fieldInfo = fi; next = null; } /** * Returns a String representation of the object. */ public String toString() { return getDeclaringClass().getName() + "." + getName() + ":" + fieldInfo.getDescriptor(); } protected void extendToString(StringBuffer buffer) { buffer.append(' '); buffer.append(getName()); buffer.append(' '); buffer.append(fieldInfo.getDescriptor()); } /* Javac.CtFieldWithInit overrides. */ protected ASTree getInitAST() { return null; } /* Called by CtClassType.addField(). */ Initializer getInit() { ASTree tree = getInitAST(); if (tree == null) return null; else return Initializer.byExpr(tree); } /** * Compiles the given source code and creates a field. * Examples of the source code are: * * <ul><pre> * "public String name;" * "public int k = 3;"</pre></ul> * * <p>Note that the source code ends with <code>';'</code> * (semicolon). * * @param src the source text. * @param declaring the class to which the created field is added. */ public static CtField make(String src, CtClass declaring) throws CannotCompileException { Javac compiler = new Javac(declaring); try { CtMember obj = compiler.compile(src); if (obj instanceof CtField) return (CtField)obj; // an instance of Javac.CtFieldWithInit } catch (CompileError e) { throw new CannotCompileException(e); } throw new CannotCompileException("not a field"); } /** * Returns the FieldInfo representing the field in the class file. */ public FieldInfo getFieldInfo() { declaringClass.checkModify(); return fieldInfo; } /** * Returns the FieldInfo representing the field in the class * file (read only). * Normal applications do not need calling this method. Use * <code>getFieldInfo()</code>. * * <p>The <code>FieldInfo</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 field is frozen. However, if the class is * frozen, the <code>FieldInfo</code> might be also pruned. * * @see #getFieldInfo() * @see CtClass#isFrozen() * @see CtClass#prune() */ public FieldInfo getFieldInfo2() { return fieldInfo; } /** * Returns the class declaring the field. */ public CtClass getDeclaringClass() { // this is redundant but for javadoc. return super.getDeclaringClass(); } /** * Returns the name of the field. */ public String getName() { return fieldInfo.getName(); } /** * Changes the name of the field. */ public void setName(String newName) { declaringClass.checkModify(); fieldInfo.setName(newName); } /** * Returns the encoded modifiers of the field. * * @see Modifier */ public int getModifiers() { return AccessFlag.toModifier(fieldInfo.getAccessFlags()); } /** * Sets the encoded modifiers of the field. * * @see Modifier */ public void setModifiers(int mod) { declaringClass.checkModify(); fieldInfo.setAccessFlags(AccessFlag.of(mod)); } /** * Returns the annotations associated with this field. * * @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 field. * 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 { FieldInfo fi = getFieldInfo2(); AnnotationsAttribute ainfo = (AnnotationsAttribute) fi.getAttribute(AnnotationsAttribute.invisibleTag); AnnotationsAttribute ainfo2 = (AnnotationsAttribute) fi.getAttribute(AnnotationsAttribute.visibleTag); return CtClassType.toAnnotationType(ignoreNotFound, getDeclaringClass().getClassPool(), ainfo, ainfo2); } /** * Returns the character string representing the type of the field. * If two fields have the same type, * <code>getSignature()</code> returns the same string. */ public String getSignature() { return fieldInfo.getDescriptor(); } /** * Returns the type of the field. */ public CtClass getType() throws NotFoundException { return Descriptor.toCtClass(fieldInfo.getDescriptor(), declaringClass.getClassPool()); } /** * Sets the type of the field. */ public void setType(CtClass clazz) { declaringClass.checkModify(); fieldInfo.setDescriptor(Descriptor.of(clazz)); } /** * Returns the value of this field if it is a constant field. * This method works only if the field type is a primitive type * or <code>String</code> type. Otherwise, it returns <code>null</code>. * A constant field is <code>static</code> and <code>final</code>. * * @return a <code>Integer</code>, <code>Long</code>, <code>Float</code>, * <code>Double</code>, <code>Boolean</code>, * or <code>String</code> object * representing the constant value. * <code>null</code> if it is not a constant field * or if the field type is not a primitive type * or <code>String</code>. */ public Object getConstantValue() { // When this method is modified, // see also getConstantFieldValue() in TypeChecker. int index = fieldInfo.getConstantValue(); if (index == 0) return null; ConstPool cp = fieldInfo.getConstPool(); switch (cp.getTag(index)) { case ConstPool.CONST_Long : return new Long(cp.getLongInfo(index)); case ConstPool.CONST_Float : return new Float(cp.getFloatInfo(index)); case ConstPool.CONST_Double : return new Double(cp.getDoubleInfo(index)); case ConstPool.CONST_Integer : int value = cp.getIntegerInfo(index); // "Z" means boolean type. if ("Z".equals(fieldInfo.getDescriptor())) return new Boolean(value != 0); else return new Integer(value); case ConstPool.CONST_String : return cp.getStringInfo(index); default : throw new RuntimeException("bad tag: " + cp.getTag(index) + " at " + index); } } /** * Obtains an attribute with the given name. * If that attribute is not found in the class file, this * method returns null. * * <p>Note that an attribute is a data block specified by * the class file format. * See {@link javassist.bytecode.AttributeInfo}. * * @param name attribute name */ public byte[] getAttribute(String name) { AttributeInfo ai = fieldInfo.getAttribute(name); if (ai == null) return null; else return ai.get(); } /** * Adds an attribute. The attribute is saved in the class file. * * <p>Note that an attribute is a data block specified by * the class file format. * See {@link javassist.bytecode.AttributeInfo}. * * @param name attribute name * @param data attribute value */ public void setAttribute(String name, byte[] data) { declaringClass.checkModify(); fieldInfo.addAttribute(new AttributeInfo(fieldInfo.getConstPool(), name, data)); } // inner classes /** * Instances of this class specify how to initialize a field. * <code>Initializer</code> is passed to * <code>CtClass.addField()</code> with a <code>CtField</code>. * * <p>This class cannot be instantiated with the <code>new</code> operator. * Factory methods such as <code>byParameter()</code> and * <code>byNew</code> * must be used for the instantiation. They create a new instance with * the given parameters and return it. * * @see CtClass#addField(CtField,CtField.Initializer) */ public static abstract class Initializer { /** * Makes an initializer that assigns a constant integer value. * The field must be integer type. */ public static Initializer constant(int i) { return new IntInitializer(i); } /** * Makes an initializer that assigns a constant long value. * The field must be long type. */ public static Initializer constant(long l) { return new LongInitializer(l); } /** * Makes an initializer that assigns a constant double value. * The field must be double type. */ public static Initializer constant(double d) { return new DoubleInitializer(d); } /** * Makes an initializer that assigns a constant string value. * The field must be <code>java.lang.String</code> type. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -