文档章节

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
06/21
0
0
Java面试基础篇——第十五篇:代理模式

什么是代理? 通过代理控制对象的访问,可以详细访问某个对象的方法,在这个方法调用处理,或调用后处理。 代理应用场景 安全代理 可以屏蔽真实角色远程代理 远程调用代理类RMI延迟加载 先加载...

developlee的潇洒人生
08/02
0
0
Java入门需掌握的30个基本概念

(1)Easy:Java的语法比C++的相对简单,另一个方面就是Java能使软件在很小的机器上运行,基础解释其和类库的支持的大小约为40kb,增加基本的标准库和线程支持的内存需要增加125kb。 (2)分布...

风一样
2011/08/03
0
0
动态代理机制详解(JDK 和CGLIB,Javassist,ASM)

在运行时期可以按照Java虚拟机规范对class文件的组织规则生成对应的二进制字节码。当前有很多开源框架可以完成这些功能,如ASM,Javassist。 动态代理机制详解(JDK 和CGLIB,Javassist,ASM...

素雷
2017/10/19
0
0
跳槽时,这些Java面试题99%会被问到

我在 Oracle 已经工作了近 7 年,面试过从初级到非常资深的Java工程师,且由于 Java 组工作任务的特点,我非常注重面试者的计算机科学基础和编程语言的理解深度,可以不要求面试者非要精通 ...

Java小铺
08/15
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Shell | linux安装包不用选择Y/N的方法

apt-get install -y packageOR echo "y" | sudo apt-get install package

云迹
7分钟前
0
0
Hadoop的大数据生态圈

基于Hadoop的大数据的产品圈 大数据产品的一句话概括 Apache Hadoop: 是Apache开源组织的一个分布式计算开源框架,提供了一个分布式文件系统子项目(HDFS)和支持MapReduce分布式计算的软件架...

zimingforever
21分钟前
1
0
八大包装类型的equals方法

先看其中一个源码 结论:八大包装类型的equals方法都是先判断类型是否相同,不相同则是false,相同则判断值是否相等 注意:包装类型不能直接用==来等值比较,否则编译报错,但是数值的基本类型...

xuklc
46分钟前
1
0
NoSQL , Memcached介绍

什么是NoSQL 非关系型数据库就是NoSQL,关系型数据库代表MySQL 对于关系型数据库来说,是需要把数据存储到库、表、行、字段里,查询的时候根据条件一行一行地去匹配,当量非常大的时候就很耗...

TaoXu
昨天
0
0
890. Find and Replace Pattern - LeetCode

Question 890. Find and Replace Pattern Solution 题目大意:从字符串数组中找到类型匹配的如xyy,xxx 思路: 举例:words = ["abc","deq","mee","aqq","dkd","ccc"], pattern = "abb"abc ......

yysue
昨天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部