JAVA-15 (2025.08.20学习记录)

Junit(属于白盒测试)

Junit的使用

javadoc设置

导入Junit依赖的环境

Calculator类

java 复制代码
package Calculator;

public class Calculator {
    public int add(int a, int b) {
        return a + b;
    }

    public int sub(int a, int b) {
        return a - b;
    }
}

CalculatorTest类

java 复制代码
package com.mm.test01;

import Calculator.Calculator;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

public class CalculatorTest {
    //加入@Before后,这个方法会在测试方法执行前先执行
    //一般在@Before修饰的方法中加入申请资源的代码:申请数据库资源、IO资源、网络资源
    @Before
    public void init() {
        System.out.println("方法执行开始了");
    }

    //加入@After后,这个方法会在测试方法执行后执行
    //一般在@After修饰的方法中加入释放资源的代码:释放数据库资源、IO资源、网络资源
    @After
    public void close() {
        System.out.println("方法执行结束了");
    }

    @Test
    public void testadd() {
        Calculator cal = new Calculator();
        int result = cal.add(1, 3);
        System.out.println(result);
        //加入断言:判断预测结果与运行结果是否一致
        Assert.assertEquals(4, result);
    }

    @Test
    public void testadd2() {
        Calculator cal = new Calculator();
        int result = cal.add(1, 4);
        System.out.println(result);
    }
}

注解

自定义注解

Calculator类(使用注解)

java 复制代码
package Calculator;

import com.mm.anno.MyAnnotation;
import com.mm.anno.MyAnnotation2;

//因为定义自定义注解时定义了配置参数,所以必须给配置参数赋值
//如果只有一个参数,且这个参数名字为value,那 value= 可以省略不写
@MyAnnotation({"abc", "def"})
//如果给配置参数设置默认值,那使用的时候无需传值
@MyAnnotation2
public class Calculator {
    public static void main(String[] args) {
    }
}

MyAnnotation1

java 复制代码
package com.mm.anno;

public @interface MyAnnotation {
    /**
     * value:成员变量的名字(注意:如果仅有一个成员变量,名字尽量叫value)
     *String[ ]:成员变量的类型(无参数方法的类型:基本数据类型(8种)、String、枚举、注解、以及以上类型的数组)
     */
    String[] value();
}

MyAnnotation2

java 复制代码
package com.mm.anno;

public @interface MyAnnotation2 {
    //给配置参数设置默认值
    String value() default "abc";
}

MyAnnotation3

java 复制代码
package com.mm.anno;

public @interface MyAnnotation3
//注解内部是可以不定义配置参数的,内部没有定义配置参数的注解,叫标记
{
}

元注解

Retention

(用于声明被修饰的注解的生命周期)

java 复制代码
package com.mm.anno;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

//使注解只在源文件中有效(即源文件保留,在.class字节码文件中不会保留注解信息)
//@Retention(RetentionPolicy.SOURCE)

//反编译查看字节码文件,字节码文件中带有MyAnnotation这个注解
//@Retention(RetentionPolicy.CLASS)

//使注解在运行时有效。当运行java程序时,JVM会保留注解,加载在内存中,程序可以通过反射获取该注解
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    String[] value();
}

Target

java 复制代码
package com.mm.anno;

import java.lang.annotation.ElementType;
import java.lang.annotation.Target;

//指定被修饰的注解能用于修饰哪些程序元素
//此处MyAnnotation注解可以用于修饰类、属性、构造器、方法
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.METHOD})
public @interface MyAnnotation {
    String[] value();
}

枚举

自定义枚举类

枚举类:属性限制不变,对象也限制不变

  • 自定义枚举类的上层父类:

    • Object

    • 注释掉toString方法后,打印对象输出的是地址

java 复制代码
package com.mm.enum01;

/**
 * 定义枚举类:季节
 */
public class season {
    //属性使用final修饰不能改变
    private final String seasonName;//季节名字
    private final String seasonDesc;//季节描述

    //用构造器对属性进行赋值操作
    //构造器私有化,外界不能调用这个构造器,只能Season内部调用
    private season(String seasonName, String seasonDesc) {
        this.seasonName = seasonName;
        this.seasonDesc = seasonDesc;
    }

    //提供枚举类的有限的、确定的对象
    //对象使用final修饰,SPRING不能重新new对象
    public static final season SPRING = new season("春天", "春暖花开");

    //额外因素

    public String getSeasonDesc() {
        return seasonDesc;
    }

    public String getSeasonName() {
        return seasonName;
    }

    @Override
    public String toString() {
        return "test{" +
                "seasonDesc='" + seasonDesc + '\'' +
                ", seasonName='" + seasonName + '\'' +
                '}';
    }
}

自定义枚举类改成enum枚举类

用enum关键字定义枚举类

  • 用enum关键字创建的枚举类的上层父类

    • java.lang.Enum

    • 注释掉toString方法后,打印对象输出的不是地址,而是对象名

java 复制代码
package com.mm.enum01;

/**
 * 用enum关键字定义枚举类
 * enum枚举类要求对象(常量)必须放在最开始的位置
 */
public enum season {
    //多个对象之间用逗号隔开,最后一个用;结束
    SPRING("春天", "春暖花开"),
    SUMMER("夏天", "烈日炎炎"),
    WINTER("冬天", "冰天雪地");
    
    //属性使用final修饰不能改变
    private final String seasonName;//季节名字
    private final String seasonDesc;//季节描述

    //用构造器对属性进行赋值操作
//构造器私有化,外界不能调用这个构造器,只能Season内部调用
    private season(String seasonName, String seasonDesc) {
        this.seasonName = seasonName;
        this.seasonDesc = seasonDesc;
    }
    
    //额外因素

    public String getSeasonDesc() {
        return seasonDesc;
    }

    public String getSeasonName() {
        return seasonName;
    }

    @Override
    public String toString() {
        return "test{" +
                "seasonDesc='" + seasonDesc + '\'' +
                ", seasonName='" + seasonName + '\'' +
                '}';
    }
}

枚举类底层没有属性

构造器、toString、get方法都删掉。只留下对象名/常量名 +,/;

java 复制代码
package com.mm.enum01;

/**
 * enum枚举类要求对象(常量)必须放在最开始的位置
 */
public enum season {
    //多个对象之间用逗号隔开,最后一个用;结束
    //这个枚举类底层没有属性,构造器、toString、get方法都删掉
    SPRING,   //原本该写为SPRING(),现在连()都省略了
    SUMMER,
    WINTER;
}

用enum关键字创建的枚举类

这个枚举类可以直接拿过来使用,3个常用方法

java 复制代码
package com.mm.enum01;

public class test {
    public static void main(String[] args) {
        //用enum关键字创建的枚举类的上层父类:java.lang.Enum
        //这个枚举类可以直接拿过来使用
        //toString:获取对象名
        season spring = season.SPRING;
        System.out.println(spring);

        //values:返回枚举类对象的数组
        season[] values = season.values();
        //遍历
        for (season s : values) {
            System.out.println(s);
        }

        //valueOf:通过对象名获取这个对象
        //注意:对象的名字必须传正确,否则报异常
        season spring1 = season.valueOf("SPRING");
        System.out.println(spring1);
    }
}

枚举类实现接口

所有枚举对象调用show方法走的都是同一个方法

TestInterface接口

java 复制代码
package com.mm.enum01;

public interface TestInterface {
    void show();
}

枚举类season

java 复制代码
package com.mm.enum01;

//枚举类实现接口
public enum season implements TestInterface {
    SPRING,
    SUMMER,
    WINTER;

    //需要重写接口内的抽象方法
    @Override
    public void show() {
        System.out.println("重写接口内的抽象方法");
    }
}

test类

java 复制代码
package com.mm.enum01;

public class test {
    public static void main(String[] args) {
        season spring = season.SPRING;
        spring.show();
        season summer = season.SUMMER;
        summer.show();
        //所有枚举对象调用show方法走的都是同一个方法
    }
}
不同枚举对象调用show方法走的是不同方法

仅需重写枚举类

java 复制代码
package com.mm.enum01;

//枚举类实现接口
public enum season implements TestInterface {
    SPRING {
        @Override
        public void show() {
            System.out.println("春天");
        }
    },
    SUMMER {
        @Override
        public void show() {
            System.out.println("夏天");
        }
    },
    WINTER {
        @Override
        public void show() {
            System.out.println("冬天");
        }
    };
}

枚举的应用

枚举Gender类

java 复制代码
package com.mm.enum01;

public enum Gender {
    男,
    女;
}

Person类

java 复制代码
package com.mm.enum01;

public class Person {
    private int age;
    private String name;
    private Gender sex;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Gender getSex() {
        return sex;
    }

    public void setSex(Gender sex) {
        this.sex = sex;
    }

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                '}';
    }
}

test类

java 复制代码
package com.mm.enum01;

public class Test {
    public static void main(String[] args) {
        Person p = new Person();
        p.setAge(19);
        p.setName("lili");
        p.setSex(Gender.男);//传入枚举类对象,在入口处对参数进行了限制
        System.out.println(p);
    }
}

test02类

java 复制代码
package com.mm.enum01;

public class test02 {
    public static void main(String[] args) {
        //switch(表达式)表达式返回结果是个等值,等值的类型可以是int、byte、short、char、String、枚举中任意一种类型
        Gender sex = Gender.男;
        switch (sex) {
            case 女:
                System.out.println("女生");
                break;
            case 男:
                System.out.println("男生");
                break;
        }
    }
}

反射

美团实例

美团接口

java 复制代码
package com.mm.Reflect;

//接口的制定方:美团外卖
public interface Mtwm {
    //在线支付功能:
    void payonline();
}

微信支付类(实现美团接口)

java 复制代码
package com.mm.Reflect;

public class Wechat implements Mtwm {
    @Override
    public void payonline() {
        //具体实现微信支付功能
        System.out.println("使用微信支付成功");
    }
}

支付宝支付类(实现美团接口)

java 复制代码
package com.mm.Reflect;

public class AliPay implements Mtwm {
    @Override
    public void payonline() {
        //具体的支付宝支付
        System.out.println("支付宝付款成功");
    }
}

银行卡支付类

java 复制代码
package com.mm.Reflect;

public class BankCard implements Mtwm {
    @Override
    public void payonline() {
        //银行卡具体功能
        System.out.println("银行卡支付成功");
    }
}

test类(普通写法)

java 复制代码
package com.mm.Reflect;

public class test {
    public static void main(String[] args) {
        //定义一个字符串,模拟前台的支付方式
        String str = "支付宝";
        if ("微信".equals(str)) {//为啥不用str.equals("微信")?避免空指针异常
            //微信支付
//            new Wechat().payonline();//被下一句替代
            pay(new Wechat());
        }

        if ("支付宝".equals(str)) {
            //支付宝支付
//            new AliPay().payonline();//被下一句替代
            pay(new AliPay());
        }

        if ("银行卡".equals(str)) {
            pay(new BankCard());
        }
    }

    //微信支付
    public static void pay(Wechat wc) {
        wc.payonline();
    }

    //支付宝支付
    public static void pay(AliPay al) {
        al.payonline();
    }

    //银行卡支付
    public static void pay(BankCard bk) {
        bk.payonline();
    }
}

假设后续还有多种支付方式,添加类和方法太麻烦了

为了提高代码的拓展性---->面向对象特性:多态

方法的形参是接口,具体传入的是接口的实现类的对象--->多态的一种形式

test类(多态)

java 复制代码
package com.mm.Reflect;

public class test {
    public static void main(String[] args) {
        //定义一个字符串,模拟前台的支付方式
        String str = "支付宝";
        if ("微信".equals(str)) {//为啥不用str.equals("微信")?避免空指针异常
            //微信支付
//            new Wechat().payonline();//被下一句替代
            pay(new Wechat());
        }

        if ("支付宝".equals(str)) {
            //支付宝支付
//            new AliPay().payonline();//被下一句替代
            pay(new AliPay());
        }

        if ("银行卡".equals(str)) {
            pay(new BankCard());
        }
    }

    //方法的形参是接口,具体传入的是接口的实现类的对象--->多态的一种形式
    public static void pay(Mtwm m) {
        m.payonline();
    }
}

多态确实可以提高代码的拓展性,但拓展性没有达到最好

上面的if分支,还是需要手动删除或者添加

解决方法:反射机制

test(反射)

java 复制代码
package com.mm.Reflect;

import java.lang.reflect.Method;

public class test {
    public static void main(String[] args) throws Exception {
        //定义一个字符串,模拟前台的支付方式
        //字符串:是微信支付类的全限定路径
        String str = "com.mm.Reflect.Wechat";

        //下面的代码就是利用反射:
        Class cls = Class.forName(str);//cls-->Class类具体的对象,Alipay/微信pay字节码信息
        Object o = cls.newInstance();
        Method method = cls.getMethod("payonline");
        method.invoke(o);
    }
}

反射(面向对象思维)

获取字节码信息的四种方式

Person类(父类)

java 复制代码
package com.mm.Reflect;

//作为一个父类
public class Person {
    //属性
    private int age;
    public String name;

    //方法
    private void eat() {
        System.out.println("Person--eat");
    }

    public void sleep() {
        System.out.println("Person--sleep");
    }
}

test类(获取Person字节码信息)

java 复制代码
package com.mm.Reflect;

public class test {
    public static void main(String[] args) throws Exception {
        //案例:以Person的字节码信息为案例
        //方式1:通过getClass方式获取
        Person p = new Person();
        Class c1 = p.getClass();
        System.out.println(c1);

        //方式2:通过内置class属性
        Class c2 = Person.class;
        System.out.println(c2);

        //注意:方式1和方式2不常用

        //方式3:调用Class类提供的静态方法forName(用得最多)
        Class c3 = Class.forName("com.mm.Reflect.Person");

        //方式4:利用类的加载器
        ClassLoader loader = test.class.getClassLoader();
        Class c4 = loader.loadClass("com.mm.Reflect.Person");

        System.out.println(c1 == c2);//True
        System.out.println(c1 == c3);//True
        System.out.println(c1 == c4);//True
    }
}

可以作为Class类的实例的种类

Person类(父类)

java 复制代码
package com.mm.Reflect;

//作为一个父类
public class Person {
    //属性
    private int age;
    public String name;

    //方法
    private void eat() {
        System.out.println("Person--eat");
    }

    public void sleep() {
        System.out.println("Person--sleep");
    }
}

test类

java 复制代码
package com.mm.Reflect;

public class test {
    public static void main(String[] args) throws Exception {
        //可以作为Class类的实例的种类
        //1、类
        Class c1 = Person.class;

        //2、接口
        Class c2 = Comparable.class;

        //3、注解
        Class c3 = Override.class;

        //4、数组
        int[] arr1 = {1, 2, 3};
        Class c4 = arr1.getClass();
        int[] arr2 = {5, 6, 7};
        Class c5 = arr2.getClass();
        //同一个维度,同一个元素类型,得到的字节码就是同一个
        System.out.println(c4 == c5);//True

        //5、基本数据类型
        Class c6 = int.class;

        //6、void方法返回值
        Class c7 = void.class;
    }
}

获取运行时类的完整结构

Person类

java 复制代码
package com.mm.Reflect;

import java.io.Serializable;

//作为一个父类,实现序列化Serializable的接口
public class Person implements Serializable {
    //属性
    private int age;
    public String name;

    //方法
    private void eat() {
        System.out.println("Person--eat");
    }

    public void sleep() {
        System.out.println("Person--sleep");
    }
}

Student类(子类)

java 复制代码
package com.mm.Reflect;

//作为子类,实现自定义接口MyInterface
@MyAnnotation(value = "hello")
public class Student extends Person implements MyInterface {
    //属性
    private int sno;//学号
    double height;//身高(default修饰)
    protected double weight;
    public double score;//成绩

    //方法
    @MyAnnotation(value = "hiMethod")
    public String showInfo() {
        return "我是三好学生";
    }

    public String showInfo(int a, int b) {
        return "重载方法,三好学生";
    }

    private void work() {
        System.out.println("我会工作");
    }

    void happy() {
        System.out.println("happy");
    }

    protected int getSno() {
        return sno;
    }

    //构造器
    public Student() {
        System.out.println("无参构造器");
    }

    public Student(double weight, double height) {
        this.weight = weight;
        this.height = height;
    }

    private Student(int sno) {
        this.sno = sno;
    }

    Student(int sno, double weight) {//default修饰的构造器
        this.sno = sno;
        this.weight = weight;
    }

    protected Student(int sno, double height, double weight) {
        this.sno = sno;
    }

    @Override
    @MyAnnotation(value = "hellomyMethod")
    public void myMethod() {
        System.out.println("重写的myMethod方法");
    }

    @Override
    public String toString() {
        return "Student{" +
                "height=" + height +
                ", sno=" + sno +
                ", weight=" + weight +
                ", score=" + score +
                '}';
    }
}

MyAnnotation接口

java 复制代码
package com.mm.Reflect;


import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.PARAMETER;

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    String value();//属性
}

获取构造器和创建对象

java 复制代码
package com.mm.Reflect;

import java.lang.reflect.Constructor;

public class test {
    public static void main(String[] args) throws Exception {
        //获取字节码信息
        Class cls = Student.class;

        //通过字节码信息获取构造器
        //getConstructors只能获取当前运行时类的被public修饰的构造器,返回值是一个数组
        Constructor[] c1 = cls.getConstructors();
        for (Constructor c : c1) {
            System.out.println(c);
        }

        //getDeclaredConstructors能获取当前运行时类的全部修饰符的构造器,返回值是一个数组
        Constructor[] c2 = cls.getDeclaredConstructors();
        for (Constructor c : c2) {
            System.out.println(c);
        }

        //获取指定的构造器
        //不传参数,得到空构造器
        Constructor con1 = cls.getConstructor();
        System.out.println(con1);

        //获取两个参数的有参构造器
        Constructor con2 = cls.getConstructor(double.class, double.class);

        //getDeclaredConstructor:获取private修饰的有参构造器
        Constructor con3 = cls.getDeclaredConstructor(int.class);
        System.out.println(con3);

        //创建对象
        Object o1 = con1.newInstance();
        System.out.println(o1);

        Object o2 = con2.newInstance(180.5, 170.5);
        System.out.println(o2);
    }
}

获取属性和对属性进行赋值

java 复制代码
package com.mm.Reflect;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class test {
    public static void main(String[] args) throws Exception {
        //获取字节码信息
        Class cls = Student.class;

        //通过字节码信息获取属性
        //getFields:获取运行时类和其父类中被public修饰的属性,返回值是一个数组
        Field[] fields = cls.getFields();
        for (Field f : fields) {
            System.out.println(f);
        }

        //getDeclaredFields:获取当前运行时类的全部修饰符的属性
        Field[] declaredFields = cls.getDeclaredFields();
        for (Field f : declaredFields) {
            System.out.println(f);
        }

        //getField:获取指定的public修饰的属性
        Field score = cls.getField("score");
        System.out.println(score);
        //getDeclaredField:获取指定的private修饰的属性
        Field sno = cls.getDeclaredField("sno");
        System.out.println(sno);


        //获取属性的具体结构
        //获取属性的修饰符:返回结果是修饰符对应的数字
        int modifiers = sno.getModifiers();
//        System.out.println(modifiers);//2
        //将对应数字转为修饰符
        System.out.println(Modifier.toString(modifiers));

        //获取属性的数据类型:
        Class type = sno.getType();
        System.out.println(type);
        System.out.println(type.getName());

        //获取属性的名字:
        String name = sno.getName();
        System.out.println(name);

        //给属性赋值
        Field sco = cls.getField("score");
        //创建一个cls类的obj对象(给属性赋值必须有对象)
        Object obj = cls.newInstance();
        //给o2对象设置sco属性,值为98
        sco.set(obj, 98);
        System.out.println(obj);
    }
}

Student类

java 复制代码
package com.mm.Reflect;

//作为子类,实现自定义接口MyInterface
@MyAnnotation(value = "hello")
public class Student extends Person implements MyInterface {
    //属性
    private int sno;//学号
    double height;//身高(default修饰)
    protected double weight;
    public double score;//成绩

    //方法
    @MyAnnotation(value = "hiMethod")
    public String showInfo() {
        return "我是三好学生";
    }

    public String showInfo(int a, int b) {
        return "有参数的方法,三好学生";
    }

    private void work() {
        System.out.println("我会工作");
    }

    void happy() {
        System.out.println("happy");
    }

    protected int getSno() {
        return sno;
    }

    //构造器
    public Student() {
        System.out.println("无参构造器");
    }

    public Student(double weight, double height) {
        this.weight = weight;
        this.height = height;
    }

    private Student(int sno) {
        this.sno = sno;
    }

    Student(int sno, double weight) {//default修饰的构造器
        this.sno = sno;
        this.weight = weight;
    }

    protected Student(int sno, double height, double weight) {
        this.sno = sno;
    }

    @Override
    @MyAnnotation(value = "hellomyMethod")
    public void myMethod() throws RuntimeException {
        System.out.println("重写的myMethod方法");
    }

    @Override
    public String toString() {
        return "Student{" +
                "height=" + height +
                ", sno=" + sno +
                ", weight=" + weight +
                ", score=" + score +
                '}';
    }
}

获取方法和调用方法

test类

java 复制代码
package com.mm.Reflect;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Parameter;

public class test {
    public static void main(String[] args) throws Exception {
        //获取字节码信息
        Class cls = Student.class;

        //通过字节码信息获取方法
        //getMethods:获取运行时类和其所以父类中被public修饰的方法
        Method[] methods = cls.getMethods();
        for (Method m : methods) {
            System.out.println(m);
        }

        //getDeclaredMethods:获取当前运行时类的全部修饰符的方法
        Method[] declaredMethods = cls.getDeclaredMethods();
        for (Method m : declaredMethods) {
            System.out.println(m);
        }

        //获取指定方法
        //获取被public修饰的无参数指定方法
        Method method1 = cls.getMethod("showInfo");
        System.out.println(method1);
        //获取被public修饰的有参数指定方法
        Method method2 = cls.getMethod("showInfo", int.class, int.class);
        System.out.println(method2);

        //获取被private修饰的指定方法
        Method method3 = cls.getDeclaredMethod("work");
        System.out.println(method3);

        //获取方法的具体结构
        //名字
        System.out.println(method1.getName());

        //修饰符
        //返回结果是修饰符对应的数字
        int modifiers = method1.getModifiers();
//        System.out.println(modifiers);//1
        System.out.println(Modifier.toString(modifiers));

        //返回值
        Class returnType = method3.getReturnType();
        System.out.println(returnType);

        //获取参数列表,返回值是一个列表
        Parameter[] parameters = method3.getParameters();
        for (Parameter p : parameters) {
            System.out.println(p);//此处无输出内容,因为无参数
        }

        //注解
        Method myMethod = cls.getMethod("myMethod");
        Annotation[] annotations = myMethod.getAnnotations();
        for (Annotation a : annotations) {
            System.out.println(a);
            //只能获取一个注解,因为@Override注解的生命周期只在编译期
        }

        //获取异常,返回值是一个列表
        Class[] exceptionTypes = myMethod.getExceptionTypes();
        for (Class c : exceptionTypes) {
            System.out.println(c);
        }

        //调用方法
        Object o2 = cls.newInstance();
        //调用o2对象的myMethod方法
        System.out.println(myMethod.invoke(o2));
        System.out.println(method2.invoke(o2, 12, 25));
    }
}

获取类的接口,所在包,注解

test类

java 复制代码
package com.mm.Reflect;

import java.lang.annotation.Annotation;

public class test {
    public static void main(String[] args) throws Exception {
        //获取字节码信息
        Class cls = Student.class;

        //通过字节码信息获取接口
        Class[] interfaces = cls.getInterfaces();
        for (Class c : interfaces) {
            System.out.println(c);
        }

        //获取父类接口:
        // 先得到父类的字节码信息
        Class superclass = cls.getSuperclass();
        // 再得到父类接口
        Class[] interfaces2 = superclass.getInterfaces();
        for (Class c2 : interfaces2) {
            System.out.println(c2);
        }

        //获取类所在类的包
        Package aPackage = cls.getPackage();
        System.out.println(aPackage);//package com.mm.Reflect
        System.out.println(aPackage.getName());//com.mm.Reflect

        //获取类的注解
        Annotation[] annotations = cls.getAnnotations();
        for (Annotation a : annotations) {
            System.out.println(a);
        }
    }
}
相关推荐
java水泥工10 分钟前
Java项目:基于SpringBoot和VUE的在线拍卖系统(源码+数据库+文档)
java·vue.js·spring boot
程序员岳焱22 分钟前
使用 JPype 实现 Java 与 Python 的深度交互
java·后端·python
neoooo39 分钟前
JDK 新特性全景指南:从古早版本到 JDK 17 的华丽变身
java·spring boot·后端
心月狐的流火号1 小时前
深入剖析 Java NIO Selector 处理可读事件
java
小眼睛FPGA1 小时前
【盘古100Pro+开发板实验例程】FPGA学习 | gamma 变化 | 图像实验指导手册
科技·学习·ai·fpga开发·fpga
励志不掉头发的内向程序员1 小时前
STL库——string(类模拟实现)
开发语言·c++
王廷胡_白嫖帝1 小时前
Qt文件压缩工具项目开发教程
java·开发语言·qt
subuq1 小时前
Web3.0 时代的电商系统:区块链如何解决信任与溯源问题?
大数据·网络·学习
张飞洪1 小时前
C# 13 与 .NET 9 跨平台开发实战:基于.NET 9 与 EF Core 9 的现代网站与服务开发
开发语言·c#·.net
渣哥1 小时前
Java开发必看!序列化与反序列化到底有多重要?
java