BCSP-玄子Share-Java框基础_反射

news2024/12/24 9:14:49

一、反射

1.1 反射介绍

Java反射:在编译时不确定哪个类被加载,而在程序运行时才加载、探知、使用

1.1.1 Java 程序的运行过程

在这里插入图片描述

1.1.2 反射及其作用

反射是指能够在运行时,观察并修改自己运行时(Runtime)行为的特性 Java 反射机制主要提供了以下的一些功能

  • 在运行时判断任意一个对象所属的类
  • 在运行时构造任意一个类的对象
  • 在运行时判断任意一个类所具有的属性和方法
  • 在运行时调用任意一个对象的方法

1.2 反射技术常用 API

  • java.lang.Class 类可获取类和类的成员信息
  • java.lang.reflect.Constructor 类可调用类的构造方法
  • java.lang.reflect.Field 类可访问类的属性
  • java.lang.reflect.Method 类可调用类的方法

1.2.1 使用反射的基本步骤

  1. 导入 java.lang.reflect.*
  2. 获得需要操作的类的 java.lang.Class 对象
  3. 调用Class的方法获取 Field、Method 等对象
  4. 使用反射 API 操作实例成员

1.3 反射的入口类 Class

Class 类是 Java 反射机制的起源和入口

  • 每个类都有自己向关的 Class 对象
  • 提供了获取类信息的相关方法

Class 类存放类的结构信息

  • 类名
  • 父类﹑接口
  • 构造方法﹑方法﹑属性
  • 注解
  • ……

1.3.1 获取 Class 实例

获取 Class 实例的常用方式

// 方法1:对象.getClass()
Class clazz = new Student().getClass();
// 方法2:类.class
Class clazz = Student.class;
// 方法3:Class.forName()
Class clazz = Class.forName("xxx.xxx.Student");
// 方法4:基本数据类型包装类.TYPE
Class<Integer> clazz = Integer.TYPE;

1.4 反射获取信息

1.4.1 获取类的基本信息

方法说明
String getName()以字符串形式返回该类型的名称
String getSimpleName()以字符串形式返回该类型的简称
Package getPackage()获取该类型所在的包
Class getSuperclass()返回该类型的超类的 Class 实例
Class[] getInterfaces()返回该类型所实现的全部接口的 Class 实例
int getModifiers()返回该类型的所有修饰符,由 public、protected、private、final、staic、abstract 等对应的 int 常量组成,返回的整数应使用 Modifier 工具类来解码,才可以判断修饰符的构成
Class[] getDeclaredClasses()返回该类型中包含的全部内部类的 Class 实例
Class getDeclaringClass()返回该类型所在的外部类的 Class 实例
  • 演示案例
public class Xz01 {
    public static void main(String[] args) throws ClassNotFoundException {

        Class<Student> c1 = Student.class;
        Class<?> c2 = new Student().getClass();
        Class<?> c3 = Class.forName("xuanzi.Student");

        System.out.println(c1.hashCode());
        System.out.println(c2.hashCode());
        System.out.println(c3.hashCode());
        System.out.println(c1 == c2);
//        hashCode 编码以及 内存地址一致表示同一个 Class 对象

        System.out.println("获取全类名(包含包路径):" + c1.getName());
        System.out.println("获取类名(仅类名称):" + c1.getSimpleName());
        System.out.println("获取包名(仅包名):" + c1.getPackage().getName());
        System.out.println("获取类加载器:" + c1.getClassLoader());
        System.out.println("获取父类路径:" + c1.getSuperclass().getName());
        System.out.println("获取类访问修饰符:" + c1.getModifiers());
        System.out.println("表示 PUBLIC:" + Modifier.PUBLIC);
    }
}
//    1324119927
//    1324119927
//    1324119927
//    true
//    获取全类名(包含包路径):xuanzi.Student
//    获取类名(仅类名称):Student
//    获取包名(仅包名):xuanzi
//    获取类加载器:jdk.internal.loader.ClassLoaders$AppClassLoader@63947c6b
//    获取父类路径:java.lang.Object
//    获取类访问修饰符:1
//    表示 PUBLIC:1

1.4.2 获取构造方法信息

方法说明
Constructor getConstructor(Class… params)返回该类型指定参数列表的 public 构造方法,构造方法的参数列表与 params 所指定的类型列表所匹配
Constructor[] getConstructors()返回该类型的所有 public 构造方法
Constructor getDeclaredConstructor(Class… params)返回该类型的指定参数列表的构造方法,访问级别不限
Constructor[] getDeclaredConstructors()返回该类型的所有构造方法,访问级别不限
  • 演示案例
public class Xz02 {
    public static void main(String[] args) throws NoSuchMethodException {
        Class<Student> c1 = Student.class;
        Constructor<Student> constructor = c1.getConstructor();
        Constructor<?>[] constructors = c1.getConstructors();
        Constructor<Student> declaredConstructor = c1.getDeclaredConstructor();
        Constructor<?>[] declaredConstructors = c1.getDeclaredConstructors();
        Constructor<?> declaredConstructors1 = c1.getDeclaredConstructor(String.class);

        System.out.println(constructor);
        System.out.println(Arrays.toString(constructors));
        System.out.println(declaredConstructor);
        System.out.println(Arrays.toString(declaredConstructors));
        System.out.println(declaredConstructors1);
        System.out.println("================================");
        for (Constructor<?> cc : declaredConstructors) {
            int modifier = cc.getModifiers();
            String xiu = "";
            if ((modifier & Modifier.PUBLIC) == Modifier.PUBLIC) {
                xiu = "PUBLIC";
            } else if ((modifier & Modifier.PROTECTED) == Modifier.PROTECTED) {
                xiu = "PROTECTED";
            } else if ((modifier & Modifier.FINAL) == Modifier.FINAL) {
                xiu = "FINAL";
            } else if ((modifier & Modifier.ABSTRACT) == Modifier.ABSTRACT) {
                xiu = "ABSTRACT";
            } else if ((modifier & Modifier.PRIVATE) == Modifier.PRIVATE) {
                xiu = "PRIVATE";
            } else {
                xiu = "未知";
            }
            System.out.println(xiu);
        }
        System.out.println("================================");
        Class<?>[] parameterTypes = declaredConstructors1.getParameterTypes();
        if (parameterTypes.length == 0) {
            System.out.println("无参");
        } else {
            for (int i = parameterTypes.length - 1; i >= 0; i--) {
                System.out.println(parameterTypes[i].getSimpleName());
            }
        }
        System.out.println("================================");
    }
}
//    public xuanzi.Student()
//    [public xuanzi.Student(java.lang.String,int,char), public xuanzi.Student()]
//    public xuanzi.Student()
//    [public xuanzi.Student(java.lang.String,int,char), public xuanzi.Student(), protected xuanzi.Student(java.lang.String), private xuanzi.Student(java.lang.String,int)]
//    protected xuanzi.Student(java.lang.String)
//    ================================
//    PUBLIC
//    PUBLIC
//    PROTECTED
//    PRIVATE
//    ================================
//    String
//    ================================

1.4.3 获取属性信息

方法说明
Field getField(String name)返回该类型中指定名称的 public 属性,name 参数用于指定属性名称
Field[] getFields()返回该类型中所有 public 属性
Field getDeclaredField(String name)返回该类型中指定名称的属性,与属性的访问级别无关
Field[] getDeclaredFields()返回该类型中的全部属性,与属性的访问级别无关
  • 演示案例
public class Xz03 {
    public static void main(String[] args) throws NoSuchMethodException, NoSuchFieldException {
        Class<Student> c1 = Student.class;
        Field[] fields = c1.getFields();
        Field name = c1.getField("name");
        Field declaredName = c1.getDeclaredField("name");
        Field[] declaredFields = c1.getDeclaredFields();
        
        System.out.println(Arrays.toString(fields));
        System.out.println(name);
        System.out.println(declaredName);
        System.out.println(Arrays.toString(declaredFields));
        System.out.println("================================");
        for (Field df : declaredFields) {
            int modifier = df.getModifiers();
            String xiu = "";
            if ((modifier & Modifier.PUBLIC) == Modifier.PUBLIC) {
                xiu = "PUBLIC";
            } else if ((modifier & Modifier.PROTECTED) == Modifier.PROTECTED) {
                xiu = "PROTECTED";
            } else if ((modifier & Modifier.FINAL) == Modifier.FINAL) {
                xiu = "FINAL";
            } else if ((modifier & Modifier.ABSTRACT) == Modifier.ABSTRACT) {
                xiu = "ABSTRACT";
            } else if ((modifier & Modifier.PRIVATE) == Modifier.PRIVATE) {
                xiu = "PRIVATE";
            } else {
                xiu = "未知";
            }
            System.out.println(xiu);
        }
        System.out.println("================================");
        for (Field declaredField : declaredFields) {
            System.out.print(declaredField.getModifiers() + " - ");
            System.out.print(declaredField.getName() + " - ");
            System.out.print(declaredField.getType() + " - ");
            System.out.println();
        }
        System.out.println("================================");
    }
}
//    [public java.lang.String xuanzi.Student.name, public int xuanzi.Student.age]
//    public java.lang.String xuanzi.Student.name
//    public java.lang.String xuanzi.Student.name
//    [public java.lang.String xuanzi.Student.name, public int xuanzi.Student.age, private char xuanzi.Student.gender]
//    ================================
//    PUBLIC
//    PUBLIC
//    PRIVATE
//    ================================
//    1 - name - class java.lang.String -
//    1 - age - int -
//    2 - gender - char -
//    ================================

1.4.4 获取方法信息

方法说明
Method getMethod(String name, Class… params)返回该实例中指定的 public 方法,name 参数用于指定方法名称,params 参数指定参数列表
Method[] getMethods()返回该实例中所有 public 方法
Method getDeclaredMethod(String name, Class… params)返回该实例中指定的方法,与方法的访问级别无关
Method[] getDeclaredMethods()返回该实例中的全部方法,与方法的访问级别无关
  • 演示案例
public class Xz04 {
    public static void main(String[] args) throws NoSuchMethodException {
        Class<Student> c1 = Student.class;
        Method[] methods = c1.getMethods();
        Method getStudent = c1.getMethod("setName", String.class);
        Method[] declaredMethods = c1.getDeclaredMethods();
        Method declaredMethod = c1.getDeclaredMethod("getGender");
        System.out.println(getStudent);
        System.out.println(Arrays.toString(methods));
        System.out.println(Arrays.toString(declaredMethods));
        System.out.println(declaredMethod);
        System.out.println("================================");
        for (Method dm : declaredMethods) {
            int modifier = dm.getModifiers();
            String xiu = "";
            if ((modifier & Modifier.PUBLIC) == Modifier.PUBLIC) {
                xiu = "PUBLIC";
            } else if ((modifier & Modifier.PROTECTED) == Modifier.PROTECTED) {
                xiu = "PROTECTED";
            } else if ((modifier & Modifier.FINAL) == Modifier.FINAL) {
                xiu = "FINAL";
            } else if ((modifier & Modifier.ABSTRACT) == Modifier.ABSTRACT) {
                xiu = "ABSTRACT";
            } else if ((modifier & Modifier.PRIVATE) == Modifier.PRIVATE) {
                xiu = "PRIVATE";
            } else {
                xiu = "未知";
            }
            System.out.println(xiu);
        }
        System.out.println("================================");
        for (Method declaredField : declaredMethods) {
            System.out.print((declaredField.getModifiers() == Modifier.PUBLIC ? "PUBLIC" : "PRIVATE") + " - ");
            System.out.print(declaredField.getName() + " - ");
            System.out.print(declaredField.getReturnType().getSimpleName() + " - ");
            System.out.print(Arrays.toString(declaredField.getParameterTypes()) + " - ");
            System.out.print(Arrays.toString(declaredField.getExceptionTypes()) + " - ");
            System.out.println();
        }
        System.out.println("================================");
    }
}
//    public void xuanzi.Student.setName(java.lang.String)
//    [public java.lang.String xuanzi.Student.getName(), public java.lang.String xuanzi.Student.toString() throws java.lang.IllegalArgumentException,java.lang.ArithmeticException, public void xuanzi.Student.setName(java.lang.String), public int xuanzi.Student.getAge(), public void xuanzi.Student.setAge(int), public void xuanzi.Student.setGender(char), public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException, public final void java.lang.Object.wait() throws java.lang.InterruptedException, public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException, public boolean java.lang.Object.equals(java.lang.Object), public native int java.lang.Object.hashCode(), public final native java.lang.Class java.lang.Object.getClass(), public final native void java.lang.Object.notify(), public final native void java.lang.Object.notifyAll()]
//    [public java.lang.String xuanzi.Student.getName(), public java.lang.String xuanzi.Student.toString() throws java.lang.IllegalArgumentException,java.lang.ArithmeticException, public void xuanzi.Student.setName(java.lang.String), private char xuanzi.Student.getGender(), public int xuanzi.Student.getAge(), public void xuanzi.Student.setAge(int), private java.lang.String xuanzi.Student.show(java.lang.String,int,char), public void xuanzi.Student.setGender(char)]
//    private char xuanzi.Student.getGender()
//    ================================
//    PUBLIC
//    PUBLIC
//    PUBLIC
//    PRIVATE
//    PUBLIC
//    PUBLIC
//    PRIVATE
//    PUBLIC
//    ================================
//    PUBLIC - getName - String - [] - [] -
//    PUBLIC - toString - String - [] - [class java.lang.IllegalArgumentException, class java.lang.ArithmeticException] -
//    PUBLIC - setName - void - [class java.lang.String] - [] -
//    PRIVATE - getGender - char - [] - [] -
//    PUBLIC - getAge - int - [] - [] -
//    PUBLIC - setAge - void - [int] - [] -
//    PRIVATE - show - String - [class java.lang.String, int, char] - [] -
//    PUBLIC - setGender - void - [char] - [] -
//    ================================

1.5 反射实例化对象

1.5.1 通过反射实现类的实例化

  • java.lang.Class
Student student = Student.class.newInstance();
//        通过 class 获取对象		
  • java.lang.reflect.Constructor
Student student = Student.class.getConstructor().newInstance();
//        通过构造获取对象
  • 演示案例
public class Xz05 {
    public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Student student = new Student();
//        直接 new 对象
        Student student1 = Student.class.newInstance();
//        通过 class 获取对象
        Student student2 = Student.class.getConstructor().newInstance();
//        通过构造获取对象
        Constructor<Student> studentConstructor = Student.class.getConstructor(String.class, char.class);
        studentConstructor.setAccessible(true);
//        通过有参构造获取对象
        Student student3 = studentConstructor.newInstance("XuanZi", '男');
        Constructor<Student> studentConstructor1 = Student.class.getDeclaredConstructor(String.class, int.class);
        studentConstructor1.setAccessible(true);
//      可设置私有构造函数
        Student student4 = studentConstructor1.newInstance("XuanZi", 12);
        System.out.println(student);
        System.out.println(student1);
        System.out.println(student2);
        System.out.println(student3);
        System.out.println(student4);
    }
}
//    xuanzi.Student{name='null', age=0, gender= }
//    xuanzi.Student{name='null', age=0, gender= }
//    xuanzi.Student{name='null', age=0, gender= }
//    xuanzi.Student{name='XuanZi', age=0, gender=男}
//    xuanzi.Student{name='XuanZi', age=12, gender= }

1.5.2 通过反射访问实例的字段

java.lang.reflect.Field

方法说明
xxx getXxx(Object obj)xxx 表示8种基本数据类型之一,若 Field 实例表示的是一个静态属性,则 obj 可以设置为 null
Object get(Object obj)以 Object 类型返回 obj 中相关属性的值
void setXxx(Object obj, xxx val)将 obj 中相关属性的值设置为 val。xxx 为8种基本数据类型之一
void set(Object obj, Object val)将 obj 中相关属性的值设置为 val
void setAccessible(boolean flag)对相关属性设置访问权限。设置为 true 可以禁止 Java 语言访问检查
  • 演示案例
public class Xz06 {
    public static void main(String[] args) throws NoSuchFieldException, InstantiationException, IllegalAccessException {
        Class<Student> studentClass = Student.class;
        Student student = studentClass.newInstance();
        Field name = studentClass.getField("name");
        System.out.println(name.get(student));
        
        name.set(student, "玄子");
        
        System.out.println(name.get(student));
    }
}
//    null
//    玄子

1.5.3 通过反射调用实例的方法

java.lang.reflect.Method

public  Object  invoke( Object obj, Object...  args )
  • Object:返回值
  • Object obj:执行该方法的对象
  • Object… args:执行该方法时传入的参数
  • 演示案例
public class Xz07 {
    public static void main(String[] args) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException, InstantiationException {
        Class<Student> studentClass = Student.class;
        Student student = studentClass.newInstance();
        Method name = studentClass.getMethod("setName", String.class);
        
        name.invoke(student, "张三");
        
        System.out.println(student);
    }
}
//    xuanzi.Student{name='张三', age=0, gender= }

1.6 反射的优缺点

1.6.1 优点

  • 允许程序创建和控制任何类的对象,无需提前硬编码目标类
  • 提高了 Java 程序的灵活性和扩展性,降低了耦合性,提高自适应能力
  • 反射的应用领域:开源框架,如 MyBatis、Spring 等

1.6.2 缺点

  • 性能问题:反射机制主要应用在对灵活性和扩展性要求很高的系统框架上
  • 代码维护问题:反射会模糊程序内部逻辑,可读性较差,且反射可能会破坏封装

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/972837.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

verilog语法之case casez casex

在rtl仿真中&#xff0c;有四种状态&#xff0c;分别是0、1、x&#xff08;unknown values&#xff09;和z&#xff08;high-impedance values&#xff09;。 case 结构体中&#xff1a;0&#xff0c;1&#xff0c;X与Z是四种不同的状态&#xff0c;case条件比较时会检测比较双…

2023年03月 C/C++(七级)真题解析#中国电子学会#全国青少年软件编程等级考试

C/C编程&#xff08;1~8级&#xff09;全部真题・点这里 第1题&#xff1a;走出迷宫 当你站在一个迷宫里的时候&#xff0c;往往会被错综复杂的道路弄得失去方向感&#xff0c;如果你能得到迷宫地图&#xff0c;事情就会变得非常简单。 假设你已经得到了一个n*m的迷宫的图纸&a…

BCSP-玄子Share-Java框基础_工厂模式/代理模式

三、设计模式 3.1 设计模式简介 软件设计中的三十六计是人们在长期的软件开发中的经验总结是对某些特定问题的经过实践检验的特定解决方法被广泛运用在 Java 框架技术中 3.1.1 设计模式的优点 设计模式是可复用的面向对象软件的基础可以更加简单方便地复用成功的设计和体系…

【管理运筹学】第 7 章 | 图与网络分析(2,最小支撑树问题)

文章目录 引言二、最小支撑树问题2.1 树的定义及其基本性质2.2 图的支撑树2.3 最小支撑树的定义及有关定理2.4 最小支撑树算法2.4.1 避圈法&#xff08;KRUSKAL算法&#xff09;2.4.2 反圈法&#xff08;PRIM算法&#xff09;2.4.3 破圈法 写在最后 引言 承接前文&#xff0c;…

宠物电商Chewy第二季度销售额28亿美元,同比增长14.3%

美国宠物电商Chewy公布2023年第二季度财报。报告显示&#xff0c;其Q2季度销售额同比增长14.3%至28亿美元&#xff0c;超出市场预期。 以下为Chewy期内业绩概要&#xff1a; 1.毛利率28.3%&#xff0c;同比增长20个基点 2.净利润有所收窄&#xff0c;同比下降15.2%至1890万美…

QT连接数据库

目录 数据库 数据库基本概念 常用的数据库 SQLite3基础 SQLite特性&#xff1a; QT连接数据库 1.1 QT将数据库分为三个层次 1.2 实现数据库操作的相关方法 sql语句&#xff08;常用&#xff09; 1&#xff09;创建表格 2&#xff09;删除表格 3&#xff09;插入记录 …

应急物资管理系统DW-S300|助力应急物资保障体系建设

国务院新闻办公室于2023年7月25日举行国务院政策例行吹风会&#xff0c;介绍防汛抗旱工作情况&#xff0c;并答记者问。应急管理部副部长、水利部副部长王道席介绍&#xff0c;要推进应急物资保障体系建设。去年&#xff0c;应急管理部会同国家发展改革委、财政部、国家粮食和物…

AIGC专栏5——EasyPhoto AI写真照片生成器 sd-webui插件介绍、安装与使用

AIGC专栏5——EasyPhoto AI写真照片生成器 插件安装与使用 学习前言源码下载地址技术原理储备&#xff08;SD/Control/Lora&#xff09;StableDiffusionControlNetLora EasyPhoto插件简介EasyPhoto插件安装安装方式一&#xff1a;Webui界面安装 &#xff08;需要良好的网络&…

Linux监测进程打开文件

分析问题过程中&#xff0c;追踪进程打开的文件可以在许多不同情况下有用&#xff0c;体现在以下几个方面&#xff1a; 故障排除和调试&#xff1a; 当程序出现问题、崩溃或异常行为时&#xff0c;追踪进程打开的文件可以帮助找出问题的根本原因。这有助于快速定位错误&#x…

深入解析 curl:掌握命令行的网络传输利器

当我们使用 curl 进行网络请求时&#xff0c;了解如何有效地使用参数是非常重要的。curl 提供了许多参数&#xff0c;用于控制请求的行为和配置。在这篇博客文章中&#xff0c;我们将详细解释一些常用的 curl 参数&#xff0c;帮助你更好地理解如何利用这个强大的工具。 什么是…

兵者多诡(HCTF2016)

环境:https://github.com/MartinxMax/CTFer_Zero_one 题目简介 解题过程 登录首页 提交png图片上传抓包&#xff0c;可以看到是向upload文件提交数据 在fp参数中尝试伪协议读取home.php文件 http://127.0.0.1:88/HCTF2016-LFI/home.php?fpphp://filter/readconvert.base64…

将YOLO数据集按照指定比例划分(训练集、验证集、测试集)的详细教程

1.将训练集、验证集、测试集按照7:2:1随机划分 1.项目准备 1.在项目下新建一个py文件&#xff0c;名字就叫做splitDataset1.py 2.将自己需要划分的原数据集就放在项目文件夹下面 以我的为例&#xff0c;我的原数据集名字叫做hatDataXml 里面的JPEGImages装的是图片 Annota…

【物联网】磁介质存储设备——机械硬盘

磁介质存储设备是一种使用磁性材料作为存储介质的设备&#xff0c;用于存储和读取数据。常见的磁介质存储设备包括硬盘驱动器&#xff08;HDD&#xff09;、软盘驱动器和磁带。 文章目录 一、机械硬盘存储器的基本结构与分类1.1 基本结构1.2 分类 二、硬盘的信息分布三、机械硬…

计算机网络的故事——HTTP报文内的HTTP信息

HTTP报文内的HTTP信息 文章目录 HTTP报文内的HTTP信息一、HTTP 报文二、请求报文及响应报文的结构三、编码提升传输速率 一、HTTP 报文 HTTP报文是由多行&#xff08;CRLF作换行符&#xff09;数据构成的字符串文本&#xff0c;HTTP报文可以分为报文首部和报文主体两部分&…

Android ChatCPT集成

准备工作 ChatGPT账号(openai) 集成好网络框架(默认使用Retrofit) 接入 选择modele 这里使用的是 「https://api.openai.com/v1/chat/completions」 创建API Keys 运行效果 POST https://api.openai.com/v1/chat/completions Content-Type: application/json Content-Length:…

RHCA之路---EX280(8)

RHCA之路—EX280(8) 1. 题目 On master.lab.example.com using the template file in http://materials.example.com/exam280/gogs as a basis, install an application in the ditto project according to the following requirements: All of the registry entries must poi…

AndroidTV端:酒店扫码认证投屏DLNA

被老板叼了几次了&#xff0c;最近实在忍不了&#xff0c;准备离职&#xff1b; 但是担心离职后长时间没有办法找到工作 就想贡献一套平时琢磨出来的程序&#xff0c;请各位有能力的话带我熬过这凛冽的寒冬。 目前写出来的&#xff0c;有三个端&#xff1a;安卓TV端&#xf…

Kali之BurpSuite_pro安装配置

文章目录 配置jdk环境安装BurpSuitePro设置快捷方式启动方式 BurpSuite2021专业版本地址&#xff1a; 下载链接&#xff1a;https://pan.baidu.com/s/1PjzcukRDoc_ZFjrNxI8UjA 提取码&#xff1a;nwm7 我的安装工具都在/home/kali/tools/ 解压后我放在burpsuite_pro目录下 把j…

Harbor 私人(企业)docker镜像仓库部署

目录 一、资源下载二、配置前准备三、配置harbor.yml文件四、安装五、上传镜像到Harbor docker镜像仓库 一、资源下载 在GitHub上可以找到相关的下载&#xff1a;https://github.com/goharbor/harbor/releases 或者Linux直接wget&#xff1a; ┌──(root㉿kali)-[~] └─# w…

飞行动力学 - 第17节-航向静稳定性 之 基础点摘要

飞行动力学 - 第17节-航向静稳定性 之 基础点摘要 1. 航向静稳定性2. 航向静稳定性的组成3. 参考资料 1. 航向静稳定性 飞机受到侧滑扰动后&#xff0c;如果能产生使机头指向原来方向的力矩&#xff0c;抵消侧滑&#xff0c;则称为航向静稳定性。 2. 航向静稳定性的组成 飞机…