JavaのリフレクションAPIをいじって、いくつかのフィールドを処理しようとしています。今、私は自分のフィールドのタイプを特定することにこだわっています。文字列は簡単です、ただmyField.getType().equals(String.class)
してください。同じことが他の派生クラスにも当てはまります。しかし、派生クラスを確認するにはどうすればよいですか?例えば。 LinkedList
のサブクラスとしてList
。 isSubclassOf(...)
またはextends(...)
メソッドが見つかりません。すべてのgetSuperClass()
を調べて、自分でスーパークラスを見つける必要がありますか?
このメソッドが必要です:
boolean isList = List.class.isAssignableFrom(myClass);
一般的に、List
(上記)はsuperclass
に置き換えられ、myClass
はsubclass
に置き換えられます。
JavaDoc から:
この
Class
オブジェクトによって表されるクラスまたはインターフェースが、指定されたClass
パラメーターによって表されるクラスまたはインターフェースと同じであるか、スーパークラスまたはスーパーインターフェースであるかを判別します。そうであれば、true
を返します。それ以外の場合は、false
を返します。このClass
オブジェクトがプリミティブ型を表す場合、指定されたtrue
パラメーターがまさにこのClass
オブジェクトである場合、このメソッドはClass
を返します。それ以外の場合は、false
を返します。
参照:
関連:
a)オブジェクトがコンパイル時にわかっているクラスまたはインターフェイス(サブクラスを含む)のインスタンスであるかどうかを確認します。
boolean isInstance = someObject instanceof SomeTypeOrInterface;
例:
assertTrue(Arrays.asList("a", "b", "c") instanceof List<?>);
b)オブジェクトが実行時にしかわからないクラスまたはインターフェース(サブクラスを含む)のインスタンスであるかどうかを確認します。
Class<?> typeOrInterface = // acquire class somehow
boolean isInstance = typeOrInterface.isInstance(someObject);
例:
public boolean checkForType(Object candidate, Class<?> type){
return type.isInstance(candidate);
}
別のオプションはinstanceofです:
Object o =...
if (o instanceof Number) {
double d = ((Number)o).doubleValue(); //this cast is safe
}
instanceofはインスタンス、つまりオブジェクトで機能します。クラスを直接操作したい場合があります。この場合、ClassクラスのasSubClassメソッドを使用できます。いくつかの例:
1)
Class o=Object.class;
Class c=Class.forName("javax.swing.JFrame").asSubclass(o);
jFrameはObjectのサブクラスであるため、これはスムーズに進みます。 cには、JFrameクラスを表すClassオブジェクトが含まれます。
2)
Class o=JButton.class;
Class c=Class.forName("javax.swing.JFrame").asSubclass(o);
jFrameはJButtonのサブクラスではないため、これによりJava.lang.ClassCastExceptionが起動します。 cは初期化されません。
3)
Class o=Serializable.class;
Class c=Class.forName("javax.swing.JFrame").asSubclass(o);
jFrameはJava.io.Serializableインターフェースを実装しているため、これはスムーズに進みます。 cには、JFrameクラスを表すClassオブジェクトが含まれます。
もちろん、必要なインポートを含める必要があります。
これは私のために働く:
protected boolean isTypeOf(String myClass, Class<?> superClass) {
boolean isSubclassOf = false;
try {
Class<?> clazz = Class.forName(myClass);
if (!clazz.equals(superClass)) {
clazz = clazz.getSuperclass();
isSubclassOf = isTypeOf(clazz.getName(), superClass);
} else {
isSubclassOf = true;
}
} catch(ClassNotFoundException e) {
/* Ignore */
}
return isSubclassOf;
}
これは、@ schuttekの回答の改良版です。プリミティブに対して正しくfalseを返すため(例:isSubclassOf(int.class、Object.class)=> false)、インターフェースを正しく処理するため(例:isSubclassOf(HashMap.class、Map.class)=> true)。
static public boolean isSubclassOf(final Class<?> clazz, final Class<?> possibleSuperClass)
{
if (clazz == null || possibleSuperClass == null)
{
return false;
}
else if (clazz.equals(possibleSuperClass))
{
return true;
}
else
{
final boolean isSubclass = isSubclassOf(clazz.getSuperclass(), possibleSuperClass);
if (!isSubclass && clazz.getInterfaces() != null)
{
for (final Class<?> inter : clazz.getInterfaces())
{
if (isSubclassOf(inter, possibleSuperClass))
{
return true;
}
}
}
return isSubclass;
}
}
Class<?>
が別のClass<?>
...のサブクラスであるかどうかを確認する再帰的メソッド.
protected boolean isSubclassOf(Class<?> clazz, Class<?> superClass) {
if (superClass.equals(Object.class)) {
// Every class is an Object.
return true;
}
if (clazz.equals(superClass)) {
return true;
} else {
clazz = clazz.getSuperclass();
// every class is Object, but superClass is below Object
if (clazz.equals(Object.class)) {
// we've reached the top of the hierarchy, but superClass couldn't be found.
return false;
}
// try the next level up the hierarchy.
return isSubclassOf(clazz, superClass);
}
}
//継承
class A {
int i = 10;
public String getVal() {
return "I'm 'A'";
}
}
class B extends A {
int j = 20;
public String getVal() {
return "I'm 'B'";
}
}
class C extends B {
int k = 30;
public String getVal() {
return "I'm 'C'";
}
}
//メソッド
public static boolean isInheritedClass(Object parent, Object child) {
if (parent == null || child == null) {
return false;
} else {
return isInheritedClass(parent.getClass(), child.getClass());
}
}
public static boolean isInheritedClass(Class<?> parent, Class<?> child) {
if (parent == null || child == null) {
return false;
} else {
if (parent.isAssignableFrom(child)) {
// is child or same class
return parent.isAssignableFrom(child.getSuperclass());
} else {
return false;
}
}
}
//コードをテストします
System.out.println("isInheritedClass(new A(), new B()):" + isInheritedClass(new A(), new B()));
System.out.println("isInheritedClass(new A(), new C()):" + isInheritedClass(new A(), new C()));
System.out.println("isInheritedClass(new A(), new A()):" + isInheritedClass(new A(), new A()));
System.out.println("isInheritedClass(new B(), new A()):" + isInheritedClass(new B(), new A()));
System.out.println("isInheritedClass(A.class, B.class):" + isInheritedClass(A.class, B.class));
System.out.println("isInheritedClass(A.class, C.class):" + isInheritedClass(A.class, C.class));
System.out.println("isInheritedClass(A.class, A.class):" + isInheritedClass(A.class, A.class));
System.out.println("isInheritedClass(B.class, A.class):" + isInheritedClass(B.class, A.class));
//結果
isInheritedClass(new A(), new B()):true
isInheritedClass(new A(), new C()):true
isInheritedClass(new A(), new A()):false
isInheritedClass(new B(), new A()):false
isInheritedClass(A.class, B.class):true
isInheritedClass(A.class, C.class):true
isInheritedClass(A.class, A.class):false
isInheritedClass(B.class, A.class):false