java基础(四)
来源:互联网 发布:java md5 32加密算法 编辑:程序博客网 时间:2024/05/16 06:00
java类加载器和反射机制
类加载器
- 负责将.class文件加载到内在中,并为之生成对应的Class对象。
类加载器的组成
- Bootstrap ClassLoader 根类加载器
- Extension ClassLoader 扩展类加载器
- Sysetm ClassLoader 系统类加载器
类加载器的作用
- Bootstrap ClassLoader 根类加载器
- 也被称为引导类加载器,负责Java核心类的加载比如System,String等。在JDK中JRE的lib目录下rt.jar文件中
- Extension ClassLoader 扩展类加载器
- 负责JRE的扩展目录中jar包的加载。在JDK中JRE的lib目录下ext目录
- Sysetm ClassLoader 系统类加载器
- 负责在JVM启动时加载来自java命令的class文件,以及classpath环境变量所指定的jar包和类路径
反射机制
- JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
反射的一些常用方法:
创建对象
newInstance()
获取构造方法
getConstructors
getDeclaredConstructors
获取所有成员
getFields,getDeclaredFields
获取单个成员
getField,getDeclaredField
修改成员的值
set(Object obj,Object value)
获取所有方法
getMethods
getDeclaredMethods
获取单个方法
getMethod
getDeclaredMethod
暴力访问(private修饰)
method.setAccessible(true);
但想要这样使用,首必须得到class文件对象,就是得到Class类的对象,而得到Class类的对象有几种方式:
// 方式1(基本不用)
Person p = new Person();
Class c = p.getClass();
// 方式2(实际开发不怎么用)
Class c3 = Person.class;
// 方式3是通过字符串加载,而不是一个具体的类名。这样可以把字符串配置到配置文件中(比如:要求一个APP支持微信支付,支付宝支付,银联支付,以后甚至更多的支付方式,这样可以通过一个接口定义支付过程的几种状态,通过反射机制和面向对象的特性把配置文件配置此接口的实现类,以达到不修改任何代码下更换支付方式)
Class c4 = Class.forName(“cn.itcast_01.Person”);
反射获取成员变量并赋值
public class ReflectDemo { public static void main(String[] args) throws Exception { // 获取字节码文件对象 Class c = Class.forName("cn.itcast_01.Person"); // 获取所有的成员变量 // Field[] fields = c.getFields(); // Field[] fields = c.getDeclaredFields(); // for (Field field : fields) { // System.out.println(field); // } /* * Person p = new Person(); p.address = "北京"; System.out.println(p); */ // 通过无参构造方法创建对象 Constructor con = c.getConstructor(); Object obj = con.newInstance(); System.out.println(obj); // 获取单个的成员变量 // 获取address并对其赋值 Field addressField = c.getField("address"); // public void set(Object obj,Object value) // 将指定对象变量上此 Field 对象表示的字段设置为指定的新值。 addressField.set(obj, "北京"); // 给obj对象的addressField字段设置值为"北京" System.out.println(obj); // 获取name并对其赋值 // NoSuchFieldException Field nameField = c.getDeclaredField("name"); // IllegalAccessException nameField.setAccessible(true);// 值为true则指示反射的对象在使用时应该取消Java语言访问检查。 nameField.set(obj, "李四"); System.out.println(obj); // 获取age并对其赋值 Field ageField = c.getDeclaredField("age"); ageField.setAccessible(true); ageField.set(obj, 27); System.out.println(obj); }}
反射获取成员方法并赋值
public class ReflectDemo { public static void main(String[] args) throws Exception { // 获取字节码文件对象 Class c = Class.forName("cn.itcast_01.Person"); // 获取所有的方法 // Method[] methods = c.getMethods(); // 获取自己的包括父亲的公共方法 // Method[] methods = c.getDeclaredMethods(); // 获取自己的所有的方法 // for (Method method : methods) { // System.out.println(method); // } Constructor con = c.getConstructor(); Object obj = con.newInstance(); /* * Person p = new Person(); p.show(); */ // 获取单个方法并使用 // public void show() // public Method getMethod(String name,Class<?>... parameterTypes) // 第一个参数表示的方法名,第二个参数表示的是方法的参数的class类型 Method m1 = c.getMethod("show"); // obj.m1(); // 错误 // public Object invoke(Object obj,Object... args) // 返回值是Object接收,第一个参数表示对象是谁,第二参数表示调用该方法的实际参数 m1.invoke(obj); // 调用obj对象的m1方法 System.out.println("----------"); // public void method(String s) Method m2 = c.getMethod("method", String.class); m2.invoke(obj, "hello"); System.out.println("----------"); // public String getString(String s, int i) Method m3 = c.getMethod("getString", String.class, int.class); Object objString = m3.invoke(obj, "hello", 100); System.out.println(objString); // String s = (String)m3.invoke(obj, "hello",100); // System.out.println(s); System.out.println("----------"); // private void function() Method m4 = c.getDeclaredMethod("function"); m4.setAccessible(true); m4.invoke(obj); }}
ArrayList的一个对象,在这个集合中添加一个字符串数据:
public class ArrayListDemo { public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { // 创建集合对象 ArrayList<Integer> array = new ArrayList<Integer>(); // array.add("hello"); // array.add(10); Class c = array.getClass(); // 集合ArrayList的class文件对象 Method m = c.getMethod("add", Object.class); m.invoke(array, "hello"); // 调用array的add方法,传入的值是hello m.invoke(array, "world"); m.invoke(array, "java"); System.out.println(array); }}
总结:
通过反射可以修改java底层代码以达到我们所需要的功能,当然还有更深入知识需要去了解,去研究。
- java基础(四)
- java基础(四)
- java基础(四)
- java基础 (四)
- JAVA基础(四)
- java基础(四)
- java基础汇总(四)
- JAVA基础加强(四)
- Java基础 笔记(四)
- Java语法基础(四)
- java基础总结(四)
- JAVA基础笔记(四)
- Java基础学习(四)
- java多线程基础(四)
- Java语言基础(四)
- java基础(四)------多线程基础
- java学习记录----java基础(四)
- Java基础(四)(集合)
- 注意点小结(Java)
- RasDeleteSubEntry
- 数据---File
- apicloud中多个按钮的切换
- Java线程安全的实现方法
- java基础(四)
- Android拍照或从系统相册获取图片
- MyEclipse 下'Publishing to Tomcat'has encountered a problem解决办法
- 实现音乐播放器歌词显示效果
- hihocoder 1362 修补木桶
- 程序设计竞赛训练手册
- 利用SpringMvc和MyBatis实现员工列表显示页面
- 准备在CSDN安家啦。
- Codeforces Problem 707C Pythagorean Triples(数学)