Java反射机制
Java反射机制
Java反射机制是在运行状态中,对于任意一个实体类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制。
Java的反射机制允许编程人员在对类未知的情况下,获取类相关信息的方式变得更加多样灵活,调用类中相应方法,是Java增加其灵活性与动态性的一种机制。
反射机制(Reflection)是Java提供的一项较为高级的功能,它提供了一种动态功能,而此功能的体现在于通过反射机制相关的API就可以获取任何Java类的包括属性、方法、构造器、修饰符等信息。元素不必在JⅧ运行时进行确定,反射可以使得它们在运行时动态地进行创建或调用。反射技术在中间件领域应用得较多。
功能
1、获得某个对象的属性
通过getClass()方法获得某个对象的类,然后实例化一个Field对象,接收类声明的属性,最后通过get()方法获得该属性的实例,注意,这里的属性必须为公有的,否则将会报illegalAeeessException的异常。
2、获得某个类的静态属性
首先根据类名获得该类,同获得某个对象的属性一样,通过实例化一个Field对象,接收该类声明的属性,不同的是,由于属性是静态的,所以直接从类中获取。
3、执行某对象的方法
同样要先获得对象的类,然后配置类的数组,并把它作搜索方法的条件。通过getMethod()方法,得到要执行的方法。执行该invoke方法,该方法中执行的是owner对象中带有参数args的方法。返回值是一个对象。
4、执行某个类的静态方法
基本的原理和“执行某个类的方法”相同,不同点在于method.invoke(null,args),这里的第一个参数是null,因为调用的是静态方法,所以不需要借助owner就能运行。
5、新建类的实例
我们利用执行带参数的构造函数的方法来新建一个实例。如果不需要参数,可以直接使用newoneClass.newlnstaneeO来实现嘲。同样要先得到要构造的实例的类,然后构造参数的类数组,构造器是通过getConstructor(argsClass)得到的,最后使用newlnstanee(args)方法新建一个实例。
反射是框架的灵魂
框架:半成品软件,可以在框架的基础上进行软件开发,简化代码。
反射:将类的各个组成部分封装为其他对象,反射机制。
反射的原理就是通过类的字节码文件(class文件)反向获取该类或者对象中的属性,因为是通过字节码获取,则需要JVM的操作。
动静态编译
静态编译:在编译期就确定类或者方法的属性,有点一次到位的意思。
动态编译:在运行期确定类或者方法的属性,好比什么时候用就什么时候编译。
静态编译是一次性编译,对于确定的代码是不能更改的,除非下线,更改,测试,再重新上线,显然这是不妥的。因此就需要动态编译,即在程序运行期间也可以进行相应的操作,一切操作方式都是灵活的,所以说反射对于程序是很重要的。
反射优缺点
优点:
- 可以在程序运行的过程中,操作这些对象。
- 可以解耦,提高程序的可扩展性。
缺点:
- 因为是JVM操作,所以对于性能来说会有所下降。
- 容易对程序源码造成一定的混乱。
反射图解
同一个字节码文件(*.class)在程序运行过程中,只会被加载一次。
反射获取方式
获取Class对象的方式:
- Class.forName(“全类名”):将字节码文件加载进内存,返回class对象,多用于配置文件中,将类名定义在配置文件中,读取文件并加载类。
- 类名.class:通过类名的属性class获取,多用于参数的构造。
- 对象.getClass():该方法定义在Object中,多用于对象的字节码获取。
public class ReflectDemo { public static void main(String[] args) throws ClassNotFoundException { // Class.forName(""); Class c1 = Class.forName("com.api.reflect.User"); System.out.println(c1); // 类名.class Class<User> c2 = User.class; System.out.println(c2); // .getClass User user = new User(); Class c3 = user.getClass(); System.out.println(c3); System.out.println(c1 == c2); System.out.println(c1 == c3); System.out.println(c2 == c3); } }
运行结果
分析:通过以上三种反射方式都可以获得实例对象,同样也证明三个对象是相同的,也就是对象只会被创建一次。
反射机制的相关类
Class类
- Class 类的实例对象表示正在运行的 Java 应用程序中的类和接口。也就是jvm中有很多的实例,每个类都有唯一的Class对象。
- Class 类没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机自动构造的。也就是说我们不需要创建,JVM已经帮我们创建了。
- Class 对象用于提供类本身的信息,比如有几种构造方法, 有多少属性,有哪些普通方法。
获得类相关的方法
获得类中属性相关的方法
获得类中注解相关的方法
获得类中构造器相关的方法
获得类中方法相关的方法
类中其他重要的方法
Field类
Field代表类的成员变量(成员变量也称为类的属性)
Method类
Method代表类的方法
Constructor类
Constructor代表类的构造方法
Demo
被反射类Book.java
public class Book{ private final static String TAG = "BookTag"; private String name; private String author; @Override public String toString() { return "Book{" + "name='" + name + '\'' + ", author='" + author + '\'' + '}'; } public Book() { } private Book(String name, String author) { this.name = name; this.author = author; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } private String declaredMethod(int index) { String string = null; switch (index) { case 0: string = "I am declaredMethod 1 !"; break; case 1: string = "I am declaredMethod 2 !"; break; default: string = "I am declaredMethod 1 !"; } return string; } }
反射逻辑封装在ReflectClass.java
public class ReflectClass { private final static String TAG = "peter.log.ReflectClass"; // 创建对象 public static void reflectNewInstance() { try { Class<?> classBook = Class.forName("com.android.peter.reflectdemo.Book"); Object objectBook = classBook.newInstance(); Book book = (Book) objectBook; book.setName("挪威的森林"); book.setAuthor("村上春树"); Log.d(TAG,"reflectNewInstance book = " + book.toString()); } catch (Exception ex) { ex.printStackTrace(); } } // 反射私有的构造方法 public static void reflectPrivateConstructor() { try { Class<?> classBook = Class.forName("com.android.peter.reflectdemo.Book"); Constructor<?> declaredConstructorBook = classBook.getDeclaredConstructor(String.class,String.class); declaredConstructorBook.setAccessible(true); Object objectBook = declaredConstructorBook.newInstance("Android开发艺术探索","任玉刚"); Book book = (Book) objectBook; Log.d(TAG,"reflectPrivateConstructor book = " + book.toString()); } catch (Exception ex) { ex.printStackTrace(); } } // 反射私有属性 public static void reflectPrivateField() { try { Class<?> classBook = Class.forName("com.android.peter.reflectdemo.Book"); Object objectBook = classBook.newInstance(); Field fieldTag = classBook.getDeclaredField("TAG"); fieldTag.setAccessible(true); String tag = (String) fieldTag.get(objectBook); Log.d(TAG,"reflectPrivateField tag = " + tag); } catch (Exception ex) { ex.printStackTrace(); } } // 反射私有方法 public static void reflectPrivateMethod() { try { Class<?> classBook = Class.forName("com.android.peter.reflectdemo.Book"); Method methodBook = classBook.getDeclaredMethod("declaredMethod",int.class); methodBook.setAccessible(true); Object objectBook = classBook.newInstance(); String string = (String) methodBook.invoke(objectBook,0); Log.d(TAG,"reflectPrivateMethod string = " + string); } catch (Exception ex) { ex.printStackTrace(); } } // 获得系统Zenmode值 public static int getZenMode() { int zenMode = -1; try { Class<?> cServiceManager = Class.forName("android.os.ServiceManager"); Method mGetService = cServiceManager.getMethod("getService", String.class); Object oNotificationManagerService = mGetService.invoke(null, Context.NOTIFICATION_SERVICE); Class<?> cINotificationManagerStub = Class.forName("android.app.INotificationManager$Stub"); Method mAsInterface = cINotificationManagerStub.getMethod("asInterface",IBinder.class); Object oINotificationManager = mAsInterface.invoke(null,oNotificationManagerService); Method mGetZenMode = cINotificationManagerStub.getMethod("getZenMode"); zenMode = (int) mGetZenMode.invoke(oINotificationManager); } catch (Exception ex) { ex.printStackTrace(); } return zenMode; } // 关闭手机 public static void shutDown() { try { Class<?> cServiceManager = Class.forName("android.os.ServiceManager"); Method mGetService = cServiceManager.getMethod("getService",String.class); Object oPowerManagerService = mGetService.invoke(null,Context.POWER_SERVICE); Class<?> cIPowerManagerStub = Class.forName("android.os.IPowerManager$Stub"); Method mShutdown = cIPowerManagerStub.getMethod("shutdown",boolean.class,String.class,boolean.class); Method mAsInterface = cIPowerManagerStub.getMethod("asInterface",IBinder.class); Object oIPowerManager = mAsInterface.invoke(null,oPowerManagerService); mShutdown.invoke(oIPowerManager,true,null,true); } catch (Exception ex) { ex.printStackTrace(); } } public static void shutdownOrReboot(final boolean shutdown, final boolean confirm) { try { Class<?> ServiceManager = Class.forName("android.os.ServiceManager"); // 获得ServiceManager的getService方法 Method getService = ServiceManager.getMethod("getService", java.lang.String.class); // 调用getService获取RemoteService Object oRemoteService = getService.invoke(null, Context.POWER_SERVICE); // 获得IPowerManager.Stub类 Class<?> cStub = Class.forName("android.os.IPowerManager$Stub"); // 获得asInterface方法 Method asInterface = cStub.getMethod("asInterface", android.os.IBinder.class); // 调用asInterface方法获取IPowerManager对象 Object oIPowerManager = asInterface.invoke(null, oRemoteService); if (shutdown) { // 获得shutdown()方法 Method shutdownMethod = oIPowerManager.getClass().getMethod( "shutdown", boolean.class, String.class, boolean.class); // 调用shutdown()方法 shutdownMethod.invoke(oIPowerManager, confirm, null, false); } else { // 获得reboot()方法 Method rebootMethod = oIPowerManager.getClass().getMethod("reboot", boolean.class, String.class, boolean.class); // 调用reboot()方法 rebootMethod.invoke(oIPowerManager, confirm, null, false); } } catch (Exception e) { e.printStackTrace(); } } }
调用相应反射逻辑方法
try { // 创建对象 ReflectClass.reflectNewInstance(); // 反射私有的构造方法 ReflectClass.reflectPrivateConstructor(); // 反射私有属性 ReflectClass.reflectPrivateField(); // 反射私有方法 ReflectClass.reflectPrivateMethod(); } catch (Exception ex) { ex.printStackTrace(); } Log.d(TAG," zenmode = " + ReflectClass.getZenMode());
Log输出结果如下:
08-27 15:11:37.999 11987-11987/com.android.peter.reflectdemo D/peter.log.ReflectClass: reflectNewInstance book = Book{name='Android进阶之光', author='刘望舒'} 08-27 15:11:38.000 11987-11987/com.android.peter.reflectdemo D/peter.log.ReflectClass: reflectPrivateConstructor book = Book{name='Android开发艺术探索', author='任玉刚'} 08-27 15:11:38.000 11987-11987/com.android.peter.reflectdemo D/peter.log.ReflectClass: reflectPrivateField tag = BookTag 08-27 15:11:38.000 11987-11987/com.android.peter.reflectdemo D/peter.log.ReflectClass: reflectPrivateMethod string = I am declaredMethod 1 ! 08-27 15:11:38.004 11987-11987/com.android.peter.reflectdemo D/peter.log.ReflectDemo: zenmode = 0
参考文章:
https://baike.baidu.com/item/JAVA%E5%8F%8D%E5%B0%84%E6%9C%BA%E5%88%B6/6015990?fr=aladdin
https://www.jianshu.com/p/9be58ee20dee
https://www.cnblogs.com/fenjyang/p/11512045.html
- java反射机制
- java反射机制
- JAVA反射机制
- Java反射机制的一些问题
- 使用java反射机制实现java的深拷贝
- JAVA反射机制
- Java反射机制剖析(二)-功能以及举例
- JAVA反射机制
- Java反射机制简单示例
- Java反射机制
- Java反射机制深入详解
- Java反射机制深入研究
- Java反射机制深入研究
- Java反射机制剖析(一)-定义和API
- java反射机制
- 【Java】Java反射机制及Spring BeanWrapper
- java反射机制详解 及 Method.invoke解释 getMethod
- Java反射机制详解
- java反射机制(一)
- Java反射机制(未完成,还缺最后一个)