Class textFieldC=tetxField.getClass(); //tetxField ialah objek kelas JTextField
Penerangan utama kebolehcapaian pantulan
Setiap objek Pembina mewakili kaedah pembina, menggunakan objek Pembina. Kaedah pembinaan yang sepadan boleh dimanipulasi.
getConstructors()
//Dapatkan orang ramai
getConstructor(Class>... parameterTypes)
//Dapatkan orang ramai yang dinyatakan
getDeclaredConstructors()
//Dapatkan semua
getDeclaredConstructor(Class>... parameterTypes)
//Dapatkan kaedah yang ditentukan
Buat kelas Demo1, isytiharkan String pembolehubah ahli jenis dan 3 pembolehubah ahli jenis int dan 3 pembina disediakan.
package bao; public class Demo1{ String s; int i,i2,i3; private Demo1() { } protected Demo1(String s,int i) { this.s=s; this.i=i; } public Demo1(String... strings)throws NumberFormatException{ if(0<strings.length) { i=Integer.valueOf(strings[0]); } if(1<strings.length) { i2=Integer.valueOf(strings[0]); } if(2<strings.length) { i3=Integer.valueOf(strings[0]); } } public void print() { System.out.println("s="+s); System.out.println("i="+i); System.out.println("i2="+i2); System.out.println("i3="+i3); } }
Tulis kelas Utama, di mana semua pembina Demo1 diakses secara reflektif, dan sama ada pembina membenarkan nombor pembolehubah parameter, parameter kemasukan dan jenis pengecualian yang mungkin dilemparkan Output maklumat.
package bao; import java.lang.reflect.Constructor; public class Main { public static void main(String[] args) { Demo1 demo=new Demo1("10","20","30"); Class<? extends Demo1>demoC=demo.getClass(); //获得所有构造方法 Constructor[] declaredConstryctors=demoC.getDeclaredConstructors(); for(int i=0;i<declaredConstryctors.length;i++) { Constructor<?> constructor=declaredConstryctors[i]; System.out.println("查看是否允许带有可变数量的参数:"+constructor.isVarArgs()); System.out.println("该构造方法的入口参数类型依次为:"); Class[]parameterTypes=constructor.getParameterTypes(); //获取所有参数类型 for(int j=0;j<parameterTypes.length;j++) { System.out.println(" "+parameterTypes[j]); } System.out.println("该构造方法的入口可能抛出异常类型为:"); //获取所有可能抛出的异常信息类型 Class[] exceptionTypes=constructor.getExceptionTypes(); for(int j=0;j<exceptionTypes.length;j++) { System.out.println(" "+exceptionTypes[j]); } Demo1 example2=null; while(example2==null) { try { if(i==2) { example2=(Demo1)constructor.newInstance(); }else if(i==1) { example2=(Demo1)constructor.newInstance("7",5); }else { Object[] parameters=new Object[] {new String[] {"100","200","300"}}; example2=(Demo1)constructor.newInstance(parameters); } }catch(Exception e){ System.out.println("在创建对象时抛出异常,下面执行setAccessible()方法"); constructor.setAccessible(true); //设置允许访问 } } if(example2!=null) { example2.print(); System.out.println(); } } } } /*输出结果: 查看是否允许带有可变数量的参数:true 该构造方法的入口参数类型依次为: class [Ljava.lang.String; 该构造方法的入口可能抛出异常类型为: class java.lang.NumberFormatException s=null i=100 i2=100 i3=100 查看是否允许带有可变数量的参数:false 该构造方法的入口参数类型依次为: class java.lang.String int 该构造方法的入口可能抛出异常类型为: s=7 i=5 i2=0 i3=0 查看是否允许带有可变数量的参数:false 该构造方法的入口参数类型依次为: 该构造方法的入口可能抛出异常类型为: 在创建对象时抛出异常,下面执行setAccessible()方法 s=null i=0 i2=0 i3=0 */
Setiap objek Medan mewakili pembolehubah ahli, dan pembolehubah ahli yang sepadan boleh dimanipulasi menggunakan objek Medan.
getFields()
getField(String name)
getDeclaredFields()
getDeclaredField(Nama rentetan)
Buat kelas Demo1 dan isytiharkan pembolehubah ahli jenis int, fioat, boolean dan String dalam turutan dan tetapkan akses berbeza hak.
package bao; public class Demo1{ int i; public float f; protected boolean b; private String s; }
Akses semua pembolehubah ahli dalam kelas Demo1 melalui refleksi, dan keluarkan nama dan jenis maklumat pembolehubah ahli.
package bao; import java.lang.reflect.Field; public class Main { public static void main(String[] args) { Demo1 demo=new Demo1(); Class demoC=demo.getClass(); //获得所有成员变量 Field[] declaredField=demoC.getDeclaredFields(); for(int i=0;i<declaredField.length;i++) { Field field=declaredField[i]; System.out.println("名称为:"+field.getName()); //获取成员变量名称 Class fieldType=field.getType(); ///获取成员变量类型 System.out.println("类型为:"+fieldType); boolean isTurn=true; while(isTurn) { try { isTurn=false; System.out.println("修改前的值为:"+field.get(demo)); if(fieldType.equals(int.class)) { //判断成员变量的类型是否为int类型 System.out.println("利用方法setInt()修改成员变量的值"); field.setInt(demo, 168); //为int类型成员变量赋值 }else if(fieldType.equals(float.class)){ //判断成员变量的类型是否为float类型 System.out.println("利用方法 setFloat()修改成员变量的值"); field.setFloat(demo, 99.9F); //为float类型成员变量赋值 }else if(fieldType.equals(boolean.class)){ //判断成员变量的类型是否为boolean类型 System.out.println("利用方法 setBoolean()修改成员变量的值"); field.setBoolean(demo, true); //为boolean类型成员变量赋值 }else { System.out.println("利用方法 set()修改成员变量的值"); field.set(demo, "MWQ"); //可以为各种类型的成员变量赋值 } //获得成员变量值 System.out.println("修改后的值为:"+field.get(demo)); }catch(Exception e) { System.out.println("在设置成员变量值时抛出异常,"+"下面执行setAccesssible()方法!"); field.setAccessible(true); //设置为允许访问 isTurn=true; } } System.out.println(); } } }
/*Hasil keluaran:
Nama ialah: i
Jenis ialah: int
Nilai sebelum pengubahsuaian ialah: 0
Gunakan kaedah setInt() untuk mengubah suai Nilai pembolehubah ahli
Nilai yang diubah suai ialah: 168
Namanya ialah: f
Jenisnya ialah: float
Nilai sebelum pengubahsuaian ialah: 0.0
Gunakan kaedah setFloat() untuk ubah suai Nilai pembolehubah ahli
Nilai yang diubah suai ialah: 99.9
Namanya ialah: b
Jenisnya ialah: boolean
Nilai sebelum pengubahsuaian ialah: false
Gunakan kaedah setBoolean() untuk ubah suai nilai pembolehubah ahli
Nilai yang diubah suai ialah: benar
Namanya ialah: s
Jenisnya ialah: class java.lang.String
Pengecualian dilemparkan apabila menetapkan nilai pembolehubah ahli , laksanakan kaedah setAccessible() di bawah!
Nilai sebelum pengubahsuaian ialah: null
Gunakan set kaedah() untuk mengubah suai nilai pembolehubah ahli
Nilai yang diubah suai ialah: MWQ
*/
Setiap objek Kaedah mewakili kaedah, dan kaedah yang sepadan boleh dimanipulasi menggunakan objek Kaedah.
getMethods()
getMethod(Nama rentetan, Kelas>... parameterTypes)
getDeclaredMethods()
getDeclaredMethod(String name, Class>... parameterTypes)
Buat kelas Demo1 , Tulis 4 kaedah biasa.
package bao; public class Demo1{ static void staitcMethod() { System.out.println("执行staitcMethod()方法"); } public int publicMethod(int i) { System.out.println("执行publicMethod()方法"); return i*100; } protected int protectedMethod(String s,int i)throws NumberFormatException { System.out.println("执行protectedMethod()方法"); return Integer.valueOf(s)+i; } private String privateMethod(String...strings) { System.out.println("执行privateMethod()方法"); StringBuffer stringBuffer=new StringBuffer(); for(int i=0;i<stringBuffer.length();i++) { stringBuffer.append(strings[i]); } return stringBuffer.toString(); } }
Reflection mengakses semua kaedah dalam kelas Demm1, dan mengeluarkan nama kaedah, jenis parameter masukan, jenis nilai pulangan dan maklumat lain
package bao; import java.lang.reflect.Field; import java.lang.reflect.Method; public class Main { public static void main(String[] args) { Demo1 demo = new Demo1(); Class demoC = demo.getClass(); // 获得所有方法 Method[] declaredMethods = demoC.getDeclaredMethods(); for (int i = 0; i < declaredMethods.length; i++) { Method method = declaredMethods[i]; // 遍历方法 System.out.println("名称为:" + method.getName()); // 获得方法名称 System.out.println("是否允许带有可变数量的参数:" + method.isVarArgs()); System.out.println("入口参数类型依次为:"); // 获得所有参数类型 Class[] parameterTypes = method.getParameterTypes(); for (int j = 0; j < parameterTypes.length; j++) { System.out.println(" " + parameterTypes[j]); } // 获得方法返回值类型 System.out.println("返回值类型为:" + method.getReturnType()); System.out.println("可能抛出的异常类型有:"); // 获得方法可能抛出的所有异常类型 Class[] exceptionTypes = method.getExceptionTypes(); for (int j = 0; j < exceptionTypes.length; j++) { System.out.println(" " + exceptionTypes[j]); } boolean isTurn = true; while (isTurn) { try { isTurn = false; if("staitcMethod".equals(method.getName())) { method.invoke(demo); // 执行没有入口参数的方法 }else if("publicMethod".equals(method.getName())) { System.out.println("返回值为:"+ method.invoke(demo, 168)); // 执行方法 }else if("protectedMethod".equals(method.getName())) { System.out.println("返回值为:"+ method.invoke(demo, "7", 5)); // 执行方法 }else { Object[] parameters = new Object[] { new String[] {"M", "W", "Q" } }; // 定义二维数组 System.out.println("返回值为:"+ method.invoke(demo, parameters)); } }catch(Exception e) { System.out.println("在执行方法时抛出异常," + "下面执行setAccessible()方法!"); method.setAccessible(true); // 设置为允许访问 isTurn = true; } } System.out.println(); } } }
/*Keputusan output :
Namanya ialah: publicMethod
Sama ada nombor pembolehubah parameter dibenarkan: false
Jenis parameter masukan ialah:
int
Jenis nilai pulangan ialah: int
Mungkin dibuang Jenis pengecualian ialah:
Laksanakan kaedah publicMethod()
Nilai pulangan ialah: 16800
Namanya ialah: staitcMethod
Sama ada nombor pembolehubah parameter dibenarkan: false
Jenis parameter masukan ialah:
Jenis nilai pulangan ialah: void
Jenis pengecualian yang mungkin dilemparkan ialah:
Laksanakan kaedah staitcMethod()
Namanya ialah: protectedMethod
Sama ada nombor pembolehubah parameter dibenarkan: false
Jenis parameter kemasukan ialah:
class java.lang.String
int
Jenis nilai pulangan ialah: int
Jenis pengecualian yang mungkin dilemparkan ialah:
class java.lang.NumberFormatException
Laksanakan kaedah protectedMethod()
Nilai pulangan ialah: 12
Namanya ialah: privateMethod
Sama ada nombor pembolehubah parameter dibenarkan: benar
The jenis parameter masukan ialah:
class [Ljava.lang.String;
Jenis nilai pulangan ialah: class java.lang.String
Jenis pengecualian yang mungkin dilemparkan ialah:
Pengecualian dilemparkan apabila melaksanakan kaedah, dan kaedah setAccessible() dilaksanakan di bawah!
Laksanakan kaedah privateMethod()
Nilai pulangan ialah:
*/
public @interface NoMemberAnnotation{Nilai rentetan();}
: Mengisytiharkan kata kunci. @interface
: Nama anotasi. NoMemberAnnotation
: jenis ahli. String
: nama ahli. value
定义并使用Annotation类型
①定义Annotation类型@Constructor_Annotation的有效范围为运行时加载Annotation到JVM中。
package annotationbao; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.CONSTRUCTOR) // 用于构造方法 @Retention(RetentionPolicy.RUNTIME) // 在运行时加载Annotation到JVM中 public @interface Constructor_Annotation{ String value() default "默认构造方法"; // 定义一个具有默认值的String型成员 }
②定义一个来注释字段、方法和参数的Annotation类型@Field_Method_Parameter_Annotation的有效范围为运行时加载Annotation到JVM中
package annotationbao; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.FIELD,ElementType.METHOD,ElementType.PARAMETER}) // 用于字段、方法和参数 @Retention(RetentionPolicy.RUNTIME) // 在运行时加载Annotation到JVM中 public @interface Field_Method_Parameter_Annotation{ String descrblic(); // 定义一个没有默认值的String型成员 Class type() default void.class; // 定义一个具有默认值的Class型成员 }
③编写一个Record类,在该类中运用前面定义Annotation类型的@Constructor_Annotation和@Field_Method_Parameter_Annotation对构造方法、字段、方法和参数进行注释。
package annotationbao; public class Record { @Field_Method_Parameter_Annotation(describe = "编号", type = int.class) int id; @Field_Method_Parameter_Annotation(describe = "姓名", type = String.class) String name; @Constructor_Annotation() public Record() { } @Constructor_Annotation("立即初始化构造方法") public Record( @Field_Method_Parameter_Annotation(describe = "编号", type = int.class) int id, @Field_Method_Parameter_Annotation(describe = "姓名", type = String.class) String name) { this.id = id; this.name = name; } @Field_Method_Parameter_Annotation(describe = "获得编号", type = int.class) public int getId() { return id; } @Field_Method_Parameter_Annotation(describe = "设置编号") public void setId( @Field_Method_Parameter_Annotation(describe = "编号", type = int.class)int id) { this.id = id; } @Field_Method_Parameter_Annotation(describe = "获得姓名", type = String.class) public String getName() { return name; } @Field_Method_Parameter_Annotation(describe = "设置姓名") public void setName( @Field_Method_Parameter_Annotation(describe = "姓名", type = String.class)String name) { this.name = name; } }
如果在定义Annotation类型时将@Retention设置为RetentionPolicy.RUNTIME,那么在运行程序时通过反射就可以获取到相关的Annotation信息,如获取构造方法、字段和方法的Annotation信息。
联合以上的定义并使用Annotation类型,通过反射访问Record类中的Annotation信息。
package annotationbao; import java.lang.annotation.*; import java.lang.reflect.*; public class Main_05 { public static void main(String[] args) { Class recordC = null; try { recordC = Class.forName("Record"); } catch (ClassNotFoundException e) { e.printStackTrace(); } System.out.println("------ 构造方法的描述如下 ------"); Constructor[] declaredConstructors = recordC .getDeclaredConstructors(); // 获得所有构造方法 for (int i = 0; i < declaredConstructors.length; i++) { Constructor constructor = declaredConstructors[i]; // 遍历构造方法 // 查看是否具有指定类型的注释 if (constructor .isAnnotationPresent(Constructor_Annotation.class)) { // 获得指定类型的注释 Constructor_Annotation ca = (Constructor_Annotation) constructor .getAnnotation(Constructor_Annotation.class); System.out.println(ca.value()); // 获得注释信息 } Annotation[][] parameterAnnotations = constructor .getParameterAnnotations(); // 获得参数的注释 for (int j = 0; j < parameterAnnotations.length; j++) { // 获得指定参数注释的长度 int length = parameterAnnotations[j].length; if (length == 0) // 如果长度为0则表示没有为该参数添加注释 System.out.println(" 未添加Annotation的参数"); else for (int k = 0; k < length; k++) { // 获得参数的注释 Field_Method_Parameter_Annotation pa = (Field_Method_Parameter_Annotation) parameterAnnotations[j][k]; System.out.print(" " + pa.describe()); // 获得参数描述 System.out.println(" " + pa.type()); // 获得参数类型 } } System.out.println(); } System.out.println(); System.out.println("-------- 字段的描述如下 --------"); Field[] declaredFields = recordC.getDeclaredFields(); // 获得所有字段 for (int i = 0; i < declaredFields.length; i++) { Field field = declaredFields[i]; // 遍历字段 // 查看是否具有指定类型的注释 if (field .isAnnotationPresent(Field_Method_Parameter_Annotation.class)) { // 获得指定类型的注释 Field_Method_Parameter_Annotation fa = field .getAnnotation(Field_Method_Parameter_Annotation.class); System.out.print(" " + fa.describe()); // 获得字段的描述 System.out.println(" " + fa.type()); // 获得字段的类型 } } System.out.println(); System.out.println("-------- 方法的描述如下 --------"); Method[] methods = recordC.getDeclaredMethods(); // 获得所有方法 for (int i = 0; i < methods.length; i++) { Method method = methods[i]; // 遍历方法 // 查看是否具有指定类型的注释 if (method .isAnnotationPresent(Field_Method_Parameter_Annotation.class)) { // 获得指定类型的注释 Field_Method_Parameter_Annotation ma = method .getAnnotation(Field_Method_Parameter_Annotation.class); System.out.println(ma.describe()); // 获得方法的描述 System.out.println(ma.type()); // 获得方法的返回值类型 } Annotation[][] parameterAnnotations = method .getParameterAnnotations(); // 获得参数的注释 for (int j = 0; j < parameterAnnotations.length; j++) { int length = parameterAnnotations[j].length; // 获得指定参数注释的长度 if (length == 0) // 如果长度为0表示没有为该参数添加注释 System.out.println(" 未添加Annotation的参数"); else for (int k = 0; k < length; k++) { // 获得指定类型的注释 Field_Method_Parameter_Annotation pa = (Field_Method_Parameter_Annotation) parameterAnnotations[j][k]; System.out.print(" " + pa.describe()); // 获得参数的描述 System.out.println(" " + pa.type()); // 获得参数的类型 } } System.out.println(); } } }
/*输出结果:
------ 构造方法的描述如下 ------
默认构造方法
立即初始化构造方法
编号 int
姓名 class java.lang.String
-------- 字段的描述如下 --------
编号 int
姓名 class java.lang.String
-------- 方法的描述如下 --------
获得姓名
class java.lang.String
设置姓名
void
姓名 class java.lang.String
获得编号
int
设置编号
void
编号 int
*/
Atas ialah kandungan terperinci Contoh analisis refleksi Java. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!