2010-01-05 52 views
3

有沒有通過標準庫或某些已經存在的庫來確定Java中兩個類/接口之間關係程度的方法?Java對象和類/接口之間的關係程度?

比方說,我有一個對象和類/接口的列表。現在我基本上想知道該列表的一個類,它具有到此對象的最短繼承樹路徑。

我已通過java.lang.reflect包和類別看,但不能真正找到任何可以方便獲取這樣的信息。這可能已經是另一個圖書館的一部分了?

回答

1

我不知道任何準備使用。

我會使用反射來發現的關係。

難的是最短路徑。

  • 你必須定義你想要什麼:

    • 例如,你先搜索接口的超?
    • 當幾個人擁有相同長度的路徑時,你會做出什麼決定?
      使用字母順序?
      使用發現順序(隨機)? ...
  • 然後,尋找這些類或接口的順序,從當前的類,那麼它的父類(以及可能實現的接口),等等...

+1

非常感謝您和提供的東西的清單,記住:-) – 2010-01-05 18:26:20

+0

@host最好的將是一個隨時可以使用的解決方案。但缺乏一個,我認爲這可能是有用的;-)很高興我們分享相同的觀點:-) – KLE 2010-01-07 07:54:08

1

this有點幫助。 不知道如何獲得最短路徑。

3

思考會讓你得到任何給定類的父類,這樣你就可以提取足夠的信息來建立自己的繼承樹,然後你就可以用它來回答你的問題。我想不出任何可以讓你更優雅的內置機制。

0

此代碼應該讓你關閉。正如其他人所說,你可能會遇到接口問題,儘管繼承深度可能很容易相同。您還需要添加一些空的檢查等。

在此示例中,FooBar3擴展FooBar2擴展FooBar。

public static void main(String[] args) { 
    List<Class<?>> l = new ArrayList<Class<?>>() {{ 
     add(FooBar2.class); 
     add(FooBar.class); 
    } }; 
    System.out.println(getClosestParent(new FooBar3(), l)); 
} 

public static Class getClosestParent(Object o, List<Class<?>> classes) { 
    List<Class<?>> related = getRelated(o, classes); 
    Collections.sort(related, new Comparator<Class<?>>() { 
     public int compare(Class<?> o1, Class<?> o2) { 
      if (o1.isAssignableFrom(o2)) { 
       return -1; 
      } else if (o2.isAssignableFrom(o1)) { 
       return 1; 
      } 
      return 0; 
     } 
    }); 
    return related.get(0); 
} 

public static List<Class<?>> getRelated(Object o, List<Class<?>> classes) { 
    List<Class<?>> filtered = new ArrayList<Class<?>>(); 
    for (Class<?> aClass : classes) { 
     if (aClass.isAssignableFrom(o.getClass())) { 
      filtered.add(aClass); 
     } 

    } 
    return filtered; 
} 
1

我不禁發現這是一個有趣的項目。這是原型代碼,可以爲您提供所需的信息。這段代碼只是試圖計算從給定類到另一個類的所有可能的繼承路徑。您可以使用它來獲取從源對象到您感興趣的所有可能類的所有路徑。正如其他評論中提到的,您可能需要打電話詢問您的偏好路徑是否使用接口,但希望這段代碼對你有幫助。

public class InheritenceDepth { 

/** 
* Obtains a list of all the possible inheritance paths from the given targetClass 
* to the specified potentialAncestorClass. If the targetClass does not extend or implement 
* the potentialAncestorClass the return list will be empty. 
*/ 
public static List<InheritancePath> classInheritancePaths(Class<?> targetClass, Class<?> potentialAncestorClass){ 
    List<InheritancePath> returnList = new ArrayList<InheritancePath>(); 
    if(potentialAncestorClass.isAssignableFrom(targetClass)){ 

     if(potentialAncestorClass.equals(targetClass)){ 
      returnList.add(new InheritancePath(potentialAncestorClass)); 
     } 

     if(targetClass.getSuperclass() != null){ 
      // try superclass 
      List<InheritancePath> pathsFromSuperClass = 
       classInheritancePaths(targetClass.getSuperclass(), potentialAncestorClass); 
      if(!pathsFromSuperClass.isEmpty()){ 
       for(InheritancePath path : pathsFromSuperClass){ 
        path.add(targetClass); 
        returnList.add(path); 
       } 
      } 
     } 

     // try interfaces 
     for(Class<?> interf : targetClass.getInterfaces()){ 
      List<InheritancePath> pathsFromInterface = 
       classInheritancePaths(interf, potentialAncestorClass); 
      if(!pathsFromInterface.isEmpty()){ 
       for(InheritancePath path : pathsFromInterface){ 
        path.add(targetClass); 
        returnList.add(path); 
       } 
      } 
     } 
    } 
    return returnList; 
} 

/** 
* Represents the path from a base class to a superclass 
*/ 
public static final class InheritancePath implements Iterable<Class<?>>{ 
    private List<Class<?>> path = new ArrayList<Class<?>>(); 
    public InheritancePath(Class<?> root){ 
     path.add(root); 
    } 

    void add(Class<?> pathElement){ 
     path.add(0, pathElement); 
    } 

    public Iterator<Class<?>> iterator(){ 
     return path.iterator(); 
    } 

    public int depth(){ 
     return path.size(); 
    } 

    public String toString(){ 
     StringBuilder sb = new StringBuilder(); 
     for(int i = 0; i < path.size(); i++){ 
      sb.append(path.get(i).getName()); 
      if(i < path.size() - 1){ 
       sb.append(" -> "); 
      } 
     } 
     return sb.toString(); 
    } 
} 

public static void main(String[] args) { 
    List<InheritancePath> paths = classInheritancePaths(ConcurrentLinkedQueue.class, Collection.class); 

    for(InheritancePath path : paths){ 
     System.out.println(path); 
    } 
} 

}

+0

非常感謝:-)我已經有了代碼在這個問題上的大部分在我心中,但只是想看看,如果有可能有一些BSD許可的圖書館,我可以使用,而無需將我自己的東西移動到可重用的圖書館:-) – 2010-01-05 18:25:44

相關問題