reflect反射
反射是发生在程序运行期的行为
Class<?> arr = 类的对象
定义:
反射就是把 java类中的各种成分 映射成一个个的Java对象
获取Class对象的三种方式
1. 类名.class
2. 对象.getClass( )
3. Class.forName( ) (包名+类名 || 权限定名)
- 类名.class 任何数据类型(包括基本数据类型)都有一个“静态”的 class属性
- 对象.getClass( ) Object → getClass();
- Class.forName(包名+类名||权限定名) 注意( )里需要" " 通过 Class类的静态方法:forName(String className)(常用) 基本 都是使用这种方法
System.out.println(Integer.class);
//结果: class java.lang.Integer
Class<?> arr = String.class;
System.out.println(arr) ;
System.out.println(arr.getClass());
System.out.println(Class.forName("java.lang.String"));
//结果: class java.lang.String
//class java.lang.Class
//class java.lang.String
反射的作用
- 生成静态代理
- 在运行时 判断对象所属的类
- 在运行时 判断类所具有的成员变量和方法
- 在运行时 构造类的对象
- 在运行时 调用对象的方法
描述:
1.在一个类加载到内存时就会存在这个类型唯一的Class对象(方 法,属性,构造器…)
2.在创建类型的对象的时候,获取的是类型的Class对象的一个镜 像||复制体
3.如果能够拿到一个类型的Class对象,就可以操作这个类
4.通过子类的Class对象获取父类的Class对象 .getSuperclass()
5.基本数据类型的Class对象 -->本身
输出 int.class = = Integer.TYPE 结果 true//int
反射常用方法
1. 一般方法
类调用
getInterface( )
参数: 无
返回值: Class<?>[] 类接口的 数组
描述: 当前对象所表示的类或接口实现的接口
测试代码:
Class[] array = InputStream.class.getInterfaces();
System.out.println(Arrays.toString(array));
//[interface java.io.Closeable]
getModifiers( )
参数: 无
返回值: int
描述: 返回此类或接口以整数编码的 Java 语言修饰符。
延伸Modifier.toString( )
参数: int
返回值: String 返回此修饰符的小写名称。
测试代码:
System.out.println(arr.getModifiers());
System.out.println(Modifier.toString(arr.getModifiers()));
//结果 17
// public final
getName( )
参数: 无
返回值: String
描述: 以 String 的形式返回此 Class 对象所表示的实体名称
Class<?> arr = String.class;
System.out.println(arr.getName());
//结果java.lang.String
getModifiers( )
参数: 无
返回值: String
描述: 返回源代码中给出的底层类的简称。
测试代码:
Class<?> arr = Integer.class;
打印arr.getSimpleName()
结果 Integer
isPrimitive()
参数: 无
返回值: boolean
描述: 判定指定的 Class 对象是否表示一个基本类型。
测试代码:
System.out.println(int.class.isPrimitive()) ;
System.out.println(Integer.TYPE.isPrimitive()) ;
//结果 true true
2.获取字段Field
英文 field字段 declared 公开的
类操作字段
getField( )
参数: (String , name)
返回值: Field
描述: 返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定 公共成员字段。
getDeclaredField()
参数: (String , name)
返回值: Field
描述: 返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指 定已声明字段。
getFields()
参数: 无
返回值: Field[ ]
描述: 返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表 示的类或接口的所有可访问公共字段。
getDeclaredFields()
参数: 无
返回值: Field[ ]
描述: 返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或 接口所声明的所有字段。
3.操作字段Field
Field 类中方法
set( )设置值
参数: (Object obj, Object value)
返回值: void
描述: 将指定对象变量上此 Field 对象表示的字段设置为指定的新值。
get( )获取值
参数: (Object obj)
返回值: Object
描述: 返回指定对象上此 Field 表示的字段的值。
setAccessible( )
参数: (boolean boolean)
返回值: 无
描述: true->放开权限 false->关闭权限 不能通过私有的构造器创建对象
4.获取方法Method
类获取方法
getMethod( )
参数: (String name, Class<?>… parameterTypes)
返回值: Method
描述: 返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定 公共成员方法。
getDeclaredMethod()
参数: (String name, Class<?>… parameterTypes)
返回值: Method
描述: 返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。
getMethods()
参数: 无
返回值: Method[ ]
描述: 返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所 表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继 承的那些的类或接口)的公共 member 方法。
getDeclaredMethods()
参数: 无
返回值: Method[ ]
描述: 返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或 接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法, 但不包括继承的方法。
5.执行方法Method
Method类中的
invoke( )
参数: (Object obj, Object… args)
返回值: Object
描述: 对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。
6.获取类中构造器:Constructor
类获取
getConstructor( )
参数: (Class<?>… parameterTypes)
返回值: Constructor
描述: 返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。
getDeclaredConstructor( )
参数: (Class<?>… parameterTypes)
返回值: Constructor
描述: 返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法。
getConstructors( )
参数: 无
返回值: Constructor<?>[ ]
描述: 返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法。
getDeclaredConstructors( )
参数: 无
返回值: Constructor<?>[ ]
描述: 返回 Constructor 对象的一个数组,这些对象反映此 Class 对象表示的类声明的所有构造方法。
7.通过反射创建对象:
Constructor类中方法
newInstance( )
参数: (Object… initargs)
返回值: T
描述: 使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例。
不能通过私有的构造器创建对象
setAccessible(boolean)设置权限,true->放开权限 false->关闭权限
Class类中newInstance( )默认调用空构造
延伸java中new和 instance的区别
newInstance():弱类型,效率低,只能调用无参构造
new():强类型,高效率,能调用任何public构造器
类的加载方式不同
在执行Class.forName("a.class.Name")时,JVM会在classpath中去找对应的类 并加载,这时JVM会执行该类的静态代码段。
在使用newInstance( )方法的 时候,必须保证这个类已经加载并且已经连 接了,而这可以通过Class的静态方法forName( )来完成的。
使用关键字new创建一个类的时候,这个类可以没有被加载,一般也不 需要该类在classpath中设定,但可能需要通过classloader(类加载器)来加载。