java Class类详解
Class类简介
在 java 世界里,一切皆对象。从某种意义上来说,java 有两种对象:实例对象和 Class 对象。每个类的运行时的类型信息就是用 Class 对象表示的,它包含了与类有关的信息,实例对象就是通过 Class 对象来创建的。Java 使用 Class 对象执行其 RTTI (运行时类型识别,Run-Time Type Identification),多态就是基于 RTTI 实现的。
每一个类都有一个 Class 对象,每当编译一个新类就产生一个 Class 对象,基本类型 (boolean, byte, char, short, int, long, float, double)有 Class 对象,就连关键字 void 也有 Class 对象(void.class)。Class 对象对应着 java.lang.Class 类,如果说类是对象的抽象和集合,那么 Class 类就是对类的抽象和集合。
Class 类只有一个私有的构造方法,不能通过 new 关键字来创建,而是在类加载的时候由 Java 虚拟机以及类加载器来自动构造的。
所有的类都是在对其第一次使用时,动态加载到 JVM 中的(懒加载)。当程序创建第一个对类的静态成员的引用时,就会加载这个类。使用 new 创建类对象的时候也会被当作对类的静态成员的引用。因此 java 程序在它开始运行之前并非被完全加载,其各个类都是在必需时才加载的。
在类加载阶段,类加载器首先检查这个类的 Class 对象是否已经被加载。如果尚未加载,默认的类加载器就会根据类的全限定名查找 .class文件。在这个类的字节码被加载时,它们会接受验证,以确保其没有被破坏,并且不包含不良 java 代码。一旦某个类的 Class 对象被载入内存,我们就可以它来创建这个类的所有对象。
获取 Class 对象的方式
有三种获得 Class 对象的方式:
Class.forName(“类的全限定名”)
实例对象 .getClass()
类名 .class (类字面常量)
第一种方式示例代码如下:
public class Dog {static {System.out.println("Loading Dog");}
}public class Cat {static {System.out.println("Loading Cat");}
}public class GetClassSimple {public static void main(String[] args) {Dog dog = new Dog();try {Class<?> cat = Class.forName("fanda.zeng.reflect.Cat");Class<?> dog2 = Class.forName("fanda.zeng.reflect.Dog");} catch (ClassNotFoundException e) {System.out.println("can not find class");e.printStackTrace();}}
}
输出:
Loading Dog
Loading Cat
上述的 static{} 代码块只会在第一次加载类的时候被调用,由输出结果得知,new 对象和调用Class.forName 时会判断类是否已经加载,没有加载则会调用类加载器来加载类,已经加载过了,不会重复加载。Class.forName 的好处就在于,不需要为了获得 Class 引用而持有该类型的对象,只要通过全限定名就可以返回该类型的一个 Class 引用。
第二种方式示例代码如下:
Dog dog = new Dog();
Class<?> clazz = dog.getClass();
输出:
Loading Dog
如果你已经有了该类型的对象,那么我们就可以通过调用 getClass() 方法来获取 Class 引用了,这个方法属于根类 Object 的一部分,它返回的是表示该对象的实际类型的 Class 引用。因为 new 操作已经把类加载到内存了,所有 getClass 方法不会再去执行类加载了,而是直接从 java 堆中返回该类型的 Class 引用。
第三种方式示例代码如下:
Class c1 = Integer.class;
Class c2 = int.class;
Class c3 = Integer.TYPE;Class dog = Dog.class;
Class cat = Cat.class;System.out.println(c1);
System.out.println(c2);
System.out.println(c3);
输出:
class java.lang.Integer
int
int
这种方式在编译时就会受到检查(因此不需要置于try语句块中),不仅可以应用于普通的类,也可以应用于接口、数组及基本数据类型。上述 c2 等价于 c3 ,因为在包装类中有个一个字段 TYPE ,TYPE 字段是一个引用,指向对应的基本数据类型的 Class 对象,因此不只 Integer 包装类,其他 7 种包装类以及 Void 类型都有对应的 TYPE 字段。
注意:上述代码没有打印 Dog 和 Cat 静态代码块的内存,因为用 .class 来创建 Class 对象的引用时,不会自动地初始化该 Class 对象,类加载被延迟到了对静态方法或者非常数静态域首次引用时才执行。示例代码如下:
public class Dog {static final String DOG_CONSTANT = "DOG_CONSTANT";static String staticValue = "dog_staticValue";static {System.out.println("Loading Dog");}
}Class dog = Dog.class;
System.out.println("===== 常量 =====");
System.out.println(Dog.DOG_CONSTANT);
System.out.println("===== 静态成员 =====");
System.out.println(Dog.staticValue);
输出:
===== 常量 =====
DOG_CONSTANT
===== 静态成员 =====
Loading Dog
dog_staticValue
由输出结果可知,当引用 staticValue 时,类被加载到内存并执行了静态代码块的内容。因为被 static final 修饰的属性在编译期就把结果放入常量池了,所以引用的时候并不需要类真正地被加载。但是,如果只是将一个域设置为 static 或 final 的,还不足以确保这种行为,此时引用会强制加载并初始化类。
Class 对象的唯一性
每个通过关键字 class 标识的类,在内存中有且只有一个与之对应的 Class 对象来描述其类型信息,不论通过哪种方式获得该类的 Class 对象,它们返回的都是指向同一个 java 堆地址上的 Class 引用,jvm 不会创建两个相同类型的 Class。也就是说,无论创建多少个实例对象,其依据的都是同一个 Class 对象。java 虚拟机中使用双亲委派模型来组织类加载器之间的关系,来保证 Class 对象的唯一性。验证代码如下:
Class dog = Dog.class;
Class dog2 = Class.forName("fanda.zeng.reflect.Dog");
Class dog3 = new Dog().getClass();
Class dog4 = new Dog().getClass() ;if (dog == dog2 && dog2 == dog3 && dog3 == dog4) {System.out.println(true);
} else {System.out.println(false);
}
输出结果为 true ,表示都是同一个堆上的 Class 引用。
Class 类的方法
先说明一下,构造方法都是获取本类的(一定不包括父类),只是公共和其他修饰符的区别。以下其他带有 Declared 的方法,都表示只能获取本类的属性(不包括父类的),不过可以获取所有修饰符修饰的属性(公有,保护,默认,私有)。不带有 Declared 的方法,可以获取本类及父类的所有的属性,不过只能获取 公有 修饰符的 。
获取构造函数
//返回 Constructor 对象数组
Constructor<?>[] getDeclaredConstructors()
Constructor<?>[] getConstructors() // 返回指定参数的 Constructor 对象
Constructor<T> getConstructor(Class<?>... parameterTypes)
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
获取成员变量
// 返回 Field 对象数组
Field[] getFields()
Field[] getDeclaredFields() // 返回指定的 Field 对象
Field getField(String name)
Field getDeclaredField(String name)
获取成员方法
// 返回 Method 对象数组
Method[] getMethods()
Method[] getDeclaredMethods() / 返回指定的 Method 对象
Method getMethod(String name, Class<?>... parameterTypes)
Method getDeclaredMethod(String name, Class<?>... parameterTypes)
获取注解方法
// 返回指定 Annotation 对象
public <A extends Annotation> A getDeclaredAnnotation(Class<A> annotationClass) {
public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {// 返回 Annotation 对象数组
Annotation[] getDeclaredAnnotations()
public Annotation[] getAnnotations ()
创建对象的方法
// 创建此 Class 对象所表示的类的一个新实例
T newInstance()
返回字符串(String)的方法
// 返回底层类的规范化名称
String getCanonicalName() // 返回全限定名(全限定名:包名.类名)
String getName() // 返回源代码中给出的底层类的简称
String getSimpleName()
返回 boolean 的方法
// 判断是不是局部类,也就是方法里面的类
boolean isLocalClass() // 判断是不是成员内部类,也就是一个类里面定义的类
boolean isMemberClass() // 判断当前类是不是匿名类,匿名类一般用于实例化接口
boolean isAnonymousClass() // 如果指定类型的注释存在于此元素上
isAnnotationPresent (Class<? extends Annotation> annotationClass)// 判断当前Class对象是否是注释类型
boolean isAnnotation() ;// 判断该类是否是枚举类
boolean isEnum() // 判断指定的 Object 是否 Class 的实例
boolean isInstance(Object obj) // 判断指定的 Class 对象是否表示一个接口类型
boolean isInterface() // 判断指定的 Class 对象是否表示一个基本类型
boolean isPrimitive()
获取 Class 的修饰符
//返回此类或接口以整数编码的 Java 语言修饰符。
public int getModifiers();修饰符是java.lang.reflect.Modifier的静态属性。对应表如下:PUBLIC: 1
PRIVATE: 2
PROTECTED: 4
STATIC: 8
FINAL: 16
SYNCHRONIZED: 32
VOLATILE: 64
TRANSIENT: 128
NATIVE: 256
INTERFACE: 512
ABSTRACT: 1024
STRICT: 2048
我们可以使用 Class.getModifiers() 获得调用类的修饰符的二进制值,然后使
用 Modifier.toString(int modifiers) 将获取到的二进制值转换为字符串。
代码示例
// 动物类
public class Animal {private int mAnimalPrivate;protected int mAnimalProtected;public int mAnimalpublic;public Animal() {}public Animal(int mAnimalPrivate) {this.mAnimalPrivate = mAnimalPrivate;}public Animal(int mAnimalPrivate, int mAnimalProtected) {this.mAnimalPrivate = mAnimalPrivate;this.mAnimalProtected = mAnimalProtected;}public Animal(int mAnimalPrivate, int mAnimalProtected, int mAnimalpublic) {this.mAnimalPrivate = mAnimalPrivate;this.mAnimalProtected = mAnimalProtected;this.mAnimalpublic = mAnimalpublic;}public void animalPublic() {System.out.println("Method : animalPublic");}private void animalPrivate() {System.out.println("Method : animalPrivate");}protected void animalProtected() {System.out.println("Method : animalProtected");}}// 猫类,继承动物类
public class Cat extends Animal {static {System.out.println("Loading Cat");}private int mCatPrivate;protected int mCatProtected;public int mCatpublic;public Cat() {}public Cat(int mCatPrivate) {this.mCatPrivate = mCatPrivate;}private Cat(int mCatPrivate, int mCatProtected) {this.mCatPrivate = mCatPrivate;this.mCatProtected = mCatProtected;}public void catPublic() {System.out.println("Method : catPublic");}private void catPrivate() {System.out.println("Method : catPrivate");}protected void catProtected() {System.out.println("Method : catProtected");}@Overridepublic String toString() {return "mCatPrivate = " + mCatPrivate + "-----------" + "mCatProtected = " + mCatProtected + "-----------" + "mCatpublic = " + mCatpublic;}
}
获取构造函数示例:
public static void main(String[] args) throws Exception {Class clazz = Cat.class;System.out.println("获取本类所有 public 构造方法");for (Constructor constructor : clazz.getConstructors()) {System.out.println(constructor.toString());}System.out.println();System.out.println("获取本类所有构造方法");for (Constructor declaredConstructor : clazz.getDeclaredConstructors()) {System.out.println(declaredConstructor.toString());}System.out.println();System.out.println("这里获取指定的带有两个参数的私有构造方法");Constructor privateConstructor = clazz.getDeclaredConstructor(int.class, int.class);System.out.println(privateConstructor.toString());// 改变访问权限privateConstructor.setAccessible(true);Cat cat = (Cat) privateConstructor.newInstance(1, 2);System.out.println(cat.toString());System.out.println();System.out.println("这里获取指定的带有一个参数的公有构造方法");Constructor publicConstructor = clazz.getConstructor(int.class);System.out.println(publicConstructor.toString());Cat cat2 = (Cat) publicConstructor.newInstance(100);System.out.println(cat2.toString());
}
输出:
获取本类所有 public 构造方法
public fanda.zeng.reflect.Cat(int)
public fanda.zeng.reflect.Cat()获取本类所有构造方法
private fanda.zeng.reflect.Cat(int,int)
public fanda.zeng.reflect.Cat(int)
public fanda.zeng.reflect.Cat()这里获取指定的带有两个参数的私有构造方法
private fanda.zeng.reflect.Cat(int,int)
Loading Cat
mCatPrivate = 1-----------mCatProtected = 2-----------mCatpublic = 0这里获取指定的带有一个参数的公有构造方法
public fanda.zeng.reflect.Cat(int)
mCatPrivate = 100-----------mCatProtected = 0-----------mCatpublic = 0
获取成员变量示例:
public static void main(String[] args) throws Exception {Class clazz = Cat.class;System.out.println("获取所有 public 成员变量");for (Field field : clazz.getFields()) {System.out.println(field.toString());}System.out.println();System.out.println("获取本类所有成员变量");for (Field field : clazz.getDeclaredFields()) {System.out.println(field.toString());}System.out.println();System.out.println("这里获取指定名字的成员变量");Field mCatPrivateField = clazz.getDeclaredField("mCatPrivate");System.out.println(mCatPrivateField.toString());// 改变访问权限mCatPrivateField.setAccessible(true);Cat cat = new Cat();mCatPrivateField.set(cat, 100);System.out.println(cat.toString());}
输出:
获取所有 public 成员变量
public int fanda.zeng.reflect.Cat.mCatpublic
public int fanda.zeng.reflect.Animal.mAnimalpublic获取本类所有成员变量
private int fanda.zeng.reflect.Cat.mCatPrivate
protected int fanda.zeng.reflect.Cat.mCatProtected
public int fanda.zeng.reflect.Cat.mCatpublic这里获取指定名字的成员变量
private int fanda.zeng.reflect.Cat.mCatPrivate
Loading Cat
mCatPrivate = 100-----------mCatProtected = 0-----------mCatpublic = 0
获取成员方法示例:
public static void main(String[] args) throws Exception {Class clazz = Cat.class;System.out.println("获取所有 public 成员方法");for (Method method : clazz.getMethods()) {System.out.println(method.toString());}System.out.println();System.out.println("获取本类所有成员方法");for (Method method : clazz.getDeclaredMethods()) {System.out.println(method.toString());}System.out.println();System.out.println("这里获取指定名字的成员方法");Method catPrivateMethod = clazz.getDeclaredMethod("catPrivate");System.out.println(catPrivateMethod.toString());// 改变访问权限catPrivateMethod.setAccessible(true);Cat cat = new Cat();catPrivateMethod.invoke(cat);
}
输出:
获取所有 public 成员方法
public java.lang.String fanda.zeng.reflect.Cat.toString()
public void fanda.zeng.reflect.Cat.catPublic()
public void fanda.zeng.reflect.Animal.animalPublic()
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 fanda.zeng.reflect.Cat.toString()
public void fanda.zeng.reflect.Cat.catPublic()
protected void fanda.zeng.reflect.Cat.catProtected()
private void fanda.zeng.reflect.Cat.catPrivate()这里获取指定名字的成员方法
private void fanda.zeng.reflect.Cat.catPrivate()
Loading Cat
Method : catPrivate
上述获取所有公共方法时,包括本类及所有的父类的公共方法都会查找出来。
相关文章:
java Class类详解
Class类简介 在 java 世界里,一切皆对象。从某种意义上来说,java 有两种对象:实例对象和 Class 对象。每个类的运行时的类型信息就是用 Class 对象表示的,它包含了与类有关的信息,实例对象就是通过 Class 对象来创建的…...
DMGI:Unsupervised Attributed Multiplex Network Embedding
[1911.06750] Unsupervised Attributed Multiplex Network Embedding (arxiv.org) 目录 Abstract 1 Introduction 2 DGI 3 Deep Multiplex Graph Infomax: DMGI 特定关系类型的节点嵌入 Joint Modeling and Consensus Regularization Extension to Semi-Supervised Lea…...
C++基本介绍
文章目录 🥭1.C基本介绍🧂1.1 C是什么🧂1.2 C发展史 🍒2. C的优势🥔2.1 语言的使用广泛度🥔2.2 C的应用领域 🫒3. C学习计划 🥭1.C基本介绍 🧂1.1 C是什么 C是一种通用…...
如何理解工业互联网与智能制造,怎么共建智慧工厂?
第六届数字中国建设峰会26日在福州开幕,在这个数字化新技术的变革风口,企业如何把握机遇,借工业互联网和智能制造实现智慧工厂建设? 探讨三个问题: 什么是工业互联网、智能制造、智慧工厂;它们三者之间的…...
主机访问不到虚拟机(centos7)web服务的解决办法
目录 一、背景 二、解决办法 2.1、配置虚拟机防火墙 2.2、修改虚拟机网络编辑器 一、背景 主机可以访问外网,虚拟机使用命令:curl http://网址,可以访问到web服务 ,主机使用http://网址,访问不到虚拟机(…...
第四章 ActiveMQ与SpringBoot集成——ActiveMQ笔记(动力节点)
第四章 ActiveMQ 与 SpringBoot 集成 4-1 ActiveMQ 与 SpringBoot 集成集成配置 1、加载 spring boot 的 activeMQ 的依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </de…...
Halcon 算子 select_shape_std 和 select_shape_xld区别
文章目录 1 select_shape_std 算子介绍2 select_shape_xld算子介绍3 select_shape_std 和 select_shape_xld区别4 Halcon 算子的特征 Features 列表介绍1 select_shape_std 算子介绍 select_shape_std (Operator) Name select_shape_std — Select regions of a given shape.Si…...
【Java基础】匿名内部类
🎊专栏【Java基础】 🍔喜欢的诗句:更喜岷山千里雪 三军过后尽开颜。 🎆音乐分享【The truth that you leave】 大一同学小吉,欢迎并且感谢大家指出我的问题🥰 目录 🎁什么是匿名内部类 &#x…...
基于Freertos的ESP-IDF开发——6.使用DHT1温湿度传感器
基于Freertos的ESP-IDF开发——6.使用DHT1温湿度传感器 0. 前言1. DHT11驱动原理2. 完整代码3. 演示效果4. 其他FreeRtos文章 0. 前言 开发环境:ESP-IDF 4.3 操作系统:Windows10 专业版 开发板:自制的ESP32-WROOM-32E 准备一个DHT11温湿度传…...
C++——模板初阶
文章目录 一.泛型编程二.函数模板1.函数模板的概念2.函数模板的格式3.函数模板的原理4.函数模板的实例化(1)隐式实例化(2)显式实例化 5.模板参数的匹配原 三.类模板1.类模板的定义格式2.类模板的实例化 前言: 本章我们…...
【TOOLS: Linux与windows及linux与linux之间文件传输常用方法及命令】
文章目录 1.1.1 Windows和VirtualBox(Ubuntu)之间文件穿传输方法1.1.2 SCP 文件传输方法1.1.3 FTP 文件传输方法 1.1.1 Windows和VirtualBox(Ubuntu)之间文件穿传输方法 1)设置 virtualbox 中的共享文件夹,用户可以在windows某个盘下创建自己的共享文件…...
【博览群书】《实战大数据》——属于我的第一本大数据图书
文章目录 前言简介目录其他 前言 Hello家人们,博主前不久参加了CSDN图书馆和机械工业出版社联合举办的图书类活动,很荣幸在活动中获得了属于自己的第一本大数据图书,《实战大数据—— 分布式大数据分析处理系统开发与应用》。作为大数据专业…...
【计算机组成原理】实验二
文章目录 实验二 运算器实验一、实验目的二、实验原理三、运算器功能编码四、实验内容任务一 算术运算任务二 逻辑运算任务三 移位运算 实验二 运算器实验 一、实验目的 完成算术、逻辑、移位运算实验,熟悉ALU运算类型的控制位运用。实验仪器:JTHS-A …...
hive数据库hql基础操作02
1.内部表和外部表 默认情况下创建的表就是内部表,Hive拥有该表的结构和文件。换句话说,Hive完全管理表(元数据和数据)的生命周期,类似于RDBMS中的表。当你删除内部表时,它会删除数据以及表的元数据。可以使…...
门电路OD门
漏极开路输出的门电路(OD门) 为了满足输出电平的变换,输出大负载电流,以及实现“线与”功能,将CMOS门电路的输出级做成漏极开路的形式,称为漏极开路输出的门电路,简称OD(Open&#x…...
没有域名,一个服务器Nginx怎么部署多个前端项目
因为没有域名,所以用路径来作区分, 主项目:直接根路由访问该项目,与正常配置无任何差别从项目:此处设置/new路径,为从项目,所有从项目访问路径均要加上/new ①修改Nginx配置文件 Nginx 配置文…...
城市内涝的原因和解决措施,内涝监测预警助力城市防涝度汛
城市内涝是城市化进程中最遇到的自然灾害,城市内涝不仅会对市民生活造成困扰,也会对城市基础设施和经济发展产生不利影响。因此,及时监测城市内涝现象,对于城市管理和城市安全具有重要意义。本文将深入探讨城市内涝的原因以及针对…...
8年测试总结,性能测试问题大全,这些问题你应该认清的...
目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 响应时间VS吞吐量…...
RabbitMQ集群安装
RabbitMQ集群安装 1.前言 OS: CentOS Linux release 7.9.2009 (Core) 机器: IPnodecpu内存存储10.106.1.241max-rabbitmg-018 核16 G100 G10.106.1.242max-rabbitmg-028 核16 G100 G10.106.1.243max-rabbitmg-038 核16 G100 G 因为操作系统版本是 centos7,所以…...
面试:link和@import的区别
1:link是XHTML标签,除了加载CSS外,还可以加载RSS;import只能加载CSS 2:link引入CSS时,在页面载入时同时加载;import需要页面完全载入后加载,可能会出行闪屏 3:link是XHTML标签,无兼容…...
椭圆曲线密码学(ECC)
一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...
如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...
如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...
Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...
免费数学几何作图web平台
光锐软件免费数学工具,maths,数学制图,数学作图,几何作图,几何,AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...
02.运算符
目录 什么是运算符 算术运算符 1.基本四则运算符 2.增量运算符 3.自增/自减运算符 关系运算符 逻辑运算符 &&:逻辑与 ||:逻辑或 !:逻辑非 短路求值 位运算符 按位与&: 按位或 | 按位取反~ …...
门静脉高压——表现
一、门静脉高压表现 00:01 1. 门静脉构成 00:13 组成结构:由肠系膜上静脉和脾静脉汇合构成,是肝脏血液供应的主要来源。淤血后果:门静脉淤血会同时导致脾静脉和肠系膜上静脉淤血,引发后续系列症状。 2. 脾大和脾功能亢进 00:46 …...
Django RBAC项目后端实战 - 03 DRF权限控制实现
项目背景 在上一篇文章中,我们完成了JWT认证系统的集成。本篇文章将实现基于Redis的RBAC权限控制系统,为系统提供细粒度的权限控制。 开发目标 实现基于Redis的权限缓存机制开发DRF权限控制类实现权限管理API配置权限白名单 前置配置 在开始开发权限…...
