资讯专栏INFORMATION COLUMN

(CZ深入浅出Java基础)反射

asoren / 608人阅读

摘要:分类根类加载器也被称为引导类加载器,负责核心类的加载比如等。要想解剖一个类必须先要获取到该类的字节码文件对象。

这是刘意老师的JAVA基础教程的笔记
讲的贼好,附上传送门

传智风清扬-超全面的Java基础

一、类的加载 1.类初始化的时机

创建类的实例
访问类的静态变量,或者为静态变量赋值
调用类的静态方法
使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
初始化某个类的子类
直接使用java.exe命令来运行某个主类

2.类加载器

2.1.作用

负责将.class文件加载到内在中,并为之生成对应的Class对象。
虽然我们不需要关心类加载机制,但是了解这个机制我们就能更好的理解程序的运行。

2.2.分类

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语言的反射机制。要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.

class类包含:

  成员变量  Field

  构造方法  Consturctor

  成员方法  Method

并且把这三个东西都看做对象

1.获取class文件对象的三种方式
public class Demo {
    public static void main(String[] args) throws ClassNotFoundException {
        //方式1
        Person p=new Person();
        Class c=p.getClass();
        
        Person p2=new Person();
        Class c2=p.getClass();
        
        System.out.println(p==p2);
        System.out.println(c==c2);
        
        //方式2
        Class c3=Person.class;
        
        //方式3
        Class c4=Class.forName("demo1.Person");//要全路径
    }
}
2.通过反射获取无参构造方法并使用
package demo1;

import java.lang.reflect.Constructor;

public class Demo {
    public static void main(String[] args) throws Exception {
        Class c = Class.forName("demo1.Person");// 要全路径

        // 获取构造方法
        System.out.println("获取public构造方法");
        Constructor[] cons = c.getConstructors();
        for (Constructor constructor : cons) {
            System.out.println(constructor);
        }

        System.out.println("获取所有构造方法");
        cons = c.getDeclaredConstructors();
        for (Constructor constructor : cons) {
            System.out.println(constructor);
        }

        System.out.println("运用class字节码文件获取某个构造方法对象,并创建该类的实例");
        Constructor con = c.getConstructor();
        Object obj=con.newInstance();
        System.out.println(con);
    }
}

class Person {
    // 成员变量
    private String name;
    int age;
    public String address;

    // 构造方法
    public Person() {
    }
    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public Person(String name, int age, String address) {
        super();
        this.name = name;
        this.age = age;
        this.address = address;
    }

    // 成员方法
    public void show() {
        System.out.println("show");
    }
    public void method(String s) {
        System.out.println("method" + s);
    }
    public String getString(String s, int i) {
        return s + "---" + i;
    }
    private void function() {
        System.out.println("function");
    }
    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + ", address=" + address + "]";
    }
}
3.通过反射去获得含参构造方法
package demo1;

import java.lang.reflect.Constructor;

public class Demo {
    public static void main(String[] args) throws Exception {
        Class c = Class.forName("demo1.Person");// 要全路径

        System.out.println("运用class字节码文件获取某个构造方法对象,并创建该类的实例");
        Constructor con = c.getConstructor(String.class, int.class, String.class);
        Object obj = con.newInstance("zxy",23,"Xi"an");
        System.out.println(obj);
    }
}

class Person {
    // 成员变量
    private String name;
    int age;
    public String address;

    // 构造方法
    public Person() {
    }

    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Person(String name, int age, String address) {
        super();
        this.name = name;
        this.age = age;
        this.address = address;
    }

    // 成员方法
    public void show() {
        System.out.println("show");
    }

    public void method(String s) {
        System.out.println("method" + s);
    }

    public String getString(String s, int i) {
        return s + "---" + i;
    }

    private void function() {
        System.out.println("function");
    }

    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + ", address=" + address + "]";
    }
}
4.获取私有构造方法
package demo1;

import java.lang.reflect.Constructor;

public class Demo {
    public static void main(String[] args) throws Exception {
        Class c = Class.forName("demo1.Person");// 要全路径

        System.out.println("运用class字节码文件获取某个构造方法对象,并创建该类的实例");
        Constructor con = c.getDeclaredConstructor(String.class);
        con.setAccessible(true);//取消Java语言的访问检查
        Object obj = con.newInstance("zxy");
        System.out.println(obj);
    }
}

class Person {
    // 成员变量
    private String name;
    int age;
    public String address;

    // 构造方法
    public Person() {
    }

    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    private Person(String name) {
        this.name = name;
    }

    public Person(String name, int age, String address) {
        super();
        this.name = name;
        this.age = age;
        this.address = address;
    }

    // 成员方法
    public void show() {
        System.out.println("show");
    }

    public void method(String s) {
        System.out.println("method" + s);
    }

    public String getString(String s, int i) {
        return s + "---" + i;
    }

    private void function() {
        System.out.println("function");
    }

    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + ", address=" + address + "]";
    }
}
5.通过反射调用方法
package demo1;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class Demo {
    public static void main(String[] args) throws Exception {
        Class c = Class.forName("demo1.Person");// 要全路径
        Constructor con = c.getConstructor();
        Object obj = con.newInstance();

        Method m1 = c.getMethod("show");//获取方法对象
        m1.invoke(obj);//调用哪个对象的这个方法

        Method m2 = c.getMethod("method", String.class);
        m2.invoke(obj, "123");

        Method m3 = c.getDeclaredMethod("function");
        m3.setAccessible(true);
        m3.invoke(obj);
    }
}

class Person {
    // 成员变量
    private String name;
    int age;
    public String address;

    // 构造方法
    public Person() {
    }

    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    private Person(String name) {
        this.name = name;
    }

    public Person(String name, int age, String address) {
        super();
        this.name = name;
        this.age = age;
        this.address = address;
    }

    // 成员方法
    public void show() {
        System.out.println("show");
    }

    public void method(String s) {
        System.out.println("method" + s);
    }

    public String getString(String s, int i) {
        return s + "---" + i;
    }

    private void function() {
        System.out.println("function");
    }

    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + ", address=" + address + "]";
    }
}
6.通过反射调用成员变量
package demo1;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;

public class Demo {
    public static void main(String[] args) throws Exception {
        Class c = Class.forName("demo1.Person");// 要全路径
        Constructor con=c.getConstructor();
        Object obj=con.newInstance();
        Field addressField = c.getField("address");
        addressField.set(obj, "xian");
        System.out.println(obj);
    }
}

class Person {
    // 成员变量
    private String name;
    int age;
    public String address;

    // 构造方法
    public Person() {
    }

    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    private Person(String name) {
        this.name = name;
    }

    public Person(String name, int age, String address) {
        super();
        this.name = name;
        this.age = age;
        this.address = address;
    }

    // 成员方法
    public void show() {
        System.out.println("show");
    }

    public void method(String s) {
        System.out.println("method" + s);
    }

    public String getString(String s, int i) {
        return s + "---" + i;
    }

    private void function() {
        System.out.println("function");
    }

    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + ", address=" + address + "]";
    }
}
7.通过用户的增删改查和学生登录注册引入中介 三、动态代理

代理:本来应该自己做的事情,却请了别人来做,被请的人就是代理对象。
举例:春季回家买票让人代买
动态代理:在程序运行过程中产生的这个对象
而程序运行过程中产生对象其实就是我们刚才反射讲解的内容,所以,动态代理其实就是通过反射来生成一个代理

(我也没太听懂)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/67509.html

相关文章

  • Java9模块化学习笔记二之模块设计模式

    摘要:但是模块化当中,无法扫描只有模块中可以使用有两种解决方案定义一个专门的资源模块,并使用提供的接口,实现它,并将这个实现注册为服务。有两种方式使用或包名,包名模块名使用运行时动态。 模块设计的原则: 1、防止出现编译时循环依赖(主要是编译器不支持),但运行时是允许循环依赖的,比如GUI应用2、明确模块的边界 几种模块设计: API模块,聚合模块(比如java.base) 可选依赖 两种方...

    李文鹏 评论0 收藏0
  • CZ深入浅出Java基础)设计模式笔记

    摘要:在设计模式中,所有的设计模式都遵循这一原则。其实就是说在应用程序中,所有的类如果使用或依赖于其他的类,则应该依赖这些其他类的抽象类,而不是这些其他类的具体类。使用设计模式是为了可重用代码让代码更容易被他人理解保证代码可靠性。 这是刘意老师的JAVA基础教程的笔记讲的贼好,附上传送门 传智风清扬-超全面的Java基础 一、面向对象思想设计原则 1.单一职责原则 其实就是开发人员经常说的高...

    李昌杰 评论0 收藏0
  • CZ深入浅出Java基础)线程笔记

    摘要:一个进程如果有多条执行路径,则称为多线程程序。这可能抛出在当前线程中。考虑多线程的数据安全问题是否是多线程环境。当前线程必须拥有此对象监视器。此方法导致当前线程称之为将其自身放置在对象的等待集中,然后放弃此对象上的所有同步要求。 这是刘意老师的JAVA基础教程的笔记讲的贼好,附上传送门 传智风清扬-超全面的Java基础 一、线程的引入 1.多线程概述 进程 a.正在运行的程序,是...

    harryhappy 评论0 收藏0
  • Java相关

    摘要:本文是作者自己对中线程的状态线程间协作相关使用的理解与总结,不对之处,望指出,共勉。当中的的数目而不是已占用的位置数大于集合番一文通版集合番一文通版垃圾回收机制讲得很透彻,深入浅出。 一小时搞明白自定义注解 Annotation(注解)就是 Java 提供了一种元程序中的元素关联任何信息和着任何元数据(metadata)的途径和方法。Annotion(注解) 是一个接口,程序可以通过...

    wangtdgoodluck 评论0 收藏0
  • Java学习路线总结,搬砖工逆袭Java架构师(全网最强)

    摘要:哪吒社区技能树打卡打卡贴函数式接口简介领域优质创作者哪吒公众号作者架构师奋斗者扫描主页左侧二维码,加入群聊,一起学习一起进步欢迎点赞收藏留言前情提要无意间听到领导们的谈话,现在公司的现状是码农太多,但能独立带队的人太少,简而言之,不缺干 ? 哪吒社区Java技能树打卡 【打卡贴 day2...

    Scorpion 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<