铜陵做网站的,海报设计兼职平台,成都装修公司招聘,建筑人才招聘网站平台9.1 概念JAVA反射机制是在运行状态中#xff0c;对于任意一个类#xff0c;都能够知道这个类的所有属性和方法#xff1b;对于任意一个对象#xff0c;都能够调用它的任意方法和属性#xff1b;public、protected、private。OO(面向对象)#xff0c;private私有的#x…9.1 概念JAVA反射机制是在运行状态中对于任意一个类都能够知道这个类的所有属性和方法对于任意一个对象都能够调用它的任意方法和属性public、protected、private。OO(面向对象)private私有的不能访问。这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。**反射就是把java类中的各种成分映射成一个个的Java对象 例如一个类有成员变量、方法、构造方法、包等等信息利用反射技术可以对一个类进行解剖把各个组成部分映射成一个个对象。物理有个反射的概念通过镜子可以知道物体的存在。看到一个镜像或名字等知道物体在哪里。(其实一个类中这些成员方法、构造方法、在加入类中都有一个类来描述) 如图是类的正常加载过程反射的原理在与class对象。 熟悉一下加载的时候Class对象的由来是将class文件读入内存并为之创建一个Class对象。Student.java---Student.class 经过编译成了一个字节码文件。9.2 作用在日常的第三方应用开发过程中经常会遇到某个类的某个成员变量、方法或是属性是私有的或是只对系统应用开放这时候就可以利用Java的反射机制通过反射来获取所需的私有成员或是方法。当然也不是所有的都适合反射之前就遇到一个案例通过反射得到的结果与预期不符。阅读源码发现经过层层调用后在最终返回结果的地方对应用的权限进行了校验对于没有权限的应用返回值是没有意义的缺省值否则返回实际值起到保护用户的隐私目的。反射是框架设计的灵魂(使用的前提条件必须先得到代表的字节码的ClassClass类用于表示.class文件(字节码))9.2.1 反编译.class--.java9.2.2通过反射机制访问java对象的属性方法构造方法等User usernew User();--》形成的java文件--XXX.class将来赋值的时候不是User类是不是就报错了啊。存在紧耦合的状态我们做OO的目的就是高内聚、松耦合说白了就是模块内部实现特定功能模块与模块之间关联度不大。这种方式是编译时我们以后写程序更多的应该是运行时给值。9.3 反射机制的相关类与Java反射相关的类如下类名用途Class类代表类的实体在运行的Java应用程序中表示类和接口Field类代表类的成员变量(成员变量也称为类的属性)Method类代表类的方法Constructor类代表类的构造方法9.3.1 查看Class类在java中的apiClass 类的实例表示正在运行的 Java 应用程序中的类和接口。也就是jvm中有N多的实例每个类都有该Class对象。(包括基本数据类型) Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的defineClass 方法自动构造的。也就是这不需要我们自己去处理创建JVM已经帮我们创建好了。没有公共的构造方法方法共有64个太多了。下面用到哪个就详解哪个吧9.3.2 根据一个字符串得到一个类类名方法含义StringgetClass表示此对象运行时类的 Class 对象ClassforName具有指定名的类的 Class 对象包装类无属性Type参考代码String str今天是反射课程; Class clzstr.getClass();//得到当前正在运行的类; System.out.println(clz); Class clz2Integer.TYPE; //包装类型不同;包装类.Type System.out.println(clz2); System.out.println(Boolean.TYPE); System.out.println(Double.TYPE); System.out.println(Character.TYPE);9.3.3 获取Class对象的 三种方式ObjectgetClass任何数据类型(包含基本数据类型)都有一个静态的class属性这时候可以通过类名.属性访问.通过Class类的静态方法forName(string className路径)参考代码//1.使用第一种方式来获取User的Class对象;User usernew User(); //弄了一个User对象在内存里面;Class clz1user.getClass(); //对象.getClassSystem.out.println(clz1); //clz1:是什么类呢com.aaa.chapter07.User;路径类名;//2.使用第二种方式;Class clz2User.class; //类名.class 这个静态属性.System.out.println(clz2);//这时候我们是不是考虑一下之前讲的那个原理图。证明原理图里面正在运行的Class是一个。System.out.println(clz1clz2);//3.Class.forName(类路径方式)try {Class clz3Class.forName(com.aaa.chapter07.User);System.out.println(clz3);System.out.println(clz2clz3);} catch (ClassNotFoundException e) {e.printStackTrace();}提问最常用哪种一般用第三个。松耦合方式。9.3.4 通过反射来获取构造方法调用方法1.获取构造方法1).批量的方法 public Constructor[] getConstructors()所有公有的构造方法 public Constructor[] getDeclaredConstructors()获取所有的构造方法(包括私有、受保护、默认、公有)2).获取单个的方法并调用 public Constructor getConstructor(Class... parameterTypes):获取单个的公有的构造方法 public Constructor getDeclaredConstructor(Class... parameterTypes):获取某个构造方法可以是私有的或受保护、默认、公有例如调用构造方法 Constructor--newInstance(Object... initargs)package com.aaa.chapter07;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.sql.Connection;/** * Created by 张晨光 on 2020/3/10 10:24 */public class Constructors {public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {Class clzClass.forName(com.aaa.chapter07.User);//2.获取所有公共字段;// Field[] fields clz.getFields();// for(Field f:fields){// System.out.println(f);// }//2.获取所有共有 私有字段;// Field[] fields clz.getDeclaredFields();// for(Field f:fields){// System.out.println(f);// }Field fieldclz.getField(country);System.out.println(field);Object objclz.getConstructor().newInstance();field.set(obj,中国);User u(User)obj;System.out.println(u.getCountry());}}2、newInstance是 Constructor类的方法(管理构造函数的类) api的解释为 newInstance(Object... initargs) 使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例并用指定的初始化参数初始化该实例。 它的返回值是T类型所以newInstance是创建了一个构造方法的声明类的新实例对象。并为之调用package com.aaa.chapter07;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;/** * Created by 张晨光 on 2020/3/10 22:29 */public class InstanceDemo {public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {Class clzClass.forName(com.aaa.chapter07.User);//1.调用第一个默认构造方法没有参数创建实例之后再次使用setter赋值。// Constructor constructor clz.getConstructor();//AltEnter,// Object objconstructor.newInstance();// User user(User)obj;// user.setName(张老师);// System.out.println(obj);//2.调用第二个有3个参数的构造方法公共的构造方法注意里面参数的使用方式.// Constructor constructor2 clz.getConstructor(String.class,char.class,Integer.class);// Object obj2constructor2.newInstance(张晨光,男,18);//类似于之前的构造方法填充值;// User user2(User)obj2;// System.out.println(user2);//3.调用第三个私有构造方法这个构造方法我们说外部无法访问.Constructor declaredConstructor clz.getDeclaredConstructor(String.class);//设置私有构造方法可以访问强制(暴力)访问.declaredConstructor.setAccessible(true);Object objdeclaredConstructor.newInstance(登徒子);User user3(User)obj;System.out.println(user3);}}9.3.5 获取成员变量并调用获取成员变量并调用1.批量的1).Field[] getFields():获取所有的公有字段2).Field[] getDeclaredFields():获取所有字段包括私有、受保护、默认、公有2.获取单个的1).public Field getField(String fieldName):获取某个公有的字段2).public Field getDeclaredField(String fieldName):获取某个字段(可以是私有的)设置字段的值Field -- public void set(Object obj,Object value):参数说明1.obj:要设置的字段所在的对象2.value:要为字段设置的值