Java——5个Demo带你学懂反射机制中最基础、最重要的内容

简介: Java——5个Demo带你学懂反射机制中最基础、最重要的内容

文章目录:


写在前面

关于JDK中自带的类加载器

Demo1:获取Class的三种方式

Demo2:如何通过反射机制访问一个Java对象的属性?(Field)

Demo3:如何通过反射机制调用一个对象的方法?(Method)

Demo4:如何通过反射机制创建一个对象?(Constructor)

Demo5:给你一个类,如何获取这个类的父类、已实现的接口?


写在前面


  • 反射机制有什么用?

       通过java语言中的反射机制可以操作字节码文件。

       优点类似于黑客。(可以读和修改字节码文件。)

       通过反射机制可以操作代码片段。(class文件。)

  • 反射机制的相关类在哪个包下?

       java.lang.reflect.*;

  • 反射机制相关的重要的类有哪些?

              java.lang.Class:代表整个字节码,代表一个类型,代表整个类。


              java.lang.reflect.Method:代表字节码中的方法字节码。代表类中的方法。


              java.lang.reflect.Constructor:代表字节码中的构造方法字节码。代表类中的构造方法


              java.lang.reflect.Field:代表字节码中的属性字节码。代表类中的成员变量(静态变量+实例变量)。


//java.lang.Class:
public class User{
    // Field
    int no;
    // Constructor
    public User(){
    }
    public User(int no){
  this.no = no;
    }
    // Method
    public void setNo(int no){
  this.no = no;
    }
    public int getNo(){
  return no;
    }
}


关于JDK中自带的类加载


  • 什么是类加载器?

       专门负责加载类的命令/工具。

      ClassLoader

  • JDK中自带了3个类加载器

       启动类加载器: rt.jar

       扩展类加载器: ext/*.jar

       应用类加载器: classpath

  • 首先通过 “启动类加载器” 加载。如果通过 “启动类加载器” 加载不到的时候,会通过 "扩展类加载器" 加载。如果 “扩展类加载器” 没有加载到,那么会通过 “应用类加载器” 加载。
  • java中为了保证类加载的安全,使用了双亲委派机制。

       优先从启动类加载器中加载,这个称为“父”;“父”无法加载到,再从扩展类加载器中加载,这个称为“母”。双亲委派。如果都加载不到,才会考虑从应用类加载器中加载。直到加载到为止。


Demo1:获取Class的三种方式


package com.szh.reflect;
import java.util.Date;
/**
 * 要操作一个类的字节码,需要先获取这个类的字节码
 * 怎么获取 java.lang.Class 实例?
 *      Class.forName()
 *      1.静态方法
 *      2.方法的参数是一个字符串
 *      3.字符串必须是一个完整类名的全限定名称
 */
public class ReflectTest01 {
    public static void main(String[] args) {
        /*
            Class.forName()
              1.静态方法
              2.方法的参数是一个字符串
              3.字符串必须是一个完整类名的全限定名称
         */
        try {
            //c1代表String.class文件,或者说c1代表String类型,下面c2、c3、c4同理
            Class c1=Class.forName("java.lang.String");
            Class c2=Class.forName("java.util.Date");
            Class c3=Class.forName("java.lang.Integer");
            Class c4=Class.forName("java.lang.System");
            System.out.println(c4.getName());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        //Java中任何一个对象都有一个方法:getClass()
        String s="abc";
        //x代表String.class文件,或者说x代表String类型
        Class x=s.getClass();
        System.out.println(x.getName());
        //Java中任何一种类型(包括基本数据类型),都有一个 class 属性
        Class z=String.class;
        Class i= Date.class;
        Class j=int.class;
        Class k=Double.class;
        System.out.println(i.getName());
    }
}



Demo2:如何通过反射机制访问一个Java对象的属性?(Field)


package com.szh.bean;
/**
 *
 */
public class Student {
    public int id;
    private String name;
    protected int age;
    boolean sex;
}
package com.szh.reflect;
import java.lang.reflect.Field;
/**
 * 必须掌握:如何通过反射机制访问一个Java对象的属性?
 *          给属性赋值 set
 *          获取属性的值 get
 */
public class ReflectTest07 {
    public static void main(String[] args) throws Exception {
        //通过反射机制获取Class,通过Class实例化对象
        Class studentClass=Class.forName("com.szh.bean.Student");
        //newInstance() 这个方法会调用Student类中的无参构造方法,完成对象的创建
        //obj此时是一个Student对象
        Object obj=studentClass.newInstance();
        //获取公共属性:id
        Field idField=studentClass.getDeclaredField("id");
        //给obj对象的id属性赋值
        idField.set(obj,1001);
        //获取obj对象的id属性值
        System.out.println(idField.get(obj));
        //获取私有属性:name
        Field nameField=studentClass.getDeclaredField("name");
        //打破封装
        nameField.setAccessible(true);
        //给obj对象的name属性赋值
        nameField.set(obj,"张起灵");
        //获取obj对象的name属性值
        System.out.println(nameField.get(obj));
    }
}



Demo3:如何通过反射机制调用一个对象的方法?(Method)


package com.szh.bean;
/**
 *
 */
public class UserService {
    public boolean login(String username,String password) {
        if ("root".equals(username) && "12345678".equals(password)) {
            return true;
        }
        return false;
    }
    public void logout() {
        System.out.println("成功退出!");
    }
}
package com.szh.reflect;
import java.lang.reflect.Method;
/**
 * 必须掌握:通过反射机制调用一个对象的方法
 */
public class ReflectTest08 {
    public static void main(String[] args) throws Exception {
        //获取类
        Class userServiceClass=Class.forName("com.szh.bean.UserService");
        //创建对象
        Object obj=userServiceClass.newInstance();
        //获取类中的Method
        Method loginMethod=userServiceClass.getDeclaredMethod("login", String.class, String.class);
        //调用方法
        /*
            loginMethod 是方法
            obj 是对象
            "root","12345678" 是实参
            retValue 是返回值
            合起来:调用UserService类中的userService对象调用login方法,传入"root","12345678"实参,获取retValue返回值
         */
        Object retValue=loginMethod.invoke(obj,"root","12345678");
        System.out.println(retValue);
    }
}



Demo4:如何通过反射机制创建一个对象?(Constructor)


package com.szh.bean;
/**
 *
 */
public class Vip {
    public int no;
    public String name;
    public String birth;
    public boolean sex;
    public Vip() {
    }
    public Vip(int no) {
        this.no = no;
    }
    public Vip(int no, String name) {
        this.no = no;
        this.name = name;
    }
    public Vip(int no, String name, String birth) {
        this.no = no;
        this.name = name;
        this.birth = birth;
    }
    public Vip(int no, String name, String birth, boolean sex) {
        this.no = no;
        this.name = name;
        this.birth = birth;
        this.sex = sex;
    }
    @Override
    public String toString() {
        return "Vip{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", birth='" + birth + '\'' +
                ", sex=" + sex +
                '}';
    }
}


package com.szh.reflect;
import java.lang.reflect.Constructor;
/**
 * 必须掌握:通过反射机制创建一个对象
 */
public class ReflectTest09 {
    public static void main(String[] args) throws Exception {
        Class vipClass=Class.forName("com.szh.bean.Vip");
        //调用无参构造方法
        Constructor c=vipClass.getConstructor();
        Object obj=c.newInstance();
        System.out.println(obj);
        //调用有参构造方法
        //第一步:先获取这个对象的有参构造方法
        Constructor constructor=vipClass.getDeclaredConstructor(int.class,String.class,String.class,boolean.class);
        //第二步:调用有参构造方法new对象
        Object newObj=constructor.newInstance(1001,"张起灵","2000-05-01",true);
        System.out.println(newObj);
    }
}


Demo5:给你一个类,如何获取这个类的父类、已实现的接口?


package com.szh.reflect;
/**
 * 给你一个类,如何获取这个类的父类、已实现的接口
 */
public class ReflectTest10 {
    public static void main(String[] args) throws Exception {
        //String
        Class stringClass=Class.forName("java.lang.String");
        //获取String的父类
        Class superClass=stringClass.getSuperclass();
        System.out.println(superClass.getName());
        //获取String类实现的所有接口
        Class[] strings=stringClass.getInterfaces();
        for (Class c : strings) {
            System.out.println(c.getName());
        }
    }
}


 

目录
打赏
0
0
0
0
85
分享
相关文章
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
这篇文章详细介绍了Java中的IO流,包括字符与字节的概念、编码格式、File类的使用、IO流的分类和原理,以及通过代码示例展示了各种流的应用,如节点流、处理流、缓存流、转换流、对象流和随机访问文件流。同时,还探讨了IDEA中设置项目编码格式的方法,以及如何处理序列化和反序列化问题。
158 1
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
|
4月前
|
Java中的反射机制与应用实例
【10月更文挑战第22天】Java作为一门面向对象的编程语言,提供了丰富的特性来支持对象的创建、操作和交互。其中,反射机制是Java的一项核心特性,它允许程序在运行时动态地获取类的信息、创建对象、调用方法、访问属性等。本文将从三个部分探讨Java中的反射机制及其应用实例:一是反射机制的基本概念和原理;二是反射机制在Java中的应用场景;三是通过实例深入理解反射机制的使用方法和技巧。
45 4
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
String常量池、String、StringBuffer、Stringbuilder有什么区别、List与Set的区别、ArrayList和LinkedList的区别、HashMap底层原理、ConcurrentHashMap、HashMap和Hashtable的区别、泛型擦除、ABA问题、IO多路复用、BIO、NIO、O、异常处理机制、反射
|
7月前
|
MQTT(EMQX) - Java 调用 MQTT Demo 代码
MQTT(EMQX) - Java 调用 MQTT Demo 代码
238 0
MQTT(EMQX) - Java 调用 MQTT Demo 代码
Java面试题:描述Java反射机制及其应用场景,并讨论其优缺点。
Java面试题:描述Java反射机制及其应用场景,并讨论其优缺点。
70 1
Java中的反射机制及其应用场景详解
Java中的反射机制及其应用场景详解
|
8月前
|
Java注解与反射机制
Java注解与反射概述: - 注解用于元数据,包括元注解`@Target`, `@Retention`, `@Documented`, `@Inherited`。 - 自定义注解用于自定义行为标记,参考[链接]例化后通过`getClass()`获取类信息。 - 主要API涉及类的多种获取方式,如`对象.getClass()`, `类名.class`, `Class.forName()`和内置类型`TYPE`。 - 应用场景包括动态创建对象,获取泛型和注解信息以及分析运行时结构。
解析Java中的反射机制及其应用场景
解析Java中的反射机制及其应用场景