第八章:反射
一. 反射的基本概念
1.什么是反射??
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
2.反射机制有什么用??
通过java语言中的反射机制可以操作字节码文件。 有点类似于黑客。(可以读和修改字节码文件) 通过反射机制可以操作代码片段。(class文件)
3.反射机制的相关类在哪个包下??
java.lang.reflect.*
4.反射机制相关的重要的类有哪些??
java.lang.Class :代表字节码文件,代表整个类。 java.lang.reflect.Method :代表字节码中的方法,代表类中的方法 java.lang.reflect.Constructor :代表字节码中的构造方法字节码,代表类中的构造方法。 java.lang.reflect.Field :代表字节码中的属性字节码,代表类中的成员变量(静态变量,成员变量)
5.在Java中获取Class的三种方式
第一种:Class c = Class.forName(“完整类名带包名”); 第二种:Class c = 引用.getClass(); 得到的是这个引用数据类型的class字节码文件。 第三种: Class c = 数据类型.class;
public class ReflectTest01 {
public static void main ( String[ ] args) {
Class c1 = null;
Class c2 = null;
try {
c1 = Class. forName ( "java.lang.String" ) ;
c2 = Class. forName ( "java.util.Date" ) ;
Class c3 = Class. forName ( "java.lang.Integer" ) ;
Class c4 = Class. forName ( "java.lang.System" ) ;
} catch ( ClassNotFoundException e) {
e. printStackTrace ( ) ;
}
String s = "abc" ;
Class x = s. getClass ( ) ;
System. out. println ( x == c1) ;
Date time = new Date ( ) ;
Class y = time. getClass ( ) ;
System. out. println ( y == c2) ;
Class z = String. class ;
Class k = Date. class ;
Class f = int . class ;
Class e = double . class ;
System. out. println ( x == z) ;
}
}
6.如何通过反射机制创建对象。
获取Class文件后,可以调用无参构造方法来实例化对象。
Class c = Class.forName("java.lang.Date")
Object obj = c.newInstance();
一定要注意:newInstance底层调用的是该类型的无参构造方法,如果没有这个无参数构
造方法,会出现异常。
public class ReflectTest02 {
public static void main ( String[ ] args) {
try {
Class< ? > c = Class. forName ( "进阶.反射08.bean.User" ) ;
Object obj = c. newInstance ( ) ;
System. out. println ( obj) ;
} catch ( ClassNotFoundException e) {
e. printStackTrace ( ) ;
} catch ( IllegalAccessException e) {
e. printStackTrace ( ) ;
} catch ( InstantiationException e) {
e. printStackTrace ( ) ;
}
}
}
7.反射机制和配置文件的使用
public class ReflectTest03 {
public static void main ( String[ ] args) throws Exception{
FileReader reader = new FileReader ( "javase/classinfo2.properties" ) ;
Properties pro = new Properties ( ) ;
pro. load ( reader) ;
reader. close ( ) ;
String calssName = pro. getProperty ( "calssName" ) ;
Class c = Class. forName ( calssName) ;
Object obj = c. newInstance ( ) ;
System. out. println ( obj) ;
}
}
二. 反射中最重要的类
1. Class类中相关方法
Class代表类的实体,在运行的Java应用程序中表示类和接口。在这个类中提供了很多有用的方法,这里对他们简单的分类介绍。
方法 用途 forName(String className) 根据类名返回类的对象 getName() 获得类的完整路径名字 newInstance() 创建类的实例 getSimpleName() 获得类的名字 getSuperclass() 获得当前类继承的父类的名字 getInterfaces() 获得当前类实现的类或是接口 getClassLoader() 获得类的加载器
方法 用途 getField(String name) 获得某个公有的属性对象 getFields() 获得所有公有的属性对象 getDeclaredField(String name) 获得某个属性对象 getDeclaredFields() 获得所有属性对象
方法 用途 getAnnotation(Class annotationClass) 返回该类中与参数类型匹配的公有注解对象 getAnnotations() 返回该类所有的公有注解对象 getDeclaredAnnotation(Class annotationClass) 返回该类中与参数类型匹配的所有注解对象 getDeclaredAnnotations() 返回该类所有的注解对象
获得类中构造器(Constructor)相关的方法
方法 用途 getConstructor(Class…<?> parameterTypes) 获得该类中与参数类型匹配的公有构造方法 getAnnotations() 获得该类的所有公有构造方法 getDeclaredConstructor(Class…<?> parameterTypes) 获得该类中与参数类型匹配的构造方法 getDeclaredConstructors() 获得该类所有构造方法
方法 用途 getMethod(String name, Class…<?> parameterTypes) 获得该类某个公有的方法 getMethods() 获得该类所有公有的方法 getDeclaredMethod(String name, Class…<?> parameterTypes) 获得该类某个方法 getDeclaredMethods() 获得该类所有方法
方法 用途 isAnnotation() 如果是注解类型则返回true isAnnotationPresent(Class<? extends Annotation> annotationClass) 如果是指定类型注解类型则返回true isAnonymousClass() 如果是匿名类则返回true getDeclaredMethods() 获得该类所有方法 isArray() 如果是一个数组类则返回true isEnum() 如果是枚举类则返回true isInstance(Object obj) 如果obj是该类的实例则返回true isLocalClass() 如果是局部类则返回true isMemberClass() 如果是内部类则返回true
2. Filed 类中相关方法
Field代表类的成员变量(成员变量也称为类的属性)。
public class ReflectTest05 {
public static void main ( String[ ] args) throws Exception{
Class studentClass = Class. forName ( "进阶.反射08.bean.Student" ) ;
System. out. println ( "完整的类名: " + studentClass. getName ( ) ) ;
System. out. println ( "简易的名字: " + studentClass. getSimpleName ( ) ) ;
Field[ ] fields = studentClass. getFields ( ) ;
Field f = fields[ 0 ] ;
String firstName = f. getName ( ) ;
System. out. println ( firstName) ;
System. out. println ( "================" ) ;
Field[ ] fs = studentClass. getDeclaredFields ( ) ;
for ( Field field: fs) {
System. out. println ( field. getModifiers ( ) ) ;
System. out. println ( Modifier. toString ( field. getModifiers ( ) ) ) ;
Class fieldType = field. getType ( ) ;
System. out. println ( fieldType. getSimpleName ( ) ) ;
System. out. println ( field. getName ( ) ) ;
}
}
}
public class ReflectTest06 {
public static void main ( String[ ] args) throws Exception{
Class studentClass = Class. forName ( "进阶.反射08.bean.Student" ) ;
StringBuilder s = new StringBuilder ( ) ;
s. append ( Modifier. toString ( studentClass. getModifiers ( ) ) + " class " + studentClass. getSimpleName ( ) + "{" + "\n" ) ;
Field[ ] fields = studentClass. getDeclaredFields ( ) ;
for ( Field field: fields) {
s. append ( "\t" + Modifier. toString ( field. getModifiers ( ) ) + " " +
field. getType ( ) . getSimpleName ( ) + " " +
field. getName ( ) + ";" + "\n"
) ;
}
s. append ( "}" ) ;
System. out. println ( s) ;
}
}
public class ReflectTest07 {
public static void main ( String[ ] args) throws Exception{
Student s = new Student ( ) ;
s. no = 111 ;
System. out. println ( s. no) ;
Class studentClass = Class. forName ( "进阶.反射08.bean.Student" ) ;
Object obj = studentClass. newInstance ( ) ;
Field noField = studentClass. getField ( "no" ) ;
noField. set ( obj, 2222 ) ;
System. out. println ( noField. get ( obj) ) ;
Field nameField = studentClass. getDeclaredField ( "name" ) ;
nameField. setAccessible ( true ) ;
nameField. set ( obj, "jackson" ) ;
System. out. println ( nameField. get ( obj) ) ;
}
}
3. Method类
public class ReflectTest08 {
public static void main ( String[ ] args) throws Exception {
Class userServiceClass = Class. forName ( "进阶.反射08.service.UserService" ) ;
Method[ ] methods = userServiceClass. getDeclaredMethods ( ) ;
for ( Method method: methods) {
System. out. println ( method. getName ( ) ) ;
System. out. println ( method. getReturnType ( ) ) ;
System. out. println ( Modifier. toString ( method. getModifiers ( ) ) ) ;
Class[ ] parameterTypes = method. getParameterTypes ( ) ;
for ( Class parameterType : parameterTypes) {
System. out. println ( parameterType. getSimpleName ( ) ) ;
}
System. out. println ( "=================" ) ;
}
}
}
public class ReflectTest09 {
public static void main ( String[ ] args) throws Exception{
StringBuilder s = new StringBuilder ( ) ;
Class userServiceClass = Class. forName ( "java.lang.String" ) ;
s. append ( Modifier. toString ( userServiceClass. getModifiers ( ) ) + " " + "class" + " " + userServiceClass. getSimpleName ( ) + "{" + "\n" ) ;
Method[ ] methods = userServiceClass. getDeclaredMethods ( ) ;
for ( Method method: methods) {
s. append ( "\t" ) ;
s. append ( Modifier. toString ( method. getModifiers ( ) ) ) ;
s. append ( " " ) ;
s. append ( method. getReturnType ( ) ) ;
s. append ( " " ) ;
s. append ( method. getName ( ) ) ;
s. append ( "(" ) ;
Class[ ] parameterTypes = method. getParameterTypes ( ) ;
for ( Class parameterType : parameterTypes) {
s. append ( parameterType. getSimpleName ( ) ) ;
s. append ( "," ) ;
}
s. deleteCharAt ( s. length ( ) - 1 ) ;
s. append ( "){}\n" ) ;
}
s. append ( "}" ) ;
System. out. println ( s) ;
}
}
public class ReflectTest10 {
public static void main ( String[ ] args) throws Exception{
UserService userService = new UserService ( ) ;
boolean loginSuccess = userService. login ( "admin" , "123" ) ;
System. out. println ( loginSuccess? "登陆成功" : "登录失败" ) ;
Class userServiceClass = Class. forName ( "进阶.反射08.service.UserService" ) ;
Object obj = userServiceClass. newInstance ( ) ;
Method loginMethod = userServiceClass. getDeclaredMethod ( "login" , String. class , String. class ) ;
Object retValue = loginMethod. invoke ( obj, "admin" , "123" ) ;
System. out. println ( retValue) ;
}
}
4.Constructor类
public class ReflectTest12 {
public static void main ( String[ ] args) throws Exception{
Vip v1 = new Vip ( ) ;
Vip v2 = new Vip ( 110 , "zhangsan" , "2020-10-11" , true ) ;
Class c = Class. forName ( "进阶.反射08.bean.Vip" ) ;
Object obj1 = c. newInstance ( ) ;
System. out. println ( obj1) ;
Constructor con = c. getDeclaredConstructor ( int . class , String. class , String. class , boolean . class ) ;
Object obj2 = con. newInstance ( 110 , "jackcon" , "1999-10-10" , true ) ;
System. out. println ( obj2) ;
}
}
public class ReflectTest13 {
public static void main ( String[ ] args) throws Exception {
Class stringClass = Class. forName ( "java.lang.String" ) ;
Class superClass = stringClass. getSuperclass ( ) ;
System. out. println ( superClass. getSimpleName ( ) ) ;
Class[ ] interfaces = stringClass. getInterfaces ( ) ;
for ( Class in : interfaces) {
System. out. println ( in. getSimpleName ( ) ) ;
}
}
}
三. 添加内容(如何获取绝对路径)
public class AboutPath {
public static void main ( String[ ] args) throws Exception{
String path = Thread. currentThread ( ) . getContextClassLoader ( )
. getResource ( "classinfo2.properties" ) . getPath ( ) ;
String path2 = Thread. currentThread ( ) . getContextClassLoader ( )
. getResource ( "进阶/反射08/笔记" ) . getPath ( ) ;
System. out. println ( path2) ;
}
}
public class IoPropertiesTest01 {
public static void main ( String[ ] args) throws Exception{
InputStream in = Thread. currentThread ( ) . getContextClassLoader ( ) . getResourceAsStream ( "classinfo2.properties" ) ;
Properties pro = new Properties ( ) ;
pro. load ( in) ;
String s = pro. getProperty ( "className" ) ;
System. out. println ( s) ;
}
}