文档章节

Java基础进阶_day18_(类加载器,反射,动态代理)

S
 Sunmos
发布于 2017/05/13 00:18
字数 2281
阅读 3
收藏 0

Java基础进阶_day18_(类加载器,反射,动态代理)

1. 类加载器

/* * 类加载器: * 类的加载:当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化. * 1.加载 * 就是指将class文件读入内存,并为之创建一个Class对象。 任何类被使用时系统都会建立一个Class对象。 * 2.连接 * A:验证 是否有正确的内部结构,并和其他类协调一致; * B:准备 负责为类的静态成员分配内存,并设置默认初始化值; * C:解析 将类的二进制数据中的符号引用替换为直接引用. * 3.初始化 * 就是我们以前讲过的初始化步骤. * 类的初始化时机: * 1.创建类的实例; * 2.访问类的静态变量,或者为静态变量赋值; * 3.调用类的静态方法; * 4.使用反射方式来强制创建某个类或接口对应的java.lang.Class对象; * 5.初始化某个类的子类; * 6.直接使用java.exe命令来运行某个主类. * * 类加载器:负责将.class文件加载到内在中,并为之生成对应的Class对象,获取到Class对象后结合反射进行使用. * 类加载器分为三种: * 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包和类路径. */
public class My_ClassLoader_Demo01 {
    public static void main(String[] args) {
    }
}

2.反射

2.1 反射概述

/* * 反射: * JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法; * 对于任意一个对象,都能够调用它的任意一个方法和属性; * 这种动态获取的信息以及动态调用对象的方法的功能. * 反射使用的前提是先获取类的字节码对象Class,使用Class中方法进行类的解析. * * 获取Class对象的三种方式:常用第三种 * A:通过类.class获取 * B:通过对象.getclass()方法获取 * C:通过Class的forName(类的全名)获取 */
public class My_Reflect_Demo01 {
    public static void main(String[] args) throws Exception {
        // 类的Class对象的获取
        // A:通过类.class获取
        Class c1 = My_Reflect_Demo01.class;
        System.out.println(c1);
        // B:通过对象.getclass()方法获取
        My_Reflect_Demo01 mrd = new My_Reflect_Demo01();
        Class c2 = mrd.getClass();
        System.out.println(c2);
        // C:通过Class的forName(类的全名)获取
        Class c3 = Class.forName("com.itheima.reflect01.My_Reflect_Demo01");
        System.out.println(c3);
    }
}

2.2 反射获取构造方法

package com.itheima.reflect02;
/* * 自定义类,反射测试用 */
public class Person {
    // 私有的属性
    private String name;
    // 默认的属性
    int age;
    // 无参构造方法
    public Person() {
    }
    // 有参构造方法
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    // 私有的构造方法
    private Person(int age) {
        this.age = age;
    }
    // 公共的成员方法
    public void show(String s) {
        System.out.println("show:" + s);
    }
    // 私有的成员方法
    private String show2(String s) {
        return "私有的成员方法";
    }
    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }
}

import java.lang.reflect.Constructor;
/* * 反射获取构造方法: * Class类的方法:获取构造方法的参数是对应数据类型的.class对象 * public Constructor[] getConstructors():获取所有的公共的构造方法; * public Constructor[] getDeclaredConstructors():获取所有的构造方法,包括私有的构造方法; * public Constructor getConstructor(Class... parameterTypes):获取指定参数个数和类型的公共的构造方法,没有参数时获取空参构造; * public Constructor getDeclaredConstructor(Class... parameterTypes):获取指定参数个数和类型的所有的构造方法,,没有参数时获取空参构造; * 创建类对象:Class类的方法 * public T newInstance(Object ... initargs):创建类的对象,参数为空时代表无参 * 当获取的是私有的构造方法时,创建对象前先调用setAccessible(boolean flag),将访问权限设为true. */
public class My_Reflect_Demo01 {
    public static void main(String[] args) throws Exception {
        // 获取类的Class对象
        Class c1 = Class.forName("com.itheima.reflect02.Person");
        // 获取所有公共的构造方法
        Constructor[] cs = c1.getConstructors();
        for (int i = 0; i < cs.length; i++) {
            System.out.println(cs[i]);
        }
        // 获取所有的构造方法
        Constructor[] cns = c1.getDeclaredConstructors();
        for (Constructor cn : cns) {
            System.out.println(cn);
        }
        // 获取单个构造方法,并创建对象
        Constructor cns1 = c1.getConstructor();
        Object obj = cns1.newInstance();
        // 获取私有的构造方法,并创建对象
        Constructor cns2 = c1.getDeclaredConstructor(int.class);
        cns2.setAccessible(true);
        Object obj2 = cns2.newInstance(23);
        System.out.println(obj2); // Person [name=null, age=23]
    }
}

2.3 反射获取成员属性

package com.itheima.reflect02;
/* * 自定义类,反射测试用 */
public class Person {
    // 私有的属性
    private String name;
    // 默认的属性
    int age;
    // 无参构造方法
    public Person() {
    }
    // 有参构造方法
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    // 私有的构造方法
    private Person(int age) {
        this.age = age;
    }
    // 公共的成员方法
    public void show(String s) {
        System.out.println("show:" + s);
    }
    // 私有的成员方法
    private String show2(String s) {
        return "私有的成员方法";
    }
    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }
}

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
/* * 反射获取类的成员属性:Class类的功能 * public Field[] getFields():获取类的公共的成员属性; * public Field[] getDeclaredFields():获取类的所有的成员属性; * public Field getField(String name):获取类的指定字段名的公共的成员属性; * public Field getDeclaredField(String name):获取类的指定字段名的成员属性(可以是私有的属性). * 设置属性的值:Field类的功能 * public void set(Object obj,Object value):设置指定obj对象变量的此field表示的字段值设为value; * */
public class My_Reflect_Demo02 {
    public static void main(String[] args) throws Exception {
        // 获取类的Class对象
        Class c1 = Class.forName("com.itheima.reflect02.Person");
        // 获取构造方法,并创建对象
        Constructor cns = c1.getDeclaredConstructor(int.class);
        cns.setAccessible(true);
        Object obj = cns.newInstance(34);
        // 获取公共的成员属性
        Field[] fields = c1.getFields();
        // 获取所有的成员属性
        Field[] fields2 = c1.getDeclaredFields();
        for (Field field : fields2) {
            System.out.println(field);
        }
        // 获取制定字段名的属性,并设置新的值
        Field field = c1.getDeclaredField("name");
        field.setAccessible(true);
        field.set(obj, "java");
        System.out.println(obj);
    }
}

2.4 反射获取成员方法

package com.itheima.reflect02;
/* * 自定义类,反射测试用 */
public class Person {
    // 私有的属性
    private String name;
    // 默认的属性
    int age;
    // 无参构造方法
    public Person() {
    }
    // 有参构造方法
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    // 私有的构造方法
    private Person(int age) {
        this.age = age;
    }
    // 公共的成员方法
    public void show(String s) {
        System.out.println("show:" + s);
    }
    // 私有的成员方法
    private String show2(String s) {
        return "私有的成员方法";
    }
    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }
}

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
/* * 反射获取类的成员方法:Class类的方法 * public Method[] getMethods():获取所有的成员方法,包括由该类或接口声明的以及从超类和超接口继承的那些的类或接口的公共成员方法; * public Method getMethod(String name,Class... parameterTypes):获取该类指定名称及指定参数个数及类型的所有公共的方法,包括该类之上的所有类及接口的公共方法。 * public Method[] getDeclaredMethods():获取本类所有的成员方法; * public Method getDeclaredMethod(String name,Class... parameterTypes):获取本类指定名称和指定参数个数及参数类型方法. * 调用方法:Method类的方法 * public Object invoke(Object obj,Object... args):调用obj对象变量的该方法,参数是Object类型的数组,返回值是object类型. */
public class My_Reflect_Demo03 {
    public static void main(String[] args) throws Exception {
        // 获取类的Class对象
        Class c1 = Class.forName("com.itheima.reflect02.Person");
        // 获取构造方法,创建对象
        Constructor cns = c1.getDeclaredConstructor();
        Object obj = cns.newInstance();
        // 获取所有的成员方法
        Method[] methods = c1.getMethods();
        // Method[] methods = c1.getDeclaredMethods();
        // 获取指定参数的成员方法
        Method method = c1.getDeclaredMethod("show2", String.class);
        method.setAccessible(true);
        Object result = method.invoke(obj, "你好");
        System.out.println(result); // 私有的成员方法
    }
}

2.5 反射案例1

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
/* * ArrayList<Integer>的一个对象,在集合中存储字符串数据 */
public class My_Reflect_Test01 {
    public static void main(String[] args) throws Exception {
        ArrayList<Integer> list = new ArrayList<Integer>();
        list.add(89);
        // 获取Class对象
        Class c1 = list.getClass();
        // 获取add方法,该方法的默认参数是E泛型,则是object的之类,将方法的参数设为object类型
        Method method = c1.getDeclaredMethod("add", Object.class);
        // 向集合中添加字符串数据
        method.invoke(list, "java");
        // 输出结果
        System.out.println(list);
    }
}

2.6 反射案例2

import java.lang.reflect.Field;
/* * 写一个方法public void setProperty(Object obj, String propertyName, Object value){}, * 此方法可将obj对象中名为propertyName的属性的值设置为value。 */
public class My_Reflect_Test02 {
    public static void main(String[] args) throws Exception {
        Person p = new Person();
        MyTool mt = new MyTool();
        mt.setProperty(p, "name", "张三");
        System.out.println(p);
    }
}
// 自定义类
class MyTool {
    // 定义方法
    public void setProperty(Object obj, String propertyName, Object value) throws Exception {
        // 获取对象的class对象
        Class c = obj.getClass();
        // 获取属性值的字段
        Field field = c.getDeclaredField(propertyName);
        // 将属性的访问权限设为true
        field.setAccessible(true);
        // 将obj对象的某个字段值设为value
        field.set(obj, value);
    }
}

本文转载自:http://blog.csdn.net/l631106040120/article/details/70188575

共有 人打赏支持
S
粉丝 0
博文 34
码字总数 0
作品 0
成都
私信 提问
【目录导航】JAVA零基础进阶之路

【JAVA零基础入门系列】(已完结)导航目录 Day1 开发环境搭建 Day2 Java集成开发环境IDEA Day3 Java基本数据类型 Day4 变量与常量 Day5 Java中的运算符 Day6 Java字符串 Day7 Java输入与输出...

MFrank
2018/06/21
0
0
Java核心机制:反射机制的原理及应用方法

一、java的核心机制 java有两种核心机制:java虚拟机(JavaVirtual Machine)与垃圾收集机制(Garbage collection): 1、Java虚拟机:是运行所有Java程序的抽象计算机,是Java语言的运行环境,在...

Java架构资源分享
2018/11/25
0
0
编程思想 之「运行时类型识别、反射」

版权声明:Follow your heart and intuition. https://blog.csdn.net/qq_35246620/article/details/79576706 温馨提示:本系列博文(含示例代码)已经同步到 GitHub,地址为「java-skills」,...

维C果糖
2018/03/16
0
0
java动态代理(JDK和cglib)

JAVA的动态代理 代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代...

长平狐
2012/10/09
272
0
老司机带你深入浅出Java反射

反射,它就像是一种魔法,引入运行时自省能力,赋予了 Java 语言令人意外的活力,通过运行时操作元数据或对象,Java 可以灵活地操作运行时才能确定的信息 这里笔者就深入浅出总结下Java反射,...

小刀爱编程
2018/11/07
0
0

没有更多内容

加载失败,请刷新页面

加载更多

徒手撸一个简单的RPC框架

徒手撸一个简单的RPC框架 之前在牛逼哄哄的 RPC 框架,底层到底什么原理得知了RPC(远程过程调用)简单来说就是调用远程的服务就像调用本地方法一样,其中用到的知识有序列化和反序列化、动态...

不学无数的程序员
32分钟前
1
0
Java 面试题目最全集合1000+ 大放送,能答对70%就去BATJTMD试试~

2019,相对往年我们会发现今年猎头电话少了,大部分企业年终奖缩水,加薪幅度也不如往年,选择好offer就要趁早,现在开始准备吧,刷一波Java面试题,能回答70%就去BATJTMD大胆试试~ 以下是2...

mikechen优知
37分钟前
2
0
玩转Koa之核心原理分析

Koa作为下一代Web开发框架,不仅让我们体验到了async/await语法带来同步方式书写异步代码的酸爽,而且本身简洁的特点,更加利于开发者结合业务本身进行扩展。 本文从以下几个方面解读Koa源码...

前端小攻略
39分钟前
1
0
分布式之数据库和缓存双写一致性方案解析

为什么写这篇文章? 首先,缓存由于其高并发和高性能的特性,已经在项目中被广泛使用。在读取缓存方面,大家没啥疑问,都是按照下图的流程来进行业务操作。 ![] 但是在更新缓存方面,对于更新...

hensemlee
今天
5
0
怎么学习大数据

最近有很多人在找,大数据是怎么学?需要学什么技术以及这些技术的学习顺序是什么?今天有时间我把个问题总结成文章分享给大家。 那大数据处理技术怎么学习呢?首先我们要学习Java语言和Lin...

董黎明
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部