反射
1、反射机制
- JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法。
- 对于任意一个对象,都能够调用它的任意一个方法和属性。
- 这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
2、反射
- 反射是把java类中的各种成分映射成一个个的Java对象
- 加载是class文件读入内存,并为之创建一个Class对象。
- 利用反射技术可以对一个类进行解剖,把个个组成部分映射成一个个对象。
java.lang.Class
1、继承了 java.lang.Object 类,实现了 java.lang.reflect.Type 等接口
- Class 类的实例表示正在运行的 Java 应用程序中的类和接口。
- 枚举 ( enum ) 是一种类,注解 ( @interface ) 是一种接口。
- USer、Role类就是Class的实例对象,Class是对类的描述,即类类型。
- class类的实例表示java应用运行时的类(class ans enum)或接口(interface and annotation)。
- 数组同样也被映射为为class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。
- 基本类型boolean,byte,char,short,int,long,float,double和关键字void同样表现为 class 对象。
2、Class类没有公有的构造方法,它由JVM自动调用,我有如下3种方式获取Class
- 某个对象实例的getClass()方法,如new User().getClass()。
- 某个类名.class属性,如User.class(任何数据类型(包括基本数据类型)都有一个“静态”的class属性)。
- 通过Class.forName("类名")获取。
-
三种方式常用第三种,第一种对象都有了还要反射干什么。第二种需要导入类的包,依赖太强,不导包就抛编译错误。一般都第三种,一个字符串可以传入也可写在配置文件中等多种方法。
2、常用的静态方法:
- static Class<?> forName( String className ) 返回与带有给定字符串名的类或接口相关联的 Class 对象。
- static Class<?> forName( String name , boolean initialize , ClassLoader loader ) 使用给定的类加载器,返回与带有给定字符串名的类或接口相关联的 Class 对象。
3、 常用的非静态方法:
- String getName() 以 String 的形式返回此 Class 对象所表示的实体(类、接口、数组类、基本类型或 void)名称。
- String getSimpleName() 返回源代码中给出的底层类的简称。
- String getCanonicalName() 返回 Java Language Specification 中所定义的底层类的规范化名称。
- Class<? super T> getSuperclass() 返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的超类的 Class。
- Class<?>[] getInterfaces() 确定此对象所表示的类实现的接口 或 此对象所表示的接口所继承的接口。
- ClassLoader getClassLoader() 返回该类的类加载器。
- int getModifiers() 以 int 形式返回该类的修饰符。
- boolean isAnnotation() 如果当前类型所表示的是一个 [注解] 则返回 true ,否则返回 false。
- boolean isArray() 如果当前类型所表示的是一个 [数组] 则返回 true ,否则返回 false。
- boolean isEnum() 如果当前类型所表示的是一个 [枚举] 则返回 true ,否则返回 false。
- boolean isInterface() 如果当前类型所表示的是一个 [接口] 则返回 true ,否则返回 false。
- Class<?>[] getClasses()获取该类的父类或接口
- T newInstance 创建此 Class 对象所表示的类的一个新实例。
4、获得某个类中的属性的非静态方法:
- Field getDeclaredField( String name ) 获得在本类中直接声明( private 、默认 、protected 、public)指定名称的属性( Field )对象。
- Field[] getDeclaredFields() 获得由本类直接声明的所有的属性组成的 Field 数组。
- Field getField( String name ) 获得本类中或父类中声明的 public 修饰的指定名称的属性对应的Field对象。
- Field[] getFields() 获得本类中或父类中声明的、由 public 修饰的所有的属性组成的 Field 数组。
获得某个类中的属性测试案例一:
package ecut.reflect.entity ; public class Student { private int id ; private String name ; public Student () { System.out.println( "无参构造执行" ); } protected Student ( int id ) { System.out.println( "带有一个int类型参数的构造执行" ); this.id = id ; } public Student( int id , String name ) { System.out.println( "带有一个int类型参数和一个String类型参数的构造执行" ); this.id = id; this.name = name; } public Student( String name , int id ) throws RuntimeException , NullPointerException { System.out.println( "带有一个String类型参数和一个int类型参数的构造执行" ); this.id = id; this.name = name; } public int getId(){ return this.id ; } public void setId( int id ) { this.id = id ; } public String getName(){ return this.name ; } public void setName( String name ) { this.name = name ; } public void eat( String food ) { System.out.println( this.name + " 吃 " + food ); } }
package ecut.reflect; import java.lang.reflect.Field; import ecut.reflect.entity.Student; public class AccessFieldTest1 { public static void main(String[] args) { Object o = new Student(); Class<?> c = o.getClass() ; Field[] fields = c.getDeclaredFields();//获得由本类直接声明的所有的属性组成的 Field 数组 for( int i = 0 , n = fields.length ; i < n ; i++ ) { Field f = fields[ i ] ; System.out.println( f ); } } }
运行结果如下:
无参构造执行 private int ecut.reflect.entity.Student.id private java.lang.String ecut.reflect.entity.Student.name
获得某个类中的属性测试案例二:
package ecut.reflect; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import ecut.reflect.entity.Student; public class AccessFieldTest2 { public static void main(String[] args) throws NoSuchFieldException, SecurityException { Object o = new Student(); Class<?> c = o.getClass() ; //获得在本类中直接声明指定名称的属性( Field )对象 private 、默认 、protected 、public Field idField = c.getDeclaredField( "id" ); int mod = idField.getModifiers();//以 int 形式返回该 属性 ( Field ) 的修饰符 System.out.println( mod ); String modifiers = Modifier.toString( mod );//返回描述指定修饰符中的访问修饰符标志的字符串 System.out.println( modifiers ); } }
运行结果如下:
无参构造执行 2 private
5、获得某个类中的方法的非静态方法:
- Method getDeclaredMethod( String name , Class<?>... parameterTypes )获得由本类直接声明的指定名称、指定参数列表的方法对应的 Method 对象。
- Method[] getDeclaredMethods() 获得由本类直接声明的所有的方法对应的 Method 数组。
- Method getMethod( String name , Class<?>... parameterTypes )获得由本类或父类声明的由 public 修饰的、指定名称、指定参数列表的方法对应的 Method 对象。
- Method[] getMethods() 获得由本类或父类声明的所有的 public 修饰方法对应的 Method 数组。
获得某个类中的方法测试案例一:
package ecut.reflect; import java.lang.reflect.Method; import ecut.reflect.entity.Student; public class AccessMethodTest1 { public static void main(String[] args) { Object o = new Student(); Class<?> c = o.getClass() ; //获得由本类直接声明的所有的方法对应的 Method 数组 Method[] methods = c.getDeclaredMethods(); for( int i = 0 , n = methods.length ; i < n ; i++ ) { Method m = methods[ i ] ; System.out.println( m ); } } }
运行结果如下:
无参构造执行 public java.lang.String ecut.reflect.entity.Student.getName() public int ecut.reflect.entity.Student.getId() public void ecut.reflect.entity.Student.setName(java.lang.String) public void ecut.reflect.entity.Student.setId(int) public void ecut.reflect.entity.Student.eat(java.lang.String)
获得某个类中的方法测试案例二:
package ecut.reflect; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import ecut.reflect.entity.Student; public class AccessMethodTest2 { public static void main(String[] args) throws NoSuchMethodException, SecurityException { Object o = new Student(); Class<?> c = o.getClass() ; // 获得由本类或父类声明的由 public 修饰的、指定名称、指定参数列表的方法对应的 Method 对象 Method eatMethod = c.getDeclaredMethod( "eat" , String.class ); int mod = eatMethod.getModifiers();//以 int 形式返回该 方法 ( Method ) 的修饰符 System.out.println( mod );//1(public)+16(final) String modifiers = Modifier.toString( mod );//返回描述指定修饰符中的访问修饰符标志的字符串 System.out.println( modifiers ); } }
运行结果如下:
无参构造执行 17 public final
6、获得某个类中的构造方法:
- Constructor<T> getDeclaredConstructor( Class<?>... parameterTypes ) 获得由本类所声明的所有的构造方法中 参数 与指定的 参数列表 匹配的那个构造方法 ,这些构造方法的修饰符可以是 private 、默认 、protected 、public。
- Constructor<?>[] getDeclaredConstructors() 获得由本类所声明的所有的构造方法组成的数组,构造方法的修饰符可以是private 、默认 、protected 、public。
- Constructor<T> getConstructor( Class<?>... parameterTypes )从本类的 public 修饰的构造方法中,寻找与 parameterTypes 相匹配的那个构造方法。
- Constructor<?>[] getConstructors()获得本类中所有的 public 修饰的构造方法组成的数组。
获得某个类中的构造方法测试案例一:
package ecut.reflect; import java.lang.reflect.Constructor; import ecut.reflect.entity.Student; public class AccessConstructorTest1 { public static void main(String[] args) { Class<?> c = Student.class ; //获得由本类所声明的所有的构造方法组成的数组,这些构造方法的修饰符可以是 private 、默认 、protected 、public Constructor<?>[] cs = c.getDeclaredConstructors(); for( Constructor<?> con : cs ){ System.out.println( con ); } System.out.println( "~~~~~~~~~~~~~~~~~~~~~~~" ); //获得本类中所有的 public 修饰的构造方法组成的数组 Constructor<?>[] constructors = c.getConstructors(); for( Constructor<?> con : constructors ){ System.out.println( con ); } } }
运行结果如下:
public ecut.reflect.entity.Student(java.lang.String,int) throws java.lang.RuntimeException,java.lang.NullPointerException public ecut.reflect.entity.Student(int,java.lang.String) protected ecut.reflect.entity.Student(int) public ecut.reflect.entity.Student() ~~~~~~~~~~~~~~~~~~~~~~~ public ecut.reflect.entity.Student(java.lang.String,int) throws java.lang.RuntimeException,java.lang.NullPointerException public ecut.reflect.entity.Student(int,java.lang.String) public ecut.reflect.entity.Student()
获得某个类中的构造方法测试案例二:
package ecut.reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Modifier; import ecut.reflect.entity.Student; public class AccessConstructorTest2 { public static void main(String[] args) throws Exception { Class<Student> c = Student.class ; //从本类的 public 修饰的构造方法中,寻找与 parameterTypes 相匹配的那个构造方法 Constructor<Student> con = c.getConstructor( int.class , String.class ); System.out.println( con ); int mod = con.getModifiers() ; System.out.println( Modifier.toString( mod ) ); System.out.println( "~~~~~~~~~~~~~~~~~~~~~~~~~~~~" ); Object o = con.newInstance( 100 , "张三丰" ); System.out.println( o );//通过反射获取到对象 } }
运行结果如下:
public ecut.reflect.entity.Student(int,java.lang.String) public ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 带有一个int类型参数和一个String类型参数的构造执行 ecut.reflect.entity.Student@15db9742
java.lang.reflect
1、Field 表示 类 或 接口 中的属性
- int getModifiers() 以 int 形式返回该 属性 ( Field ) 的修饰符。
- Class<?> getType() 返回当前属性的类型 ( 是一个 Class 类型的对象 )。
- String getName() 返回此 Field 对象表示的属性 的名称。
- Object get( Object o ) 返回指定对象( o ) 中,该 Field 表示的属性的值。
- void set( Object o , Object value ) 为指定对象 ( o ) 的 该属性赋值。
2、Method 表示 类 或 接口 中的方法
- int getModifiers() 以 int 形式返回该 方法 ( Method ) 的修饰符
- String getName() 以 String形式返回此 Method对象表示的方法名称。
- Class<?> getReturnType() 返回一个Class对象,该对象描述了此 Method对象所表示的方法的正式返回类型。
- Class<?>[] getParameterTypes() 按照声明顺序返回 Class对象的数组,这些对象描述了此 Method对象所表示的方法的形参类型。
- Class<?>[] getExceptionTypes() 返回 Class对象的数组,这些对象描述了声明将此 Method对象表示的底层方法抛出的异常类型。
- Object invoke( Object target , Object... args ) 对带有指定参数的指定对象调用由此 Method对象表示的底层方法
3、Modifier表示 类 或 接口 中的修饰符
- static String toString( int mod ) 返回描述指定修饰符中的访问修饰符标志的字符串。
4、Constructor 表示 某个 类的 构造方法,构造方法特点: 与类名同名 、没有返回类型 、构造不能被继承。
- int getModifiers() 以 int 形式返回该 构造方法 ( Constructor) 的修饰符
- Class<?>[] getParameterTypes() 按照声明顺序返回一组 Class对象,这些对象表示此 Constructor对象所表示构造方法的形参类型。
- Class<?>[] getExceptionTypes() 返回 Class对象的数组,这些对象描述了声明将此 Constructor对象表示的构造方法抛出的异常类型
5、Array : 不表示数组,它提供了操作数组的方法
- static int getLength( Object array ) 获得 array 对应的数组中元素个数。
- static void set( Object array, int index , Object value ) 相当于 array[ index ] = value ;
- static Object get( Object array , int index ) 相当于 Object o = array[ index ] ;
- static Object newInstance( Class<?> componentType , int length ) 比如 Array.newInstance( int.class , 10 ) 相当于 new int[ 10 ] ;
- static Object newInstance( Class<?> componentType , int... dimensions )比如 Array.newInstance( char.class , 4 , 5 ) 相当于 new char[ 4 ] [ 5 ] ;
Array测试案例一:
package ecut.reflect;
import java.lang.reflect.Array;
import java.util.Random;
public class AccessArrayTest1 {
public static void main(String[] args) {
Random rand = new Random();
Object o = new int[ 10 ] ;
// 获得 o 的运行时类型 ( o 所引用的对象的类型 )
Class<?> c = o.getClass(); // java.lang.Object 类的 getClass 方法被所有类所继承
if( c.isArray() ) {
// 获得数组长度
int length = Array.getLength( o ) ; // o.length ;
System.out.println( "数组元素个数: " + length );
// 用反射方式遍历数组
for( int i = 0 ; i < length ; i++ ){
Object v = Array.get( o , i ) ; // o[ i ] ;
System.out.print( v + " " );
}
System.out.println();
// 用反射方式为数组中的每个元素赋值
for( int i = 0 ; i < length ; i++ ){
int v = rand.nextInt( 100 ) ; // 产生 [ 0 , 100 ) 之间的整数
Array.set( o , i , v ); // o [ i ] = v ;
}
System.out.println( "~~~~~~~~~~~~~" );
for( int i = 0 ; i < length ; i++ ){
Object v = Array.get( o , i ) ; // o[ i ] ;
System.out.print( v + " " );
}
System.out.println();
}
}
}
运行结果如下:
数组元素个数: 10 0 0 0 0 0 0 0 0 0 0 ~~~~~~~~~~~~~ 38 42 84 1 38 20 81 83 52 49
Array测试案例二:
package ecut.reflect;
import java.lang.reflect.Array;
import java.util.Random;
public class AccessArrayTest2 {
public static void main(String[] args) {
Random rand = new Random();
Object o = Array.newInstance( int.class , 10 ); // Object o = new int[ 10 ] ;
Class<?> c = o.getClass() ;
if( c.isArray() ){
int n = Array.getLength( o );
System.out.println( n );
// 用反射方式为数组中的每个元素赋值
for (int i = 0; i < n; i++) {
int v = rand.nextInt(100); // 产生 [ 0 , 100 ) 之间的整数
Array.set(o, i, v); // o [ i ] = v ;
}
// 用反射方式遍历数组
for (int i = 0; i < n; i++) {
Object v = Array.get(o, i); // o[ i ] ;
System.out.print(v + " ");
}
System.out.println();
} else {
System.out.println( "不是数组" );
}
}
}
运行结果如下:
10 54 23 75 30 6 83 92 92 76 53
Array测试案例三:
package ecut.reflect;
import java.lang.reflect.Array;
public class AccessArrayTest3 {
public static void main(String[] args) {
Object o = Array.newInstance( int.class , 4 , 5 ) ; // new char[ 4 ] [ 5 ] ;
Class<?> c = o.getClass();
if( c.isArray() ){
int x = Array.getLength( o ) ; // 获得最外维的数组的长度
System.out.println( "外部数组长度: " + x );
for( int i = 0 ; i < x ; i++ ){
// 获得数组内部的元素 ( 可能还是数组 )
Object e = Array.get( o , i );
Class<?> cc = e.getClass();
if( cc.isArray() ){
int y = Array.getLength( e ) ; // 获得第二维的数组的长度
for( int j = 0 ; j < y ; j++ ){
// 获得第二维数组中的元素
Object v = Array.get( e , j ) ;
System.out.print( v + " " );
}
System.out.println();
} else {
System.out.println( e );
}
}
}
}
}
运行结果如下:
外部数组长度: 4
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
6、Type
- Type 是 Java 编程语言中所有类型的公共高级接口。它们包括原始类型、参数化类型、数组类型、类型变量和基本类型。
7、AccessibleObject 是 Field 、Method 、Constructor 类的父类
- boolean isAccessible() 获取此对象的 accessible 标志的值 ,判断指定对象是否可以被访问,比如 private 修饰的属性就不能直接访问。
- void setAccessible( boolean flag )将此对象的 accessible 标志设置为指示的布尔值,让一个本来不能访问的对象可以被访问,可以写作 setAccessible( true )。
操作属性:
- Object get( Object o ) 返回指定对象( o ) 中,该 Field 表示的属性的值。
- void set( Object o , Object value ) 为指定对象 ( o ) 的 该属性赋值。
操作属性测试案例:
package ecut.reflect;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import ecut.reflect.entity.Student;
public class AccessFieldTest3 {
public static void main(String[] args) {
Object o = new Student();
Class<?> c = o.getClass();
try {
// 获得由本类直接声明的所有的属性组成的 Field 数组
Field idField = c.getDeclaredField("id");
System.out.println(idField);
int mod = idField.getModifiers(); // 获得修饰符
String modifier = Modifier.toString(mod);
System.out.println("modifier : " + modifier);
// 返回当前属性的类型 ( 是一个 Class 类型的对象 )
Class<?> type = idField.getType();
System.out.println("type : " + type.getName());
// 返回此 Field 对象表示的属性 的名称
String name = idField.getName();
System.out.println("name : " + name);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
}
}
运行结果:
无参构造执行
private int ecut.reflect.entity.Student.id
modifier : private
type : int
name : id
操作属性测试案例:
package ecut.reflect;
import java.lang.reflect.Field;
import ecut.reflect.entity.Student;
public class AccessFieldTest4 {
public static void main(String[] args) {
Object o = new Student( 100 , "张三丰" );
Class<?> c = o.getClass();
try {
Field idField = c.getDeclaredField( "id" );
//判断指定对象是否可以被访问,比如 private 修饰的属性就不能直接访问
if( idField.isAccessible() == false) {
//让一个本来不能访问的对象可以被访问,可以写作 setAccessible( true )
idField.setAccessible( true );
}
// 从 o 对象中 获取 idField 所表示的属性的值
Object v = idField.get( o ) ; // o.id ;
System.out.println( v );
int value = 1001 ;
//为指定对象 ( o ) 的 该属性赋值
// 为 o 对象中的 idField 所表示的属性 赋予 value 所表示的值
idField.set( o , value );
//返回指定对象( o ) 中,该 Field 表示的属性的值
v = idField.get( o ) ; // o.id ;
System.out.println( v );
} catch (NoSuchFieldException e) {
System.out.println( "属性不存在" );
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
System.out.println( "不准访问" );
e.printStackTrace();
}
}
}
运行结果:
带有一个int类型参数和一个String类型参数的构造执行
100
1001
执行构造方法:
- Constructor<?> con = getConstructor( Class<?>... parameterTypes ) ;
- Object o = con.newInstance( Object... initargs ) ;或: Class<?> c = Student.class ;
- Object o = c.newInstance();
执行构造测试案例:
package ecut.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import ecut.reflect.entity.Student;
public class AccessConstructorTest3 {
public static void main(String[] args) throws Exception {
Class<?> c = Student.class ;
//从本类的 public 修饰的构造方法中,寻找与 parameterTypes 相匹配的那个构造方法
Constructor<?> con = c.getConstructor( String.class , int.class );
System.out.println( con );
//以 int 形式返回该 构造方法 ( Constructor ) 的修饰符
int mod = con.getModifiers();
String modifier = Modifier.toString( mod ) ;
System.out.println( "modifier : " + modifier );
// 获得构造方法的名称,返回带会包名.类名的形式
String name = con.getName();
System.out.println( "name : " + name );
// 获得参数类型列表
Class<?>[] paramTypes = con.getParameterTypes();
System.out.print( "parameter types : " );
for( int i = 0 , n = paramTypes.length ; i < n ; i++ ){
Class<?> t = paramTypes[ i ];
System.out.print( t.getName() + " " );
}
System.out.println();
// 获取所声明抛出的异常类型
Class<?>[] exceptionTypes = con.getExceptionTypes();
System.out.print( "exception types : " );
for( int i = 0 , n = exceptionTypes.length ; i < n ; i++ ){
Class<?> t = exceptionTypes[ i ];
System.out.print( t.getName() + " " );
}
System.out.println();
}
}
运行结果如下:
public ecut.reflect.entity.Student(java.lang.String,int) throws java.lang.RuntimeException,java.lang.NullPointerException
modifier : public
name : ecut.reflect.entity.Student
parameter types : java.lang.String int
exception types : java.lang.RuntimeException java.lang.NullPointerException
执行构造测试案例:
package ecut.reflect;
import java.lang.reflect.Constructor;
import ecut.reflect.entity.Student;
public class AccessConstructorTest4 {
public static void main(String[] args) throws Exception {
Class<?> c = Student.class ;
Constructor<?> con = null ;
Object o = null ;
con = c.getConstructor(); // 获取 public 修饰的无参构造
o = con.newInstance() ; // 调用无参构造创建对象
System.out.println( o );
// 根据参数类型列表寻找相应的由 public 修饰 构造方法
con = c.getConstructor( int.class , String.class );
o = con.newInstance( 9527 , "华安" );
System.out.println( o );
//获得由本类所声明的所有的构造方法组成的数组,这些构造方法的修饰符可以是 private 、默认 、protected 、public
con = c.getDeclaredConstructor( int.class ) ;
//让一个本来不能访问的对象可以被访问,可以写作 setAccessible( true )
con.setAccessible( true );
o = con.newInstance( 250 );
System.out.println( o );
}
}
运行结果如下:
无参构造执行
ecut.reflect.entity.Student@15db9742
带有一个int类型参数和一个String类型参数的构造执行
ecut.reflect.entity.Student@6d06d69c
带有一个int类型参数的构造执行
ecut.reflect.entity.Student@7852e922
执行构造测试案例:
package ecut.reflect;
import ecut.reflect.entity.Student;
/**
* 本类中并不会获取 Constructor 类型的对象,但是会通过 构造方法来创建对象
*/
public class AccessConstructorTest5 {
public static void main(String[] args) throws Exception {
Class<?> c = Student.class ;
//依赖于 相应类型中的 public修饰的 无参构造方法 (被绝大多数框架所采用 )等同于c.getConstructor().newInstance();
Object o = c.newInstance();
System.out.println( o );
}
}
运行结果如下:
无参构造执行
ecut.reflect.entity.Student@15db9742
执行方法:
- Class<?> c = Class.forName( "edu.ecut.entity.Student" );
- Constructor<?> con = c.getConstructor( int.class , String.class );
- Object s = con.newInstance( 100 , "张翠山" );
- 先找到指定的方法:Method eatMethod = c.getDeclaredMethod( "eat" , String.class ) ;
- 让方法执行起来:Object result = eatMethod.invoke( s , "藜蒿炒腊肉" ); // s.eat( "藜蒿炒腊肉" );
执行方法测试案例:
package ecut.reflect;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
public class AccessMethodTest3 {
public static void main(String[] args) throws Exception {
Class<?> c = HashMap.class ;
//获得由本类直接声明的指定名称、指定参数列表的方法对应的 Method 对象
Method m = c.getDeclaredMethod( "put" , Object.class , Object.class );
System.out.println( m );
//以 int 形式返回该 方法 ( Method ) 的修饰符
int mod = m.getModifiers();
String modifier = Modifier.toString( mod ) ;
System.out.println( "modifier : " + modifier );
//返回当前方法的返回类型 ( 是一个 Class 类型的对象 )
Class<?> returnType = m.getReturnType();
System.out.println( "return type : " + returnType.getName() );
//返回此 方法 的名称
String name = m.getName();
System.out.println( "name : " + name );
// 获得参数类型列表
Class<?>[] paramTypes = m.getParameterTypes();
System.out.print( "parameter types : " );
for( int i = 0 , n = paramTypes.length ; i < n ; i++ ){
Class<?> t = paramTypes[ i ];
System.out.print( t.getName() + " " );
}
System.out.println();
// 获取所声明抛出的异常类型
Class<?>[] exceptionTypes = m.getExceptionTypes();
System.out.print( "exception types : " );
for( int i = 0 , n = exceptionTypes.length ; i < n ; i++ ){
Class<?> t = exceptionTypes[ i ];
System.out.print( t.getName() + " " );
}
System.out.println();
}
}
运行结果如下:
public java.lang.Object java.util.HashMap.put(java.lang.Object,java.lang.Object)
modifier : public
return type : java.lang.Object
name : put
parameter types : java.lang.Object java.lang.Object
exception types :
InvokeMethod测试案例一:
package ecut.reflect; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class InvokeMethodTest1 { public static void main(String[] args) throws Exception { /*加载指定的类 ,3种方式获取Class (1)某个对象实例的getClass()方法,如new Student().getClass() (2)某个类名.class属性,Student.class (3)通过Class.forName("完整的类名")获取*/ Class<?> c = Class.forName( "ecut.reflect.entity.Student" ); Constructor<?> con = c.getConstructor( int.class , String.class ); //Student s = new Student( 100 , "张翠山" ); Object s = con.newInstance( 100 , "张翠山" ); //获得由本类或父类声明的由 public 修饰的、指定名称、指定参数列表的方法对应的 Method 对象 Method eatMethod = c.getDeclaredMethod( "eat" , String.class ) ; try { // s.eat( "藜蒿炒腊肉" ); // 被调用的方法是 eat ; 传入的参数是字符串 ; 调用 s 所引用的对象的 eat 方法 eatMethod.invoke( s , "藜蒿炒腊肉" ); } catch (IllegalAccessException e) { System.out.println( e.getMessage() ); //e.printStackTrace(); } catch (IllegalArgumentException e) { System.out.println( e.getMessage() ); //e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } }
运行结果如下:
带有一个int类型参数和一个String类型参数的构造执行
张翠山 吃 藜蒿炒腊肉
如果方法正常完成,则将该方法返回的值返回给调用者;如果该值为基本类型,则首先适当地将其包装在对象中。但是,如果该值的类型为一组基本类型,则数组元素不 被包装在对象中;换句话说,将返回基本类型的数组。如果底层方法返回类型为 void,则该调用返回 null。
InvokeMethod测试案例二:
package ecut.reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Method; public class InvokeMethodTest2 { public static void main(String[] args) throws Exception { /*加载指定的类 ,3种方式获取Class (1)某个对象实例的getClass()方法,如new Student().getClass() (2)某个类名.class属性,Student.class (3)通过Class.forName("完整的类名")获取*/ Class<?> c = Class.forName( "ecut.reflect.entity.Student" ); Constructor<?> con = c.getConstructor( int.class , String.class ); //Student s = new Student( 100 , "张翠山" ); Object s = con.newInstance( 100 , "张翠山" ); //获得由本类或父类声明的由 public 修饰的、指定名称、指定参数列表的方法对应的 Method 对象 Method eatMethod = c.getDeclaredMethod( "eat" , String.class ) ; // s.eat( "藜蒿炒腊肉" ); // 被调用的方法是 eat ; 传入的参数是字符串 ; 调用 s 所引用的对象的 eat 方法 Object result = eatMethod.invoke( s , "藜蒿炒腊肉" ); System.out.println( "result : " + result ); } }
运行结果如下:
带有一个int类型参数和一个String类型参数的构造执行 张翠山 吃 藜蒿炒腊肉 result : null
InvokeMethod测试案例三:
package ecut.reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Method; public class InvokeMethodTest3 { public static void main(String[] args) throws Exception { // 加载指定的类 Class<?> c = Class.forName( "ecut.reflect.entity.Student" ); Constructor<?> con = c.getConstructor( int.class , String.class ); //Student s = new Student( 100 , "张翠山" ); Object s = con.newInstance( 100 , "张翠山" ); Method getIdMethod = c.getDeclaredMethod( "getId" ) ; // int id = s.getId() ; // 被调用的方法是 getId ; 没有传入的参数 ; 调用 s 所引用的对象的 getId Object result = getIdMethod.invoke( s ); System.out.println( "result : " + result ); Method getNameMethod = c.getDeclaredMethod( "getName" ) ; // String name = s.getName() ; // 被调用的方法是 getName ; 没有传入的参数 ; 调用 s 所引用的对象的 getName result = getNameMethod.invoke( s ); System.out.println( "result : " + result ); } }
运行结果如下:
带有一个int类型参数和一个String类型参数的构造执行 result : 100 result : 张翠山
待解决问题
Proxy代理
参考博客链接
https://blog.csdn.net/sinat_38259539/article/details/71799078
转载请于明显处标明出处