2012-01-02 1 views
1

List<?>を返す外部ライブラリを使用しています。 このリストの各オブジェクトがJDKのオブジェクト(String、int、Integer ...)であるかどうかを確認する必要があります。 これは適切な解決策ですか?クラスがJava JDKに属しているかどうかを確認するには

List<?> list = externalLibrary.search(...); 
for(clazz : list) { 
    if (clazz.getPackage().getName().startsWith("java.lang")) 
     // do something different 
} 

いいですか?

+0

ここでclazzは何ですか?返されるリスト?? –

+1

また、 'javax'、' sun'、 'com.sun'あるいは' oracle'や 'com.oracle'で始まるパッケージもあることに注意してください。 – Thomas

+3

Btw、何のためにそれが必要ですか? – Thomas

答えて

4

「JDKのオブジェクト」の定義に応じて、エッジの周りでかなりぼやける可能性があります。いいえ、これは実行しません。 java.langパッケージは、JDKに含まれるすべてのクラスのほんの一部です。

一般に
if (theObject.getClass().getClassLoader() == "".getClass().getClassLoader()) ... 

、異なるClassLoaderは、アプリケーションクラス対システムクラスのために使用される、すなわち -

あなたは、各オブジェクトがjava.lang.Stringロード同じClassLoaderによってロードされたかどうかを確認することがあります。

+1

スマートですが、IMHOで十分ではありません。単一クラスローダーを持つシステムでは、すべてのクラスが同じクラスローダーによってロードされます。 – AlexR

+0

最も単純な構成では、すべてのオブジェクトに対して単一のクラスローダーがありますか?したがって、別のクラスローダを取得しなければ、これは標準クラスと第三者クラスを区別するのに役立たないでしょう。 – Thomas

+0

これは私のユニットテストに合格しません:私はそれを買うことはできません。 –

0

それはちょうどあなたが、次のパッケージをチェックする必要があり、おそらくOKです:おそらく他の人を

java 
javax 
com.sun 
sun 

を...

1

個人的に私はクラスローダベースの答えが好き。しかし、StringBuilderでもtrueを返します。 「組み込み」型だけの定義をさらに絞りたい場合は、これがプリミティブ型(intなど)かラッパー型(Integerなど)かStringかを評価できます。あなたはこのような何かを書くことができます。

import java.util.Map; 
    import java.util.TreeMap; 



    public class Utils { 

     private static Map<String, Class<?>> SUBST_MAP = new TreeMap<String, Class<?>>(); 
     private static Map<String, Class<?>> SIMPLE_MAP = new TreeMap<String, Class<?>>(); 


     static { 
      SUBST_MAP.put(Byte.class.getName(), Byte.TYPE); 
      SUBST_MAP.put(Short.class.getName(), Short.TYPE); 
      SUBST_MAP.put(Integer.class.getName(), Integer.TYPE); 
      SUBST_MAP.put(Long.class.getName(), Long.TYPE); 
      SUBST_MAP.put(Float.class.getName(), Float.TYPE); 
      SUBST_MAP.put(Double.class.getName(), Double.TYPE); 
      SUBST_MAP.put(Boolean.class.getName(), Boolean.TYPE); 
      SUBST_MAP.put(Character.class.getName(), Character.TYPE); 
      SIMPLE_MAP.put(String.class.getName(), Boolean.TRUE); 

     } 




    /** 
    * Gets the the class type of the types of the argument. 
    * 
    * if substPrimitiveWrapper is true, 
    * then if there is argument, that represent primitive type wrapper (such as Integer), 
    *  then it will be substituted to primitive type (such as int). 
    * else no substitution will be done. 
    * 
    * @param arg object. 
    * @param substPrimitiveWrapper - wheteher to do primitive type substitution. 
    * @retrun class type. 
    */ 

    public static Class<?> getClassType(Object arg, boolean substPrimitiveWrapper){ 
     Class<?> classType = null; 
     String className = null; 
     Class<?> substClass = null; 

     if(arg != null){ 
      //making default classType 
      classType = arg.getClass(); 
      if(substPrimitiveWrapper){ 
       className = classType.getName(); 
       substClass = (Class<?>)SUBST_MAP.get(className); 
       if(substClass != null){ 
        classType = substClass; 
       } 

      } 
     } 
     return classType; 
    } 

    /** 
    * This method consider JDK type any primitive type, wrapper class or String. 
    * 
    * 
    * @param arg object 
    * @return where arg is JDK type or now. 
    */ 
    public static boolean isJDKClass(Object arg){ 
     Class<?> classType = getClassType(arg, true); 
     boolean isJDKClass = false; 
     if(classType!=null){ 
      //if(String.class.equals(classType)){ 
      // isJDKClass = true; //this is String, note that String is final 
      //} 
      assert classType!=null; 
      String className = classType.getName(); 
      Boolean isFound = (Boolean)SIMPLE_MAP.get(className); 
      if(Boolean.TRUE.equals(isFound)){ 
       isJDKClass = true; //this is predefined class 
      } 


      boolean isPrimitiveType = classType.isPrimitive(); 
      if(isPrimitiveType){ 
       isJDKClass = true; //this is primitive type or wrapper class 
      } 
     } 

     return isJDKClass; 
    } 

    } 

ます。また、必要に応じてjava.math.BigDecimaljava.util.Datejava.sql.Timestampなどのようなクラスのサポートを追加することができます。しかし、最終的なものではないことに注意してください。でさえも誰かが拡張したとしても、という方法ではJDKクラスとはみなされません。

+0

コメントを追加してコードを少し変更しました。 – alexsmail

1

私たちは、クラスがJDK

public class JDKClass { 

    private static Set<String> CS = new HashSet<String>(); 

    static { 
     try { 
      File file = new File(System.getProperty("java.home"), 
        "lib/classlist"); 
      BufferedReader r = new BufferedReader(new FileReader(file)); 
      String l; 
      while (true) { 
       l = r.readLine(); 
       if (l == null) { 
        break; 
       } else { 
        CS.add(l.replace('/', '.')); 
       } 
      } 
     } catch (Exception e) { 
      throw new RuntimeException(e); 
     } 
    } 

    public static boolean contains(String o) { 
     return CS.contains(o) || o.startsWith("java") || o.startsWith("com.sun") 
       || o.startsWith("sun") || o.startsWith("oracle") 
       || o.startsWith("org.xml") || o.startsWith("com.oracle"); 
    } 

    private JDKClass() { 
    } 

} 
0

に属している場合は、(それがrt.jarのから来f.g.場合)ClassLoader.getSystemResourcesを使用して、クラスがロードされているものを瓶から確認することができますチェックするには、以下のクラスを使用します。

あなたはURLのような取得します:SLF4Jから取ら

jar:file:/C:/Users/user/.m2/repository/org/slf4j/slf4j-log4j12/1.6.1/slf4j-log4j12-1.6.1.jar!/org/slf4j/impl/StaticLoggerBinder.class 

例コード:

private static String STATIC_LOGGER_BINDER_PATH = 
    "org/slf4j/impl/StaticLoggerBinder.class"; 
    private static void singleImplementationSanityCheck() { 
    try { 
     ClassLoader loggerFactoryClassLoader = LoggerFactory.class 
      .getClassLoader(); 
     Enumeration paths; 
     if (loggerFactoryClassLoader == null) { 
     paths = ClassLoader.getSystemResources(STATIC_LOGGER_BINDER_PATH); 
     } else { 
     paths = loggerFactoryClassLoader 
      .getResources(STATIC_LOGGER_BINDER_PATH); 
     } 
    List implementationList = new ArrayList(); 
    while (paths.hasMoreElements()) { 
    URL path = (URL) paths.nextElement(); 
    implementationList.add(path); 
    } 
    .... 
    } 
0

を私は簡単に解決策は、問題の事に、この方法だと思います: にメソッドを書きますあなたによって定義されたすべてのクラスを識別します。ほとんどの場合、すべてのユーザ定義クラスはcom.something.somethingのようなパターンに従います。次に、com.something.somethingに属していない場合、それはJDKクラスです

関連する問題