WEB开发网
开发学院软件开发Java Classworking 工具箱: 分析泛型数据结构 阅读

Classworking 工具箱: 分析泛型数据结构

 2010-03-18 00:00:00 来源:WEB开发网   
核心提示: TypeDescription 类只是个抽象基类,其中定义了处理三种类型的方法:原生类型、数组和类实例,Classworking 工具箱: 分析泛型数据结构(3),这个基类以类型描述符的形式包含了一个值,我用于这个类的类型描述符大致符合 JVM 规范定义的类型描述符的形式,并立即把描述添加到目录

TypeDescription 类只是个抽象基类,其中定义了处理三种类型的方法:原生类型、数组和类实例。这个基类以类型描述符的形式包含了一个值。我用于这个类的类型描述符大致符合 JVM 规范定义的类型描述符的形式,但是有些扩展,添加了泛型具体 “版本” 的实际参数类型列表。这个扩展允许把 Ljava/util/Map<Ljava/lang/String;Ljava/lang/String;>; 这种形式的描述符作为类型系统的一部分。

组织数据结构

组织数据结构信息的问题比表示信息的问题略微复杂一些。组织信息的基本问题在于数据结构经常是递归的:一个类中可能有一个字段,这个字段引用这个类的一个实例,或者它引用的一个类可能直接或间接地引用回到原来的类。所以,只想直接展开结构,可能会形成无限的递归循环。

我使用目录技术来处理这种递归引用。在找到类引用时,检查目标,查看这个类以前是否已经看到过。如果是,那么目录就返回现有的描述。如果没有,则目录创建新的描述实例,并立即把描述添加到目录(甚至在描述的完整细节可用之前就添加)。清单 2 显示了这个 TypeDirectory 类的基本代码,现在暂时不管它,以后会添加处理泛型的一些细节:

清单 2. TypeDirectory 类

public class TypeDirectory 
{ 
  /** Source for binary class representations. */ 
  private final BinaryClassLoader m_loader; 
   
  /** Field list for all arrays. */ 
  private final FieldDescription[] m_arrayFields; 
   
  /** Map from descriptor or signature to type for all non-generic types, 
   * including generics with substitutions. */ 
  private HashMap<String,TypeDescription> m_typeMap = 
    new HashMap<String,TypeDescription>(); 
  ... 
   
  /** 
   * Constructor. Initializes the type directory with descriptions of 
   * primitive types. 
   * 
   * @param loader binary class loader 
   */ 
  public TypeDirectory(BinaryClassLoader loader) { 
    m_loader = loader; 
    addType(new PrimitiveTypeDescription("B", "byte")); 
    addType(new PrimitiveTypeDescription("C", "char")); 
    addType(new PrimitiveTypeDescription("D", "double")); 
    addType(new PrimitiveTypeDescription("F", "float")); 
    TypeDescription inttype = new PrimitiveTypeDescription("I", "int"); 
    addType(inttype); 
    addType(new PrimitiveTypeDescription("J", "long")); 
    addType(new PrimitiveTypeDescription("S", "short")); 
    addType(new PrimitiveTypeDescription("V", "void")); 
    addType(new PrimitiveTypeDescription("Z", "boolean")); 
    m_arrayFields = new FieldDescription[] { 
      new FieldDescription("int", null, inttype) 
    }; 
  } 
   
  /** 
   * Add type description to type directory. 
   * 
   * @param desc type description to add 
   */ 
  public void addType(TypeDescription desc) { 
    m_typeMap.put(desc.getDescriptor(), desc); 
  } 
   
  /** 
   * Add generic class to template directory. 
   * 
   * @param tmpl generic template to add 
   */ 
  public void addTemplate(GenericTemplate tmpl) { 
    m_templateMap.put(tmpl.getDescriptor(), tmpl); 
  } 
   
  /** 
   * Get description for the type. The type may be a primitive, an array, or a 
   * class. If the type is a generic class, it will be treated as though all 
   * type variables used their lower bounds. 
   * 
   * @param dtor type descriptor 
   * @return type description 
   */ 
  public TypeDescription getTypeInstance(String dtor) { 
     
    // check for an existing description 
    TypeDescription desc = m_typeMap.get(dtor); 
    if (desc == null) { 
       
      // new description needed - must be array or class 
      if (dtor.charAt(0) == '[') { 
        desc = new ArrayClassDescriptor(dtor, 
          getTypeInstance(dtor.substring(1))); 
      } else { 
         
        // parse binary class to build description 
        byte[] byts = m_loader.getBytes(dtor); 
        desc = new SimpleClassDescription(dtor, byts, this); 
      } 
    } 
    return desc; 
  } 
   
  /** 
   * Get description for generic class with specific type substitutions. 
   * 
   * @param sig field signature with type substitutions 
   * @param types actual types used for instance (values may be 
   * <code>null</code> if no substitution defined) 
   * @return type description 
   */ 
  public TypeDescription getSignatureInstance(String sig, 
    TypeDescription[] types) { 
     
    // first check for direct match on substituted signature 
    TypeDescription desc = (TypeDescription)m_typeMap.get(sig); 
    if (desc == null) { 
       
      // no direct match, first handle array 
      if (sig.charAt(0) == '[') { 
        desc = new ArrayClassDescriptor(sig, 
          getSignatureInstance(sig.substring(1), types)); 
      } else { 
         
        ... 
      } 
    } 
    return desc; 
  } 
   
  /** 
   * Get description for signature with type mapping. 
   * 
   * @param sig field signature for type variables 
   * @param tmap type mapping for variables 
   * @return type description 
   */ 
  public TypeDescription getMappedSignatureInstance(String sig, 
    HashMap<String,TypeDescription> tmap) { 
    ... 
  } 
  ... 
   
  /** 
   * Descriptor for primitive "class." There's really nothing to record for a 
   * primitive type except the name, so that's all this does. Because instances 
   * only need to be created and added to the directory at initialization, this 
   * is an inner class. 
   */ 
  private static class PrimitiveTypeDescription extends TypeDescription 
  { 
    private final String m_externalName; 
     
    private PrimitiveTypeDescription(String iname, String xname) { 
      super(iname); 
      m_externalName = xname; 
    } 
     
    public boolean isPrimitive() { 
      return true; 
    } 
    public String toString() { 
      return m_externalName; 
    } 
  } 
   
  /** 
   * Descriptor for array class. This is just a wrapper around the descriptor 
   * for the item type, with the same field list used for all arrays. 
   */ 
  private class ArrayClassDescriptor extends TypeDescription 
  { 
    private final TypeDescription m_itemType; 
     
    protected ArrayClassDescriptor(String name, TypeDescription item) { 
      super(name); 
      m_itemType = item; 
    } 
     
    public boolean isArray() { 
      return true; 
    } 
    public TypeDescription getArrayItemType() { 
      return m_itemType; 
    } 
    public FieldDescription[] getFields() { 
      return m_arrayFields; 
    } 
    public String toString() { 
      return m_itemType + "[]"; 
    } 
  } 
} 

上一页  1 2 3 4 5 6 7 8  下一页

Tags:Classworking 工具箱 分析

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接