java学习笔记(三十三)反射
来源:互联网 发布:sql with nolock 编辑:程序博客网 时间:2024/06/05 15:20
1:类加载器
(1)什么是类的加载
当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,
初始化三步来实现对这个类进行初始化。
一个类在加载过程中的三部曲:1.加载 就是指将class文件读入内存,并为之创建一个Class对象. 任何类被使用时系统都会建立一个Class对象。2.连接验证 是否有正确的内部结构,并和其他类协调一致准备 负责为类的静态成员分配内存,并设置默认初始化值解析 将类的二进制数据中的符号引用替换为直接引用3.初始化 就是我们以前讲过的初始化步骤
(2)类的加载时机
2.1 创建类的实例2.2 访问类的静态变量,或者为静态变量赋值2.3 调用类的静态方法2.4 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象2.5 初始化某个类的子类2.6 直接使用java.exe命令来运行某个主类
(3)加载器分类
3.1 类加载起的作用?
负责将.class文件加载到内在中,并为之生成对应的Class对象。
3.2 类加载器的分类
Bootstrap ClassLoader 根类加载器也被称为引导类加载器,负责Java核心类的加载比如System,String等。在JDK中JRE的lib目录下rt.jar文件中Extension ClassLoader 扩展类加载器负责JRE的扩展目录中jar包的加载。在JDK中JRE的lib目录下ext目录Sysetm ClassLoader 系统类加载器负责在JVM启动时加载来自java命令的class文件
2:反射
Student.java–Student.class(字节码文件)–看成一个对象,这个对象就叫字节码文件对象–对应的类Class
什么是反射?
通过字节码文件对象去使用成员。
(1)获取字节码文件对象的三种方式: A:Object类的getClass()方法 B:数据类型的静态class属性 C:Class类的静态方法forName()练习:使用上述三种方式获取类的Class对象
public class ReflectDemo { public static void main(String[] args) throws ClassNotFoundException { //获取Person类对应的Class字节码文件对象 //A:Object类的getClass()方法 Person p1 = new Person(); Person p2 = new Person(); Class c1 = p1.getClass(); Class c2 = p2.getClass(); System.out.println(p1==p2);//false System.out.println(c1==c2);//true //每一个类会对应一个字节码文件对象,而这个字节码文件对象就是这个类的原型,每一个类有且仅有一个字节码文件对象 System.out.println("-------------"); //B:数据类型的静态class属性 Class c3 = Person.class; System.out.println(c2==c3); System.out.println("---------------"); //C:Class类的静态方法forName() 在这里所说的类名是全类名(带包名的类名) Class c4 = Class.forName("com.edu_01.Person"); System.out.println(c3==c4); }}
(2)反射的使用步骤
Class:
成员变量 Field
构造方法 Constructor
成员方法 Method
反射: class字节码文件对象 -- 去得到对应的成员对象 -- 通过该成员的对象调用方法使用 通过反射获取构造方法并使用
(3)成员方法
1.通过反射获取构造方法
public Constructor[] getConstructors() 获取公共的构造方法 public Constructor[] getDeclaredConstructors() 获取所有的构造方法(包括私有) public Constructor getConstructor(Class... parameterTypes) 根据构造参数获取公共的指定构造
2.通过反射获取构造方法并创建对象
public T newInstance(Object... initargs)
persion.java
public class Person { //创建三个成员变量 String name; public int age; private String address; //创建几个构造方法 public Person(){} Person(String name){ this.name = name; } protected Person(String name,int age){ this.name = name; this.age = age; } private Person(String name,int age,String address){ this.name = name; this.age = age; this.address = address; } //创建一个成员方法 public void method(){ System.out.println("method"); } void function(int price){ System.out.println(price); } private void show(String husband,String wife){ System.out.println(husband+"--"+wife); } @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", address=" + address + "]"; }}
ConstructorDemo.java
public class ConstructorDemo { public static void main(String[] args) throws Exception { //public Constructor[] getConstructors() 获取公共的构造方法 //获取Peroson类对应的字节码文件对象 Class c = Class.forName("com.edu_01.Person"); //获取Perosn类中对应的构造方法 Constructor[] cons = c.getConstructors(); //遍历所有获取到的构造方法 for (Constructor con : cons) { System.out.println(con);//public com.edu_01.Person() } System.out.println("----------------"); //public Constructor[] getDeclaredConstructors() 获取所有的构造方法(包括私有) Constructor[] cons2 = c.getDeclaredConstructors(); for (Constructor con : cons2) { System.out.println(con); } System.out.println("---------------"); //public Constructor getConstructor(Class... parameterTypes) 根据构造参数获取公共的指定构造 //获取Person类中的公共的无参数的构造方法 Constructor con = c.getConstructor(); System.out.println(con); //怎么通过我们刚才获取的无参构造创建对象 //public T newInstance(Object... initargs) Object obj = con.newInstance(); System.out.println(obj); System.out.println("-------------"); //获取Person类中的非公共的构造方法 //public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) Constructor con2 = c.getDeclaredConstructor(String.class,int.class,String.class); //获取构造器的时候,传入的什么参数,在调用获取到的这个构造方法对象的时候也就需要传入什么类型的参数 //取消这个构造器对象所对应的访问权限检测 con2.setAccessible(true); Object obj2 = con2.newInstance("陈奕迅",45,"香港"); System.out.println(obj2); System.out.println("-----------"); //获取被Protected修饰的构造方法 Constructor con3 = c.getDeclaredConstructor(String.class,int.class); //取消访问权限的检测 con3.setAccessible(true); Object obj3 = con3.newInstance("张学友",50); System.out.println(obj3); }}
3.通过反射获取成员变量并使用
public Field[] getFields()获取公有的成员变量 public Field[] getDeclaredFields()获取全部的成员变量,包括私有 public Field getDeclaredField(String name) 传入变量名称返回指定的成员变量对象,包括私有 public Field getField(String name)传入变量名称返回指定的成员变量对象,仅可获取共有的 public void set(Object obj,Object value)给一个对象的一个字段设置一个值
public class FieldDemo { public static void main(String[] args) throws Exception { //获取Perosn类对应的字节码文件对象 Class c = Class.forName("com.edu_01.Person"); //利用反射获取一个[Perosn对象 Constructor con = c.getConstructor(); Object obj = con.newInstance(); //获取所有公共的字段对象 //public Field[] getFields()获取公有的成员变量 Field[] fields = c.getFields(); for (Field field : fields) { System.out.println(field); } System.out.println("--------------"); //获取所有的字段对象,包括私有 //public Field[] getDeclaredFields()获取全部的成员变量,包括私有 Field[] fields2 = c.getDeclaredFields(); for (Field field : fields2) { System.out.println(field); } System.out.println("--------------"); //public Field getDeclaredField(String name) 传入变量名称返回指定的成员变量对象,包括私有 //获取String name;字段 Field f = c.getDeclaredField("name"); //使用f这个对象给一个Perosn对象设置姓名 //public void set(Object obj, Object value) /** * 参数1:需要设置的对象 * 参数2:需要给这个对象设置什么值 */ //取消访问修饰符的限制 f.setAccessible(true); f.set(obj, "谢娜"); System.out.println("--------------"); //public Field getField(String name)传入变量名称返回指定的成员变量对象,仅可获取公有的 //获取public int age; Field f2 = c.getField("age"); f2.set(obj, 30); System.out.println("---------------"); Field f3 = c.getDeclaredField("address"); //取消权限检测 f3.setAccessible(true); f3.set(obj, "湖南"); System.out.println(obj); }}
结果:
4.通过反射获取成员方法并使用
public Method[] getMethods()获取所有公共成员方法 public Method[] getDeclaredMethods()获取所有成员方法,包括私有 public Method getMethod(String name, Class<?>... parameterTypes)参数一:方法名 参数二:方法参数类型.class 获取指定的公共方法 public Method getDeclaredMethod(String name,Class<?>... parameterTypes)参数一:方法名 参数二:方法参数类型.class 获取指定的方法,包括私有 Object invoke(Object obj, Object... args) 让某一个对象使用这个方法,并且传入参数
public class MethodDemo { public static void main(String[] args) throws Exception { //1.获取Person类中所有的公有的成员方法 //创建Pwrson类对应的字节码文件对象 Class c = Class.forName("com.edu_01.Person"); //利用反射的方式创建一个Person对象 Constructor con = c.getConstructor(); Object obj = con.newInstance(); //public Method[] getMethods()获取所有公共成员方法,包括父类的公共的成员方法 Method[] methods = c.getMethods(); for (Method method : methods) { System.out.println(method); } System.out.println("---------------"); //获取Person类中的所有的成员方法 //public Method[] getDeclaredMethods()获取所有成员方法,包括私有,只能获取本类的所有的成员方法,不能获取父类的 Method[] methods2 = c.getDeclaredMethods(); for (Method method : methods2) { System.out.println(method); } System.out.println("---------------"); // public Method getMethod(String name, Class<?>... parameterTypes) //参数一:方法名 参数二:方法参数类型.class 获取指定的公共方法 //获取method()这个公有的成员方法 Method m = c.getMethod("method"); System.out.println(m); System.out.println("---------------"); //public Method getDeclaredMethod(String name,Class<?>... parameterTypes) //参数一:方法名 参数二:方法参数类型.class 获取指定的方法,包括私有 //需求获取method这个个方法 Method m2 = c.getDeclaredMethod("method"); System.out.println(m2); //使用m2这个成员方法的对象 //public Object invoke(Object obj,Object... args) /** * 参数1:执行m2这个方法的对象 * 参数2:执行m2这个方法的时候,需要传入的参数 */ m2.invoke(obj); System.out.println("-----------------"); //获取Person类中function方法 Method m3 = c.getDeclaredMethod("function", int.class); //取消权限检测 m3.setAccessible(true); m3.invoke(obj, 10); System.out.println("-------------------"); Method m4 = c.getDeclaredMethod("show", String.class,String.class); m4.setAccessible(true); m4.invoke(obj, "张杰","谢娜"); }}
结果:
练习:有一个ArrayList(Integer)的一个对象,我想在这个集合中添加一个字符串数据,如何实现呢?
public class ArrTest { public static void main(String[] args) throws Exception { //1.创建ArrayList类对应的字节码文件对象 ArrayList<Integer> arr = new ArrayList<>(); Class c = arr.getClass(); //2.通过字节码文件对象获取到add方法对象 Method addM = c.getDeclaredMethod("add", Object.class); //3.调用add方法的对象,给集合中添加字符串 addM.invoke(arr, "java"); addM.invoke(arr, "world"); System.out.println(arr); }}
结果:
阅读全文
0 0
- java学习笔记(三十三)反射
- java学习笔记(三十三)
- Java-反射(学习笔记)
- 软件工程视频学习笔记(三十三)
- 信息安全工程师 学习笔记(三十三)
- Java 反射学习笔记
- Java反射学习笔记
- java反射学习笔记
- Java反射学习笔记
- Java 反射学习笔记
- Java反射学习笔记
- Java学习笔记----反射
- Java反射学习笔记
- Java反射学习笔记
- Java反射学习笔记
- JAVA反射学习笔记
- 反射java学习笔记
- JAVA 反射学习笔记
- 使用设备检测(Device detection)的 JS 服务端渲染(SSR)
- Spring基础学习教程(简介)-01
- MongoDB账号安全权限管理
- 操作系统第三章 处理机调度与死锁
- python类方法 实例方法 静态方法
- java学习笔记(三十三)反射
- hdu5002:Tree (LCT)
- js特效-无缝轮播图,简单上手
- HP EVA4400/6400/8400/P6000数据恢复方法
- JAVA几种缓存技术介绍说明
- 关于Cookie的知识的总结
- 2017 Android暑期实习生面试经验谈
- 在中国想要投资比特币 (bitcoin) 该如何开始,如何申请钱包?
- CSS 实现隐藏滚动条同时又可以滚动