Open7

Classクラスで遊ぶ

tomkeitomkei

基本

インスタンスからClassクラスのオブジェクトの取得 getClass()

// 適当にオブジェクトを作成
Object o = new Object();
Class<Object> co = o.getClass()
// ==> class java.lang.Object

クラスリテラル(クラス名.class)によるClassクラスのオブジェクトの取得

Class<Object> co  = Object.class
 // ==> class java.lang.Class

ClassクラスインスタンスもClass<Class>のオブジェクトを持っている

Class<Class> cc = Class.class
// ==> class java.lang.Class
tomkeitomkei

HashSetの持つすべてのメソッド名を取得する。

  • for
import java.lang.reflect.Method;
import java.util.HashSet;

public class HashSetMethods {
    public static void main(String[] args) {
        HashSet<Integer> set = new HashSet<>();
        Method[] methods = set.getClass().getMethods();
        for (Method method : methods) {
            System.out.println(method.getName());
        }
    }
}
  • stream経由
Arrays.stream(HashSet.class.getMethods())
  .forEach(m -> System.out.println(m.getName()))
tomkeitomkei

int[] のクラスの持つすべてのメソッド名を取得する。

  • for
Method[] methods = int[].class.getMethods();
for (Method method : methods) {
    System.out.println(method.getName());
}

int[]のクラスの取得 その1

int[].class
// ==> class [I

int[]のクラスの取得 その2

Class.forName("[I")
// ==> class [I
tomkeitomkei

配列のクラス名

基本データ型の配列のクラス名は

  • int[] => [I
  • double[] => [D
  • boolean[] => [Z
  • char[] => [C
  • long[] => [J
  • float[] => [F
  • short[] => [S
  • byte[] => [B

となる。

参照型の配列のクラス名は

  • Object[] => [Ljava.lang.Object;
  • Integer[] => [Ljava.lang.Integer;

のように[L<classname>;の形になる。
<classname>はFQCNであることと、最後にセミコロンがつく点に注意。

クラスリテラル(クラス名.class)での取得

int[].class
// ==> class [I
Object[].class
// ==> class [Ljava.lang.Object;
Integer[].class
// ==> class [Ljava.lang.Integer;

Class.forNameでの取得

Class.forName("[I")
// class [I
Class.forName("[Ljava.lang.Object;")
// ==> class [Ljava.lang.Object;
Class.forName("[Ljava.lang.Integer;")
// ==>  class [Ljava.lang.Integer;
tomkeitomkei

Classクラスの持つメソッドについて

Class.class.getMethods()

でClassクラスの持つメソッドが取得できる。
以下はjshellでの実行結果

Method[78] { public static java.lang.Class java.lang.Class.forName(java.lang.String,boolean,java.lang.ClassLoader) throws java.lang.ClassNotFoundException, public static java.lang.Class java.lang.Class.forName(java.lang.Module,java.lang.String), public static java.lang.Class java.lang.Class.forName(java.lang.String) throws java.lang.ClassNotFoundException, public java.lang.String java.lang.Class.toString(), public java.lang.Module java.lang.Class.getModule(), public java.security.ProtectionDomain java.lang.Class.getProtectionDomain(), public native boolean java.lang.Class.isAssignableFrom(java.lang.Class), public native boolean java.lang.Class.isInstance ... ng.Object.wait() throws java.lang.InterruptedException, public boolean java.lang.Object.equals(java.lang.Object), public native int java.lang.Object.hashCode(), public final native java.lang.Class java.lang.Object.getClass(), public final native void java.lang.Object.notify(), public final native void java.lang.Object.notifyAll() }

ちょっと見づらいので、整形

Arrays.stream(Class.class.getMethods()).forEach(m -> System.out.println(m.getName()))

実行結果

  1. forName
  2. forName
  3. forName
  4. toString
  5. getModule
  6. getProtectionDomain
  7. isAssignableFrom
  8. isInstance
  9. getModifiers
  10. isInterface
  11. isArray
  12. isPrimitive
  13. getSuperclass
  14. cast
  15. getName
  16. toGenericString
  17. newInstance
  18. isAnnotation
  19. isSynthetic
  20. getClassLoader
  21. getTypeParameters
  22. getGenericSuperclass
  23. getPackage
  24. getPackageName
  25. getInterfaces
  26. getGenericInterfaces
  27. getComponentType
  28. getSigners
  29. getEnclosingMethod
  30. getEnclosingConstructor
  31. getDeclaringClass
  32. getEnclosingClass
  33. getSimpleName
  34. getTypeName
  35. getCanonicalName
  36. isAnonymousClass
  37. isLocalClass
  38. isMemberClass
  39. getClasses
  40. getFields
  41. getMethods
  42. getConstructors
  43. getField
  44. getMethod
  45. getConstructor
  46. getDeclaredClasses
  47. getDeclaredFields
  48. getDeclaredMethods
  49. getDeclaredConstructors
  50. getDeclaredField
  51. getDeclaredMethod
  52. getDeclaredConstructor
  53. getResourceAsStream
  54. getResource
  55. desiredAssertionStatus
  56. isEnum
  57. getEnumConstants
  58. asSubclass
  59. getAnnotation
  60. isAnnotationPresent
  61. getAnnotationsByType
  62. getAnnotations
  63. getDeclaredAnnotation
  64. getDeclaredAnnotationsByType
  65. getDeclaredAnnotations
  66. getAnnotatedSuperclass
  67. getAnnotatedInterfaces
  68. getNestHost
  69. isNestmateOf
  70. getNestMembers
  71. wait
  72. wait
  73. wait
  74. equals
  75. hashCode
  76. getClass
  77. notify
  78. notifyAll
tomkeitomkei

forNameやwaitなど、実装がオーバーロードされているものがある。

Java11 の公式ドキュメントを見ると

  1. forName​(Module module, String name)
    与えられたモジュール内の与えられた「バイナリ名」を持つClassを返します。
  2. forName​(String className)
    指定された文字列名を持つクラスまたはインタフェースに関連付けられた、Classオブジェクトを返します。
  3. forName​(String name, boolean initialize, ClassLoader loader)
    指定されたクラス・ローダーを使って、指定された文字列名を持つクラスまたはインタフェースに関連付けられたClassオブジェクトを返します。

普通にClass.forName("[I")などとする場合は、2番のメソッドが呼ばれているぽい。

tomkeitomkei

getInterfaces()でInterFaceを取得。

  • HashSetのInterface
HashSet.class.getInterfaces()
// => Class[3] { interface java.util.Set, interface java.lang.Cloneable, interface java.io.Serializable }
  • ArrayListのInterFace
ArrayList.class.getInterfaces()
// => Class[4] { interface java.util.List, interface java.util.RandomAccess, interface java.lang.Cloneable, interface java.io.Serializable }