JAvaコアテクノロジーの反射
8962 ワード
クラス能力を解析できるプログラムは反射となる.反射を使用する主なオブジェクトは、アプリケーションプログラマーではなくツールコンストラクタです.1、ClassがClassクラスのインスタンスを返すには、いくつかの方法があります.
2、検査クラス構造検査クラス構造--java反射機構の重要な内容java.lang.reflectパッケージの3つのクラスField、Method、Constructorは、クラスドメイン、メソッド、コンストラクタを記述するためにそれぞれ使用されます.
3、実行時の反射分析オブジェクトの反射メカニズムのデフォルトの動作はjavaアクセス制御に制限されている.
4、反射により汎用配列コードjavaを記述する.lang.reflectパッケージのArrayクラスでは、配列を動的に作成できます.
5.メソッドポインタ実行オブジェクトメソッドまたは静的メソッド
必要に応じてMethodオブジェクトを使用することをお勧めします.インタフェースと内部クラスを使用することが望ましいです.反射反射をあまり使わないでください.コンパイラはプログラムのエラーを発見するのに役立ちません.エラーは、実行時にのみ検出され、例外が発生します.
//a
Girl g1 = new Girl();
Class c0 = g1.getClass();
//b
String className = "com.gong.reflect.Girl";
Class c1 = Class.forName(className);
//c
Class c2 = Girl.class;
2、検査クラス構造検査クラス構造--java反射機構の重要な内容java.lang.reflectパッケージの3つのクラスField、Method、Constructorは、クラスドメイン、メソッド、コンストラクタを記述するためにそれぞれ使用されます.
public class ReflectionTest {
public static void main(String[] args) {
// read class name from command line args or user input
String name;
if (args.length > 0)
name = args[0];
else {
Scanner in = new Scanner(System.in);
System.out.println("Enter class name (e.g. java.util.Date): ");
name = in.next();
}
try {
Class cl = Class.forName(name);
Class supercl = cl.getSuperclass();
String modifiers = Modifier.toString(cl.getModifiers());
//getModifiers() 、
System.out.println(cl.getModifiers());
//Modifier.toString modifier
System.out.println("modifiers:"+modifiers);
if (modifiers.length() > 0)
System.out.print(modifiers + " ");
System.out.print("class " + name);
if (supercl != null && supercl != Object.class)
System.out.print(" extends " + supercl.getName());
System.out.print("
{
");
printConstructors(cl);
System.out.println();
printMethods(cl);
System.out.println();
printFields(cl);
System.out.println("}");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.exit(0);
}
public static void printConstructors(Class cl) {
Constructor[] constructors = cl.getDeclaredConstructors();
for (Constructor c : constructors) {
String name = c.getName();
System.out.print(" ");
String modifiers = Modifier.toString(c.getModifiers());
if (modifiers.length() > 0)
System.out.print(modifiers + " ");
System.out.print(name + "(");
// print parameter types
Class[] paramTypes = c.getParameterTypes();
for (int j = 0; j < paramTypes.length; j++) {
if (j > 0)
System.out.print(", ");
System.out.print(paramTypes[j].getName());
}
System.out.println(");");
}
}
public static void printMethods(Class cl) {
Method[] methods = cl.getDeclaredMethods();
for (Method m : methods) {
Class retType = m.getReturnType();
String name = m.getName();
System.out.print(" ");
// print modifiers, return type and method name
String modifiers = Modifier.toString(m.getModifiers());
if (modifiers.length() > 0)
System.out.print(modifiers + " ");
System.out.print(retType.getName() + " " + name + "(");
// print parameter types
Class[] paramTypes = m.getParameterTypes();
for (int j = 0; j < paramTypes.length; j++) {
if (j > 0)
System.out.print(", ");
System.out.print(paramTypes[j].getName());
}
System.out.println(");");
}
}
public static void printFields(Class cl) {
Field[] fields = cl.getDeclaredFields();
for (Field f : fields) {
Class type = f.getType();
String name = f.getName();
System.out.print(" ");
String modifiers = Modifier.toString(f.getModifiers());
if (modifiers.length() > 0)
System.out.print(modifiers + " ");
System.out.println(type.getName() + " " + name + ";");
}
}
}
3、実行時の反射分析オブジェクトの反射メカニズムのデフォルトの動作はjavaアクセス制御に制限されている.
public class FieldTest {
public static void main(String[] args) {
try {
Girl g = new Girl("lady gaga", 26, 38);
Class cl = g.getClass();
Field f = cl.getDeclaredField("name");
//
//true java ,
f.setAccessible(true);
Object o = f.get(g);
System.out.println(o);
}catch(SecurityException e) {
e.printStackTrace();
}catch(NoSuchFieldException e) {
e.printStackTrace();
}catch(IllegalArgumentException e) {
e.printStackTrace();
}catch(IllegalAccessException e) {
e.printStackTrace();
}
}
}
4、反射により汎用配列コードjavaを記述する.lang.reflectパッケージのArrayクラスでは、配列を動的に作成できます.
public class ArrayGrowTest {
public static void main(String[] args) {
int[] a = { 1, 2, 3 };
a = (int[]) goodArrayGrow(a);
arrayPrint(a);
String[] b = { "Tom", "Dick", "Harry" };
b = (String[]) goodArrayGrow(b);
arrayPrint(b);
System.out.println("The following call will generate an exception.");
b = (String[]) badArrayGrow(b);
}
static Object[] badArrayGrow(Object[] a) {
int newLength = a.length * 11 / 10 + 10;
// String
Object[] newArray = new Object[newLength];
System.arraycopy(a, 0, newArray, 0, a.length);
return newArray;
}
static Object goodArrayGrow(Object a) {
Class cl = a.getClass();
if (!cl.isArray()) return null;
Class componentType = cl.getComponentType();
int length = Array.getLength(a);
int newLength = length * 11 / 10 + 10;
//componentType ,newLength
Object newArray = Array.newInstance(componentType, newLength);
System.arraycopy(a, 0, newArray, 0, length);
return newArray;
}
static void arrayPrint(Object a) {
Class cl = a.getClass();
if (!cl.isArray()) return;
Class componentType = cl.getComponentType();
int length = Array.getLength(a);
System.out.print(componentType.getName() + "[" + length + "] = { ");
for (int i = 0; i < Array.getLength(a); i++)
System.out.print(Array.get(a, i) + " ");
System.out.println("}");
}
}
5.メソッドポインタ実行オブジェクトメソッドまたは静的メソッド
public class MethodPointerTest {
public static void main(String[] args) throws Exception {
Method square = MethodPointerTest.class.getMethod("square", double.class);
Method sqrt = Math.class.getMethod("sqrt", double.class);
printTable(1, 10, 10, square);
printTable(1, 10, 10, sqrt);
}
public static double square(double x) {
return x * x;
}
public static void printTable(double from, double to, int n, Method f) {
System.out.println(f);
double dx = (to - from) / (n - 1);
for (double x = from; x <= to; x += dx) {
try {
double y = (Double) f.invoke(null, x);
System.out.printf("%10.4f | %10.4f%n", x, y);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
必要に応じてMethodオブジェクトを使用することをお勧めします.インタフェースと内部クラスを使用することが望ましいです.反射反射をあまり使わないでください.コンパイラはプログラムのエラーを発見するのに役立ちません.エラーは、実行時にのみ検出され、例外が発生します.