当前位置: 首页 > news >正文

java入门笔记基础语法篇(4)

变量

在Java中,每个变量都有一个类型(type)。在声明变量时,变量的类型位于变量
名之前。例如:
int days;
double salary;
long earthPopulation;
boolean done;
  • 在Java中,每个声明以分号结束。
  • 变量名必须是一个以字母开头并由字母或数字构成的序列。
  • 需要注意,与大多数程序设计语言相比,Java中“字母”和“数字”的范围更大。
  • 字母包括'A'~'Z'、'a'~'z'、'_'、'$'或在某种语言中表示字母的任何Unicode字符。
  • 如果想要知道哪些Unicode字符属于Java中的“字母”,可以使用Character类的isJavaIdentifierStart和isJavaIdentifierPart方法来检查。
  • 尽管$是一个合法的Java字符,但不要在你自己的代码中使用这个字符。 它只用在Java编译器或其他工具生成的名字中。
  • 另外,不能使用Java保留字作为变量名。

 初始化变量

声明一个变量之后,必须使用赋值语句对变量进行初始化,我们最好不要用未初始化的变量。否则java编译器会认为是未定义行为。

public class UninitializedVariableError {public static void main(String[] args) {int num;// 下面这行会报错,因为num未初始化System.out.println(num); }
}

在 IntelliJ IDEA 中,当你编写这段代码时,IDE 会在代码编辑区域直接给出提示。鼠标悬停在有问题的代码行上,会弹出提示框,显示类似 “Variable 'num' might not have been initialized” 的信息,同时在代码行号旁边会有红色波浪线标记。在编译运行时,运行窗口会显示编译错误信息,通常也会提示变量num未初始化。

 下面我们来看一段正确的示例,在代码中我已经给出了所有类型初始化的示例:

public class VariableInitialization {public static void main(String[] args) {// 初始化byte类型变量byte byteVar = 120;System.out.println("byte类型变量的值: " + byteVar);// 初始化short类型变量short shortVar = 3000;System.out.println("short类型变量的值: " + shortVar);// 初始化int类型变量int intVar = 2024;System.out.println("int类型变量的值: " + intVar);// 初始化long类型变量,需要在数字后面加L或llong longVar = 10000000000L;System.out.println("long类型变量的值: " + longVar);// 初始化float类型变量,需要在数字后面加F或ffloat floatVar = 3.14f;System.out.println("float类型变量的值: " + floatVar);// 初始化double类型变量double doubleVar = 3.1415926;System.out.println("double类型变量的值: " + doubleVar);// 初始化char类型变量char charVar = 'A';System.out.println("char类型变量的值: " + charVar);// 初始化boolean类型变量boolean booleanVar = true;System.out.println("boolean类型变量的值: " + booleanVar);}
}
  •  在java中,我们对一个已经声明过的变量进行赋值,就需要将变量名放在等号(=)左侧,相应取值的java表达式放在等号的右侧。我们可以将声明放在代码中的任何地方。
  • 但在Java中,变量的声明尽可能地靠近变量第一次使用的地方,这是一种良好的程序编写风格。

 常量 

在Java中,利用关键字final指示常量,例如:
public class BasicConstantExample {public static void main(String[] args) {// 使用 final 关键字声明一个 int 类型的常量final int DAYS_IN_WEEK = 7;// 下面这行代码会编译错误,因为常量的值不能被修改// DAYS_IN_WEEK = 8; System.out.println("一周的天数是: " + DAYS_IN_WEEK);// 声明一个 double 类型的常量final double PI = 3.14159;System.out.println("圆周率的值是: " + PI);}
}

在上述代码中,DAYS_IN_WEEK 和 PI 被 final 修饰,分别代表一周的天数和圆周率。当尝试修改这些常量的值时,编译器会报错,从而保证了常量值的不可变性。

  • 在java中,关键字final表示这个变量只能被赋值一次,一旦被赋值之后,就不能够再更改了。习惯上,常量名使用全大写。
  • 在Java中,经常希望某个常量可以在一个类中的多个方法中使用,通常将这些常量 称为类常量。可以使用关键字static final设置一个类常量。
 一个简单的数学常量示例:
public class MathConstants {// 定义圆周率常量,使用 public static final 修饰public static final double PI = 3.1415926;// 定义自然对数的底数常量public static final double E = 2.71828;public static void main(String[] args) {// 可以直接通过类名访问类常量System.out.println("圆周率的值是: " + MathConstants.PI);System.out.println("自然对数的底数的值是: " + MathConstants.E);// 计算半径为 5 的圆的面积double radius = 5;double area = MathConstants.PI * radius * radius;System.out.println("半径为 " + radius + " 的圆的面积是: " + area);}
}

 运算符

  • 在Java中,使用算术运算符+、-、*、/表示加、减、乘、除运算。
  • 当参与/运算的 两个操作数都是整数时,表示整数除法;否则,表示浮点除法。
  • 整数的求余操作 (有时称为取模)用%表示。
  • 例如,15/2等于7,15%2等于1,15.0/2等于7.5。
  • 需要注意,整数被0除将会产生一个异常,而浮点数被0除将会得到无穷大或NaN结果。

 算术运算符

用于执行基本的数学运算,包括加、减、乘、除、取模、自增和自减。

运算符描述示例
+加法,用于两个数相加int a = 5 + 3; // a 的值为 8
-减法,用于两个数相减int b = 7 - 2; // b 的值为 5
*乘法,用于两个数相乘int c = 4 * 6; // c 的值为 24
/除法,用于两个数相除。如果是整数相除,结果会舍去小数部分

int d = 10 / 3; // d 的值为 3

%取模(求余数),用于求两个数相除的余数int e = 10 % 3; // e 的值为 1
++自增运算符,分为前置自增(++i)和后置自增(i++)。前置自增先将变量的值加 1,再使用变量;后置自增先使用变量,再将变量的值加1

int i = 5; int j = ++i; // i 为 6,j 为 6 

int m = 5; int n = m++; // m 为 6,n 为 5

--自减运算符,分为前置自减(--i)和后置自减(i--)。原理与自增运算符类似

int x = 5; int y = --x; // x 为 4,y 为 4

int p = 5; int q = p--; // p 为 4,q 为 5

代码示例: 
//算术运算符
public class ArithmeticOperatorExample {public static void main(String[] args) {int a = 10;int b = 3;System.out.println("a + b = " + (a + b));System.out.println("a - b = " + (a - b));System.out.println("a * b = " + (a * b));System.out.println("a / b = " + (a / b));System.out.println("a % b = " + (a % b));int c = a++;System.out.println("a++ 后,a 的值是:" + a + ",c 的值是:" + c);c = ++a;System.out.println("++a 后,a 的值是:" + a + ",c 的值是:" + c);}
}
注:当然,程序员都知道加1、减1是数值变量最常见的操作。在Java中,借鉴了C和
C++的做法,也提供了自增、自减运算符:n++将变量n的当前值加1,n--则将n的值
减1。

赋值运算符

用于将一个值赋给变量,还可以结合算术运算符进行复合赋值。

运算符描述示例
=基本赋值运算符,将右边的值赋给左边的变量int x = 10;
+=加等于,先将变量与右边的值相加,再将结果赋给变量int a = 5; a += 3; // 相当于 a = a + 3,a 的值
-=减等于,先将变量与右边的值相减,再将结果赋给变量int b = 7; b -= 2; // 相当于 b = b - 2,b 的值为 5
*=乘等于,先将变量与右边的值相乘,再将结果赋给变量int c = 4; c *= 6; // 相当于 c = c * 6,c 的值为 24
/=除等于,先将变量与右边的值相除,再将结果赋给变量int d = 10; d /= 2; // 相当于 d = d / 2,d 的值为 5
%=取模等于,先将变量与右边的值取模,再将结果赋给变量int e = 10; e %= 3; // 等价于 e = e % 3,e 的值变为 1
 代码示例:
 // 赋值运算符int num3 = 5;num3 += 2;System.out.println("使用 += 后 num3 的值: " + num3);num3 -= 1;System.out.println("使用 -= 后 num3 的值: " + num3);num3 *= 3;System.out.println("使用 *= 后 num3 的值: " + num3);num3 /= 2;System.out.println("使用 /= 后 num3 的值: " + num3);num3 %= 3;System.out.println("使用 %= 后 num3 的值: " + num3);
  • 可以在赋值中使用二元运算符,这是一种很方便的简写形式。例如:
  • x +=4; 等价与x = x+4; 
  • (一般的,我们把运算符放在 = 号的左边,如 *=或%= )。

比较运算符

比较运算符用于比较两个值的大小关系,结果为布尔类型(true 或 false),以下是详细介绍及示例:

运算符描述示例
==等于,判断两个值是否相等

int x = 5;

int y = 5;

boolean isEqual = (x == y); // 结果为 t

!=不等于,判断两个值是否不相等

int m = 3;

int n = 4;

boolean isNotEqual = (m != n); // 结果为 true

>大于,判断左边的值是否大于右边的值

int a = 7;

int b = 5;

boolean isGreater = (a > b); // 结果为 true

<小于,判断左边的值是否小于右边的值

int c = 2;

int d = 4;

boolean isLess = (c < d); // 结果为 true

>=大于等于,判断左边的值是否大于或等于右边的值

int e = 5;

int f = 5;

boolean isGreaterOrEqual = (e >= f); // 结果为 true

<=小于等于,判断左边的值是否小于或等于右边的值

int g = 3;

int h = 4;

boolean isLessOrEqual = (g <= h); // 结果为 true

代码示例:
// 比较运算符boolean isEqual = num1 == num2;System.out.println("num1 是否等于 num2: " + isEqual);boolean isNotEqual = num1 != num2;System.out.println("num1 是否不等于 num2: " + isNotEqual);boolean isGreater = num1 > num2;System.out.println("num1 是否大于 num2: " + isGreater);boolean isLess = num1 < num2;System.out.println("num1 是否小于 num2: " + isLess);boolean isGreaterOrEqual = num1 >= num2;System.out.println("num1 是否大于等于 num2: " + isGreaterOrEqual);boolean isLessOrEqual = num1 <= num2;System.out.println("num1 是否小于等于 num2: " + isLessOrEqual);

逻辑运算符

逻辑运算符用于对布尔值进行逻辑操作,以下是常见的逻辑运算符及示例:

运算符描述示例
&&逻辑与,只有当两个操作数都为 true 时,结果才为 true

boolean a = true;

boolean b = false;

boolean result = a && b; // 结果为 false

||逻辑或,只要两个操作数中有一个为 true,结果就为 true

boolean m = true;

boolean n = false;

boolean res = m||n; // 结果为 true`

!逻辑非,对操作数的布尔值取反

boolean p = true;

boolean q =!p; // 结果为 false

代码示例: 

 // 逻辑运算符boolean bool1 = true;boolean bool2 = false;boolean logicalAnd = bool1 && bool2;System.out.println("逻辑与结果: " + logicalAnd);boolean logicalOr = bool1 || bool2;System.out.println("逻辑或结果: " + logicalOr);boolean logicalNot =!bool1;System.out.println("逻辑非结果: " + logicalNot);
  • Java沿用了C++的做法,使用&&表示逻辑“与”运算符,使用||表示逻辑“或”运算符。从!=运算符可以想到,感叹号!就是逻辑非运算符。
  • &&和||运算符是按照“短路”方式来求值的:如果第一个操作数已经能够确定表达式的值,第二个操作数就不必计算了。
  • 用&&运算符合并两个表达式,计算得到第一个表达式的真值为false,结果就不可能为true。
  • 因此,第二个表达式就不必计算了。可以利用这一点来避免错误。

位运算符

处理整型类型时,可以直接对组成整型数值的各个位完成操作。这意味着可以使用
掩码技术得到整数中的各个位。

位运算符用于对整数类型的二进制位进行操作,以下是常见的位运算符及示例:

运算符描述示例
&按位与,对两个操作数的对应二进制位进行与操作,只有当对应位都为 1 时,结果位才为 1int x = 5; // 二进制 0101
int y = 3; // 二进制 0011
int result = x & y; // 结果为 1,二进制 0001
|按位或,只要两个操作数中有一个为 true,结果就为 true`int a = 5; // 二进制 0101
int b = 3; // 二进制 0011
int orResult = a|b; // 结果为 7,二进制 0111`
<<左移运算符,将操作数的二进制位向左移动指定的位数,右边空出的位用 0 填充。左移 n 位相当于将操作数乘以 2 的 n 次方

int num = 5;

int result = num << 2;

>>有符号右移运算符,将操作数的二进制位向右移动指定的位数,左边空出的位用原符号位填充(正数补 0,负数补 1)。有符号右移 n 位相当于将操作数除以 2 的 n 次方并向下取整

int positive = 20;

int posResult = positive >> 2; 

int negative = -20;

int negResult = negative >> 2;

>>>无符号右移运算符,将操作数的二进制位向右移动指定的位数,左边空出的位始终用 0 填充,不考虑符号位

int negative = -20;

int result = negative >>> 2;

// -20 的二进制(补码)1111 1111 1111 1111 1111 1111 1110 1100 无符号右移 2 位后 0011 1111 1111 1111 1111 1111 1111 1011,结果为 1073741819

^按位异或,对两个操作数的对应二进制位进行异或操作,当两个对应位不同时结果位为 1,相同时结果位为 0

int m = 5;

// 二进制 0101

 int n = 3;

// 二进制 0011 

int xorResult = m ^ n;

// 结果为 6,二进制 0110

 代码示例:
// 5. 位运算符int bitNum1 = 5; // 二进制: 0101int bitNum2 = 3; // 二进制: 0011int bitwiseAnd = bitNum1 & bitNum2;System.out.println("按位与结果: " + bitwiseAnd);int bitwiseOr = bitNum1 | bitNum2;System.out.println("按位或结果: " + bitwiseOr);int bitwiseXor = bitNum1 ^ bitNum2;System.out.println("按位异或结果: " + bitwiseXor);int bitwiseNot = ~bitNum1;System.out.println("按位取反结果: " + bitwiseNot);int leftShift = bitNum1 << 2;System.out.println("左移 2 位结果: " + leftShift);int rightShift = bitNum1 >> 1;System.out.println("右移 1 位结果: " + rightShift);int unsignedRightShift = bitNum1 >>> 1;System.out.println("无符号右移 1 位结果: " + unsignedRightShift);

三目运算符

Java支持三元操作符?:,这个操作符有时很有用。如果条件为true,下面的表达式
布尔表达式 ? 表达式1 : 表达式2;
就为第一个表达式的值,否则计算为第二个表达式的值。
下面我们来看一段代码示例:
//在此表达式中,会返回x和y中较小的一个。
x<y?x:y

运算符优先级

运算符结合性
[]   ()(方法调用)从左向右
!  ~  ++  --  +(一元运算) -(一元运算) ()(强制类型转换)new从右向左
*      /   %从左向右
+  -从左向右
<<  >>  >>>从左向右
<  <=   >  >=  instanceof从左向右
==   !=从左向右
&从左向右
^从左向右
&&从左向右
|从左向右
? :从右向左
=  +=  -=  *=  /=  %=  &= = ^= <<= >>= >>>=从右向左

枚举类型

枚举类型是一种强类型,编译器会确保使用的是预先定义好的枚举常量,避免了错误的字符串或其他非法值的使用。

当变量的取值只在一个有限的集合内时,我们可以自定义枚举类型。枚举类型包括有限个命名的值。一般我们使用 enum关键字来定义枚举类型,例如:
enum Season {SPRING, SUMMER, AUTUMN, WINTER
}

上述代码定义了一个名为Season的枚举类型,包含了SPRING(春天)、SUMMER(夏天)、AUTUMN(秋天)、WINTER(冬天)四个枚举常量。

字符串

从概念上,Java 字符串是 Unicode 字符序列,如 “Java\u2122” 含 5 个 Unicode 字符 J、a、v、a 和™。Java 没有内置字符串类型,而是在标准类库中提供预定义的 String 类。每个双引号括起来的字符串,都是 String 类的实例。
public class StringExample {public static void main(String[] args) {// 定义一个普通字符串String normalString = "Hello, World!";System.out.println("普通字符串: " + normalString);// 定义一个包含Unicode字符的字符串String unicodeString = "Java\u2122";System.out.println("包含Unicode字符的字符串: " + unicodeString);// 字符串是String类的实例,可以调用String类的方法int length = normalString.length();System.out.println("普通字符串的长度: " + length);boolean isEqual = normalString.equals("Hello, World!");System.out.println("普通字符串与指定内容是否相等: " + isEqual);}
}

在上述代码中:

  1. 定义了一个普通字符串 normalString,它是 String 类的一个实例。通过 System.out.println 输出该字符串。
  2. 定义了包含 Unicode 字符(\u2122 代表商标符号™)的字符串 unicodeString,同样输出该字符串。
  3. 利用 String 类的 length 方法获取 normalString 的长度,并输出。
  4. 使用 String 类的 equals 方法比较 normalString 与指定字符串内容是否相等,并输出结果。
子串
  • String类的substring方法可以从一个较大的字符串提取出一个子串。
  • 在 Java 中,String 类的 substring 方法用于从一个较大的字符串中提取子串,它有两种重载形式,下面分别举例说明:

1. substring(int beginIndex)

该方法用于从指定的索引位置 beginIndex 开始截取字符串,一直到原字符串的末尾。

public class SubstringExample1 {public static void main(String[] args) {String originalString = "Hello, World!";// 从索引 7 开始截取字符串String subString = originalString.substring(7);System.out.println("原字符串: " + originalString);System.out.println("截取后的子串: " + subString);}
}

代码解释

  • originalString 是原始的字符串 "Hello, World!"
  • originalString.substring(7) 表示从索引为 7 的字符(索引从 0 开始计数)开始截取,即字符 W,一直到字符串末尾,所以截取后的子串是 "World!"

2. substring(int beginIndex, int endIndex)

该方法用于从指定的起始索引 beginIndex 开始截取字符串,直到指定的结束索引 endIndex 之前的位置(不包括 endIndex 位置的字符)。

public class SubstringExample2 {public static void main(String[] args) {String originalString = "Java Programming";// 从索引 0 开始,到索引 4 之前结束(不包括索引 4 的字符)String subString = originalString.substring(0, 4);System.out.println("原字符串: " + originalString);System.out.println("截取后的子串: " + subString);}
}

代码解释

  • originalString 是原始的字符串 "Java Programming"
  • originalString.substring(0, 4) 表示从索引为 0 的字符(即字符 J)开始截取,到索引为 4 的字符(即字符 P)之前结束,所以截取后的子串是 "Java"

注:

  • 索引值必须在有效范围内,即 0 到 字符串长度 - 1 之间,否则会抛出StringIndexOutofBoundsException异常。
  • 当 beginIndex 等于 endIndex 时,截取的子串为空字符串。
  • substring的工作方式有一个优点:容易计算子串的长度。
  • 字符串 s.substring(a,b)的长度为b-a。

拼接

  • 与绝大多数的程序设计语言一样,Java语言允许使用+号连接(拼接)两个字符串。
  • 这是最直观、最简单的字符串拼接方式,适用于少量字符串的拼接。
public class StringConcatenationExample {public static void main(String[] args) {String str1 = "Hello";String str2 = "World";String result = str1 + " " + str2;System.out.println(result);}
}

 代码解释:

  • + 是 Java 中的字符串拼接运算符。当 + 用于连接两个字符串时,会将它们连接成一个新的字符串。
  • 这里先将 str1 的值 "Hello" 与空格字符串 " " 拼接,得到 "Hello ",然后再将这个结果与 str2 的值 "World" 拼接,最终得到 "Hello World"
  • result 是一个新的字符串变量,用于存储拼接后的结果。

原理
在编译时,Java 编译器会将使用 + 运算符拼接字符串的代码转化为 StringBuilder 类的操作。对于简单的拼接,这种方式很方便,但如果在循环中使用,会导致性能问题,因为每次拼接都会创建新的 StringBuilder 对象。

 不可变字符串

  • String类没有提供用于修改字符串的方法。在 Java 中,String类代表不可变字符串,即字符串一旦创建,其内容就不能被改变。
  • 由于不能修改Java字符串中的字符,所以在Java文档中将String类对象称为不可变字符串。
  • 不可变字符串有一个优点:编译器可以让字符串共享。
  • 具体的工作方式,可以想象将各种字符串存放在公共的存储池中。字符串变量指向存储池中相应的位置。如果复制一个字符串变量,原始字符串与复制的字符串共享相同的字符。
  • 字符串常量池:Java 为了提高性能和减少内存开销,维护了一个字符串常量池。当创建字符串常量时,如String s = "abc";,JVM 首先会在字符串常量池中查找是否存在"abc"这个字符串。如果存在,直接返回常量池中该字符串的引用;如果不存在,则在常量池中创建该字符串,然后返回引用。这使得相同内容的字符串常量在内存中只有一份实例,进一步体现了String的不可变性。
代码示例: 
public final class Stringimplements java.io.Serializable, Comparable<String>, CharSequence {private final char value[];
}
  •  String类内部使用一个private final char[]数组来存储字符串内容,final关键字确保了该数组一旦初始化,就不能再指向其他数组,从底层实现上保证了字符串的不可变性。
  • 由于value数组是private的,外部代码无法直接访问和修改该数组,同时final修饰符保证了数组引用的不可更改性。 
总而言之,Java的设计者认为共享带来的高效率远远胜过于提取、拼接字符串所带来的低效率。查看一下程序会发现:很少需要修改字符串,而是往往需要对字符串进行比较。有一种例外情况,将来自于文件或键盘的单个字符或较短的字符串汇集成字符串。为此,Java提供了一个独立的类,这在之后会介绍。

检测字符串是否相等

在Java中,我们可以使用equals方法检测两个字符串是否相等。

1. 使用 equals 方法

equals方法用于比较两个字符串的内容是否相等。它是String类重写自Object类的方法,用于专门比较字符串的实际字符序列。

String str1 = "Hello";
String str2 = "Hello";
String str3 = new String("Hello");boolean isEqual1 = str1.equals(str2); 
boolean isEqual2 = str1.equals(str3); System.out.println(isEqual1); 
System.out.println(isEqual2); 

在上述代码中,str1str2都指向字符串常量池中的同一个"Hello"字符串,str3通过new关键字创建了一个新的String对象,但内容同样是"Hello"equals方法比较的是字符串的内容,所以isEqual1isEqual2都为true

当然,如果我们要想检测两个字符串是否相等,而不区分大小写,可以使用equalsIgnoreCase
法。

2. 使用 equalsIgnoreCase 方法

equalsIgnoreCase方法与equals方法类似,也是用于比较字符串内容,但它忽略大小写。

我们要想检测两个字符串是否相等,而不区分大小写,就可以使用equalsIgnoreCase方法。

 注:请注意!请一定不要用`==`检测字符串是否相等,它只判断内存地址是否相同,即便内容一样,不同位置的字符串拷贝也会使判断出错。

只有字符串常量在虚拟机中是共享的,+substring等操作生成的字符串不共享。所以千万不要使用==判断字符串相等,否则极易出现类似随机间歇性错误的严重 bug。

public class StringEqualityIgnoreCase {public static void main(String[] args) {String str1 = "Hello";String str2 = "hello";// 比较 str1 和 str2,忽略大小写boolean result = str1.equalsIgnoreCase(str2);System.out.println("str1.equalsIgnoreCase(str2) 的结果: " + result); }
}

代码解释:在比较 str1 和 str2 时,equalsIgnoreCase 方法不考虑字母的大小写,因此即使 str1 中的 H 是大写,str2 中的 h 是小写,该方法仍会返回 true

 空串与Null串

在 Java 中,空串(Empty String)和 Null 串是两个不同的概念。

空串

空串是长度为 0 的字符串,它是 String 类的一个有效实例,在内存中是实际存在的对象,只不过该对象不包含任何字符。可以通过两种方式创建空串:

// 方式一:直接使用双引号赋值
String emptyStr1 = "";
// 方式二:使用 String 类的构造函数
String emptyStr2 = new String();
判断方式

判断一个字符串是否为空串,通常可以使用 length() 方法或者 isEmpty() 方法:

String str = "";
// 使用 length() 方法判断
if (str.length() == 0) {System.out.println("字符串为空串");
}
// 使用 isEmpty() 方法判断
if (str.isEmpty()) {System.out.println("字符串为空串");
}
使用场景
  • 初始化变量:在某些情况下,需要将字符串变量初始化为空串,以便后续根据业务逻辑进行赋值操作。
String result = "";
// 根据条件进行赋值
if (condition) {result = "Some value";
}
  • 作为方法返回值:当方法没有合适的字符串结果需要返回时,可以返回空串。
public String getResult() {// 某些条件下没有结果return "";
}

Null 串

Null 串表示一个字符串变量没有引用任何对象,即该变量不指向任何有效的 String 实例。null 是 String变量中存放的一个特殊值,它表示目前没有任何对象与该变量关联

String nullStr = null;
判断方式

判断一个字符串是否为 null,需要使用 == 运算符:

String str = null;
if (str == null) {System.out.println("字符串为 null");
}

 需要注意的是,在使用 null 字符串调用方法时会抛出 NullPointerException 异常,例如:

String nullStr = null;
// 下面这行代码会抛出 NullPointerException 异常
// System.out.println(nullStr.length()); 
使用场景
  • 表示对象未初始化:当一个字符串变量在声明时还不确定具体的值,或者在某些条件下没有合适的字符串对象可以引用时,可以将其初始化为 null
String userInput;
// 假设在某个方法中获取用户输入
userInput = getUserInput(); 
if (userInput == null) {System.out.println("未获取到用户输入");
}
  • 方法参数传递:在方法调用时,如果某个字符串参数没有合适的值可以传递,可以传递 null 表示该参数未提供。
public void processString(String str) {if (str == null) {System.out.println("传入的字符串为 null");} else {// 处理字符串}
}

注意事项

在实际开发中,经常需要同时判断字符串是否为 null 或空串,可以结合 null 判断和空串判断:

String str = null;
if (str == null || str.isEmpty()) {System.out.println("字符串为 null 或空串");
}

需要注意判断顺序,先判断 null 再判断空串,避免对 null 字符串调用 isEmpty() 方法导致 NullPointerException 异常。

 码点与代码单元

  • Java字符串由char值序列组成。
  • char数据类型是一个采用UTF-16编码表示Unicode码点的代码单元。大多数的常用Unicode字符使用一个代码单元就可以表示,而辅助字符需要一对代码单元表示。

Unicode 简介

Unicode 是一种字符编码标准,它为世界上几乎所有的字符都分配了一个唯一的数字,这个数字被称为码点。Unicode 码点的范围从 U+0000 到 U+10FFFF,可以表示超过一百万个字符。

码点(Code Point)

  • 定义:码点是指 Unicode 编码中的一个数值,它唯一标识一个字符。例如,字符 'A' 的 Unicode 码点是 U+0041,字符 '中' 的 Unicode 码点是 U+4E2D。在 Java 中,码点用 int 类型表示,因为它的取值范围超出了 char 类型所能表示的范围。
  • 获取码点:可以使用 String 类的 codePointAt(int index) 方法来获取字符串中指定位置的码点。示例代码如下:
public class CodePointExample {public static void main(String[] args) {String str = "A中";// 获取第一个字符的码点int codePoint1 = str.codePointAt(0); // 获取第二个字符的码点int codePoint2 = str.codePointAt(1); System.out.println("字符 'A' 的码点: " + Integer.toHexString(codePoint1)); System.out.println("字符 '中' 的码点: " + Integer.toHexString(codePoint2)); }
}

遍历码点:可以使用 String 类的 codePoints() 方法来遍历字符串中的所有码点。

示例代码如下:

public class CodePointTraversal {public static void main(String[] args) {String str = "A中";str.codePoints().forEach(codePoint -> {System.out.println("码点: " + Integer.toHexString(codePoint));});}
}

代码单元(Code Unit)

  • 定义:代码单元是字符串存储和处理的基本单位。在 Java 中,String 类内部使用 UTF - 16 编码来存储字符,UTF - 16 编码使用 16 位(即 2 个字节)作为一个代码单元。对于 Unicode 码点在 U+0000 到 U+FFFF 范围内的字符(称为 BMP,基本多文种平面字符),可以用一个代码单元来表示;而对于码点在 U+10000 到 U+10FFFF 范围内的字符(称为补充字符),则需要用两个代码单元(即一个代理对)来表示。
  • 获取代码单元:可以使用 charAt(int index) 方法来获取字符串中指定位置的代码单元。示例代码如下:
public class CodeUnitExample {public static void main(String[] args) {String str = "A中";// 获取第一个代码单元char codeUnit1 = str.charAt(0); // 获取第二个代码单元char codeUnit2 = str.charAt(1); System.out.println("第一个代码单元: " + codeUnit1); System.out.println("第二个代码单元: " + codeUnit2); }
}
  • 代码单元数量:可以使用 length() 方法来获取字符串中的代码单元数量。需要注意的是,对于包含补充字符的字符串,length() 方法返回的是代码单元的数量,而不是字符的实际数量。示例代码如下:
public class CodeUnitLength {public static void main(String[] args) {// 包含补充字符的字符串String str = "\uD83D\uDE00"; System.out.println("代码单元数量: " + str.length()); System.out.println("实际字符数量: " + str.codePoints().count()); }
}

码点与代码单元的关系

  • 对于 BMP 字符,一个码点对应一个代码单元。
  • 对于补充字符,一个码点对应两个代码单元。在处理包含补充字符的字符串时,需要特别注意,不能简单地使用 charAt() 和 length() 方法,而应该使用与码点相关的方法,如 codePointAt() 和 codePoints() 方法。

 输入输出

在 Java 中,输入输出(I/O)操作是非常重要的部分,它允许程序与外部环境进行数据交互,比如从键盘读取用户输入、将数据写入文件、从网络接收数据等。Java 的 I/O 操作主要分为标准输入输出、文件输入输出和网络输入输出。

格式化输出

可以使用 System.out.print(x) 将数值x输出到控制台上。这条命令将以x对应的数据类型所允许的最大非0数字位数打印输出x。
输出整数
public class IntegerOutputExample {public static void main(String[] args) {int number = 12345;// 使用 System.out.print 输出整数System.out.print("整数输出结果: ");System.out.print(number);}
}

代码解释

  • 首先定义了一个 int 类型的变量 number 并赋值为 12345
  • 第一行 System.out.print 输出提示信息 "整数输出结果: "
  • 第二行 System.out.print 输出变量 number 的值。

沿用C库函数 

  •  Java SE 沿用了 C 语言库函数中的 printf 方法风格。
  • 在 C 语言里,printf 函数是一个非常常用的输出函数,可按指定格式输出各种类型的数据。
  • 而 Java 在 java.io.PrintStream 类中也提供了 printf 方法,其功能和使用方式与 C 语言的 printf 函数有相似之处,都是支持格式化输出。
  • 代码示例:
public class PrintfExample {public static void main(String[] args) {int num = 10;double pi = 3.14159;String name = "John";// 输出整数System.out.printf("整数: %d\n", num);// 输出浮点数,保留两位小数System.out.printf("浮点数: %.2f\n", pi);// 输出字符串System.out.printf("字符串: %s\n", name);// 组合输出System.out.printf("%s 的幸运数字是 %d,他喜欢的圆周率近似值是 %.2f。\n", name, num, pi);}
}

与 C 语言 printf 的区别

注意:虽然 Java 的 printf 方法借鉴了 C 语言 printf 函数的格式化输出方式,但 Java 是面向对象的语言,printf 是 PrintStream 类的一个实例方法,并且 Java 有自己严格的类型检查机制,这和 C 语言有所不同。例如在 C 语言里,可能需要更手动地管理类型转换和内存,而 Java 会在编译阶段进行类型检查,保证代码的类型安全性。

 用于printf的转换符

转换符类型举例
d十进制整数159
x十六进制整数9f
o八进制整数237
f定点浮点数15.9
e指数浮点数1.59e+01
g通用浮点数
a十六进制浮点数0x1.fccdp3
s字符串Hello
c字符H
b布尔True
h散列码42628b2
tx 或 Tx(T 强制大写)日期时间(已经过时,应当改为使用 java.time 类)-
%百分号%
n与平台有关的行分隔符

代码示例:

public class FormatConversionExample {public static void main(String[] args) {// 整数相关转换符int intValue = 159;System.out.printf("十进制整数(d): %d\n", intValue);System.out.printf("十六进制整数(x): %x\n", intValue);System.out.printf("八进制整数(o): %o\n", intValue);// 浮点数相关转换符double doubleValue = 15.9;System.out.printf("定点浮点数(f): %.1f\n", doubleValue);System.out.printf("指数浮点数(e): %e\n", doubleValue);System.out.printf("通用浮点数(g): %g\n", doubleValue);System.out.printf("十六进制浮点数(a): %a\n", doubleValue);// 字符串、字符、布尔、散列码相关转换符String strValue = "Hello";char charValue = 'H';boolean boolValue = true;Object obj = new Object();System.out.printf("字符串(s): %s\n", strValue);System.out.printf("字符(c): %c\n", charValue);System.out.printf("布尔(b): %b\n", boolValue);System.out.printf("散列码(h): %h\n", obj);// 百分号和行分隔符转换符System.out.printf("百分号(%%): %% \n");System.out.printf("与平台有关的行分隔符(n): 第一行%n第二行");}
}

运行结果:

十进制整数(d): 159
十六进制整数(x): 9f
八进制整数(o): 237
定点浮点数(f): 15.9
指数浮点数(e): 1.590000e+01
通用浮点数(g): 15.9
十六进制浮点数(a): 0x1.fccdp3
字符串(s): Hello
字符(c): H
布尔(b): true
散列码(h): 7852e922
百分号(%): % 
与平台有关的行分隔符(n): 第一行
第二行

用于printf的转换符

public class PrintfFlagsExample {public static void main(String[] args) {double number = 3333.33;int intNumber = 159;// + 标志:打印正数和负数的符号System.out.printf("+ 标志示例:%+f\n", number);// 空格 标志:在正数之前添加空格System.out.printf("空格 标志示例:% f\n", number);// 0 标志:数字前面补0System.out.printf("0 标志示例:%010.2f\n", number);// - 标志:左对齐System.out.printf("- 标志示例:%-10.2f\n", number);// ( 标志:将负数括在括号内double negativeNumber = -3333.33;System.out.printf("( 标志示例:%(f\n", negativeNumber);//, 标志:添加分组分隔符System.out.printf(", 标志示例:%,f\n", number);// #(对于f格式)标志:包含小数点System.out.printf("#(对于f格式)标志示例:%,#.0f\n", number);// #(对于x或o格式)标志:添加前缀0x或0System.out.printf("#(对于x格式)标志示例:%#x\n", intNumber);// $ 标志:指定要格式化的参数索引System.out.printf("$ 标志示例:%1$d %1$x\n", intNumber);// < 标志:格式化前面说明的数值System.out.printf("< 标志示例:%d%<x\n", intNumber);}
}

运行结果

+ 标志示例:+3333.330000
空格 标志示例: 3333.330000
0 标志示例:003333.33
- 标志示例:3333.33  
( 标志示例:(3333.33)
, 标志示例:3,333.330000
#(对于f格式)标志示例:3,333.
#(对于x格式)标志示例:0x9f
$ 标志示例:159 9f
< 标志示例:159 9f
标志目的示例代码中的效果
+打印正数和负数的符号输出+3333.330000
空格在正数之前添加空格输出 3333.330000
0数字前面补 0输出003333.33
-左对齐输出3333.33
(将负数括在括号内输出(3333.33)
,添加分组分隔符输出3,333.330000
#(对于 f 格式)包含小数点输出3,333.
#(对于 x 或 o 格式)添加前缀 0x 或 0输出0x9f
$指定要格式化的参数索引输出159 9f
<格式化前面说明的数值输出159 9f

日期和时间转换符 

import java.util.Calendar;public class DateTimeConversionExample {public static void main(String[] args) {Calendar calendar = Calendar.getInstance();System.out.println("完整的日期和时间 (c): " + String.format("%tc", calendar));System.out.println("ISO 8601日期 (F): " + String.format("%tF", calendar));System.out.println("美国格式的日期 (月/日/年) (D): " + String.format("%tD", calendar));System.out.println("24小时时间 (T): " + String.format("%tT", calendar));System.out.println("12小时时间 (r): " + String.format("%tr", calendar));System.out.println("24小时时间,没有秒 (R): " + String.format("%tR", calendar));System.out.println("4位数字的年(前面补0) (Y): " + String.format("%tY", calendar));System.out.println("年的后两位数字(前面补0) (y): " + String.format("%ty", calendar));System.out.println("年的前两位数字(前面补0) (C): " + String.format("%tC", calendar));System.out.println("月的完整拼写 (B): " + String.format("%tB", calendar));System.out.println("月的缩写 (b或h): " + String.format("%tb", calendar));System.out.println("两位数字的月(前面补0) (m): " + String.format("%tm", calendar));System.out.println("两位数字的日(前面补0) (d): " + String.format("%td", calendar));System.out.println("两位数字的日(前面不补0) (e): " + String.format("%te", calendar));System.out.println("星期几的完整拼写 (A): " + String.format("%tA", calendar));System.out.println("星期几的缩写 (a): " + String.format("%ta", calendar));System.out.println("三位数的年中第几天(前面补0),在001到366之间 (j): " + String.format("%tj", calendar));System.out.println("两位数字的小时(前面补0),在0到23之间 (H): " + String.format("%tH", calendar));System.out.println("两位数字的小时(前面不补0),在0到23之间 (k): " + String.format("%tk", calendar));System.out.println("两位数字的小时(前面补0),在01到12之间 (I): " + String.format("%tI", calendar));System.out.println("两位数字的小时(前面不补0),在1到12之间 (l): " + String.format("%tl", calendar));System.out.println("两位数字的分钟(前面补0) (M): " + String.format("%tM", calendar));System.out.println("两位数字的秒(前面补0) (S): " + String.format("%tS", calendar));System.out.println("三位数字的毫秒(前面补0) (L): " + String.format("%tL", calendar));System.out.println("九位数字的毫秒(前面补0) (N): " + String.format("%tN", calendar));System.out.println("上午或下午的标志 (p): " + String.format("%tp", calendar));System.out.println("从GMT起,RFC 822数字位移 (z): " + String.format("%tz", calendar));System.out.println("时区 (Z): " + String.format("%tZ", calendar));System.out.println("从格林尼治时间1970-01-01 00:00:00起的秒数 (s): " + String.format("%ts", calendar));System.out.println("从格林尼治时间1970-01-01 00:00:00起的毫秒数 (Q): " + String.format("%tQ", calendar));}
}

转换符

类型

示例

c

完整的日期和时间

Sun Jan 26 14:53:00 CST 2025

F

ISO 8601 日期

2025-01-26

D

美国格式的日期 (月 / 日 / 年)

01/26/25

T

24 小时时间

14:53:00

r

12 小时时间

02:53:00 pm

R

24 小时时间,没有秒

14:53

Y

4 位数字的年(前面补 0)

2025

y

年的后两位数字(前面补 0)

25

C

年的前两位数字(前面补 0)

20

B

月的完整拼写

January

b 或 h

月的缩写

Jan

m

两位数字的月(前面补 0)

01

d

两位数字的日(前面补 0)

26

e

两位数字的日(前面不补 0)

26

A

星期几的完整拼写

Sunday

a

星期几的缩写

Sun

j

三位数的年中第几天(前面补 0),在 001 到 366 之间

026

H

两位数字的小时(前面补 0),在 0 到 23 之间

14

k

两位数字的小时(前面不补 0),在 0 到 23 之间

14

I

两位数字的小时(前面补 0),在 01 到 12 之间

02

l

两位数字的小时(前面不补 0),在 1 到 12 之间

2

M

两位数字的分钟(前面补 0)

53

S

两位数字的秒(前面补 0)

00

L

三位数字的毫秒(前面补 0)

123

N

九位数字的毫秒(前面补 0)

123000000

p

上午或下午的标志

pm

z

从 GMT 起,RFC 822 数字位移

+0800

Z

时区

CST

s

从格林尼治时间 1970-01-01 00:00:00 起的秒数

1738009980

Q

从格林尼治时间 1970-01-01 00:00:00 起的毫秒数

1738009980123

相关文章:

java入门笔记基础语法篇(4)

变量 在Java中&#xff0c;每个变量都有一个类型&#xff08;type&#xff09;。在声明变量时&#xff0c;变量的类型位于变量 名之前。例如&#xff1a; int days; double salary; long earthPopulation; boolean done; 在Java中&#xff0c;每个声明以分号结束。变量名必须…...

java语法学习

目录 一、基础语法 1.注释 2.关键字 3.字面量 4.变量 定义与使用 存储 5.数据类型 6.标识符 7.集成环境 二、运算符 1.概念 2.种类 算术运算符 除法与取模 转化规则 自增减 赋值运算符 关系运算符 逻辑运算符 短路运算符 三元运算符 其它运算符 三、流…...

装饰SpringMVC的适配器实现响应自动包装

文章目录 1.common-tool-starter1.目录结构2.ResultWrapper.java 2.common-web-starter1.目录结构2.IgnoredResultWrapper.java 自定义注解&#xff0c;忽略对返回结果的自动包装3.ReturnValueHandlersDecorator.java 对适配器进行扩展的装饰器4.WebAutoConfiguration.java 将装…...

【Rust自学】15.4. Drop trait:告别手动清理,释放即安全

喜欢的话别忘了点赞、收藏加关注哦&#xff08;加关注即可阅读全文&#xff09;&#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵&#xff01;(&#xff65;ω&#xff65;) 15.4.1. Drop trait的意义 类型如果实现了Drop trait&#xff0c;就可以让程序员自定义当值…...

【算法】【归并排序】AcWing 算法基础 788. 逆序对的数量

题目 给定一个长度为 n 的整数数列&#xff0c;请你计算数列中的逆序对的数量。 逆序对的定义如下&#xff1a;对于数列的第 i个和第 j 个元素&#xff0c;如果满足 i<j且 a[i]>a[j]&#xff0c;则其为一个逆序对&#xff1b;否则不是。 输入格式 第一行包含整数 n&#…...

一个局域网通过NAT访问另一个地址重叠的局域网(IP方式访问)

正文共&#xff1a;1335 字 7 图&#xff0c;预估阅读时间&#xff1a;4 分钟 现在&#xff0c;我们已经可以通过调整两台设备的组合配置&#xff08;地址重叠时&#xff0c;用户如何通过NAT访问对端IP网络&#xff1f;&#xff09;或仅调整一台设备的配置&#xff08;仅操作一…...

05-机器学习-数据标注

一、学习数据标注的核心目标 数据标注不仅是“打标签”&#xff0c;而是理解数据与AI模型之间的桥梁。需要掌握&#xff1a; 标注技术&#xff1a;不同任务类型的标注方法&#xff08;如分割、实体识别&#xff09;。标注工具&#xff1a;高效使用专业工具&#xff08;如CVAT…...

LQ1052 Fibonacci斐波那契数列

题目描述 Fibonacci斐波那契数列也称为兔子数列&#xff0c;它的递推公式为&#xff1a;FnFn-1Fn-2&#xff0c;其中F1F21。 当n比较大时&#xff0c;Fn也非常大&#xff0c;现在小蓝想知道&#xff0c;Fn除以10007的余数是多少&#xff0c;请你编程告诉她。 输入 输入包含一…...

AWTK 骨骼动画控件发布

Spine 是一款广泛使用的 2D 骨骼动画工具&#xff0c;专为游戏开发和动态图形设计设计。它通过基于骨骼的动画系统&#xff0c;帮助开发者创建流畅、高效的角色动画。本项目是基于 Spine 实现的 AWTK 骨骼动画控件。 代码&#xff1a;https://gitee.com/zlgopen/awtk-widget-s…...

分库分表后如何进行join操作

在分库分表后的系统中&#xff0c;进行表之间的 JOIN 操作比在单一数据库表中复杂得多&#xff0c;因为涉及的数据可能位于不同的物理节点或分片中。此时&#xff0c;传统的 SQL JOIN 语句不能直接用于不同分片的数据&#xff0c;以下是几种处理这样的跨分片 JOIN 操作的方法&a…...

arkui-x 前端布局编码模板

build() {Column() {Row() {// 上侧页面布局实现}// 下侧页面布局实现}.width(Const.THOUSANDTH_1000).height(Const.THOUSANDTH_1000).justifyContent(FlexAlign.SpaceBetween).backgroundImage($r(app.media.background_xxx)).backgroundImageSize(ImageSize.Cover).backgrou…...

宝塔面板SSL加密访问设置教程

参考:https://www.bt.cn/bbs/thread-117246-1-1.html 如何快速使用证书加密访问面板 因早期默认未开启https访问所以没有相关的风险提醒&#xff0c;现面板默认已开启https加密访问、提升安全性 由于采用的是服务器内部本身签发证书&#xff0c;不被公网浏览器信任请参考以下步…...

c++ set/multiset 容器

1. set 基本概念 简介&#xff1a; 所有元素都会在插入时自动排序本质&#xff1a; set/multiset属于关联式容器&#xff0c;底层结构是用二叉树实现。set 和 multiset 区别&#xff1a; set容器不允许有重复的元素。 multiset允许有重复的元素。2. set 构造和赋值 构造&a…...

前部分知识复习02

一、物体的屏幕UV坐标 float2 ScreenUV i.pos.xy / _ScreenParams.xy; 二、抓取屏幕图像 GrabPass{" _A "} //_A为贴图图像名称 之后需在Pass中声明该贴图才能在Pass中引用此贴图 三、屏幕抓取并制作热效应代码 Shader"unity/HeatDistort 07" {Pr…...

开发环境搭建-3:配置 JavaScript 开发环境 (fnm+ nodejs + pnpm + nrm)

在 WSL 环境中配置&#xff1a;WSL2 (2.3.26.0) Oracle Linux 8.7 官方镜像 node 官网&#xff1a;https://nodejs.org/zh-cn/download 点击【下载】&#xff0c;选择想要的 node 版本、操作系统、node 版本管理器、npm包管理器 根据下面代码提示依次执行对应代码即可 基本概…...

kotlin内联函数——let,run,apply,also,with的区别

一、概述 为了帮助您根据使用场景选择合适的作用域函数&#xff08;scope function&#xff09;&#xff0c;我们将对它们进行详细描述并提供使用建议。从技术上讲&#xff0c;许多情况下范围函数是可以互换使用的&#xff0c;因此示例中展示了使用它们的约定俗成的做法。 1.…...

【深度学习|DenseNet-121】Densely Connected Convolutional Networks内部结构和参数设置

【深度学习|DenseNet-121】Densely Connected Convolutional Networks内部结构和参数设置 【深度学习|DenseNet-121】Densely Connected Convolutional Networks内部结构和参数设置 文章目录 【深度学习|DenseNet-121】Densely Connected Convolutional Networks内部结构和参数…...

数据结构与算法-要点整理

知识导图: 一、数据结构 包含:线性表(数组、队列、链表、栈)、散列表、树(二叉树、多路查找树)、图 1.线性表 数据之间就是“一对一“的逻辑关系。 线性表存储数据的实现方案有两种,分别是顺序存储结构和链式存储结构。 包含:数组、队列、链表、栈。 1.1 数组…...

Fort Firewall:全方位守护网络安全

Fort Firewall是一款专为 Windows 操作系统设计的开源防火墙工具&#xff0c;旨在为用户提供全面的网络安全保护。它基于 Windows 过滤平台&#xff08;WFP&#xff09;&#xff0c;能够与系统无缝集成&#xff0c;确保高效的网络流量管理和安全防护。该软件支持实时监控网络流…...

Nginx实战技巧(Practical Tips for nginx)

引言 简介 ‌Nginx&#xff08;发音为 "engine-x"&#xff09;是一个高性能的HTTP和反向代理服务器.‌ Nginx以其高并发处理能力、低资源消耗和灵活的配置而闻名&#xff0c;适用于高流量的Web服务器和应用程序。‌ Nginx的主要功能包括&#xff1a; ‌HTTP服务器…...

YOLOv8:目标检测与实时应用的前沿探索

随着深度学习和计算机视觉技术的迅速发展&#xff0c;目标检测&#xff08;Object Detection&#xff09;一直是研究热点。YOLO&#xff08;You Only Look Once&#xff09;系列模型作为业界广受关注的目标检测框架&#xff0c;凭借其高效、实时的特点&#xff0c;一直迭代更新…...

解锁数字经济新动能:探寻 Web3 核心价值

随着科技的快速发展&#xff0c;我们正迈入一个全新的数字时代&#xff0c;Web3作为这一时代的核心构成之一&#xff0c;正在为全球数字经济带来革命性的变革。本文将探讨Web3的核心价值&#xff0c;并如何推动数字经济的新动能。 Web3是什么&#xff1f; Web3&#xff0c;通常…...

Lua 环境的安装

1.安装Lua运行环境 本人采用的是在windows系统中使用cmd指令方式进行安装&#xff0c;安装指令如下&#xff1a; winget install "lua for windows" 也曾使用可执行程序安装过&#xff0c;但由于电脑是加密电脑&#xff0c;最后都已失败告终。使用此方式安装可以安…...

Object类(2)

大家好&#xff0c;今天我们继续来看看Object类中一些成员方法&#xff0c;这些方法在实际中有很大的用处&#xff0c;话不多说&#xff0c;来看。 注&#xff1a;所有类都默认继承Object类的&#xff0c;所以可调用Object类中的方法&#xff0c;如equals&#xff0c;也可以发生…...

汽车网络信息安全-ISO/SAE 21434解析(中)

目录 第七章-分布式网络安全活动 1. 供应商能力评估 2. 报价 3. 网络安全职责界定 第八章-持续的网络安全活动 1. 网路安全监控 2. 网络安全事件评估 3. 漏洞分析 4. 漏洞管理 第九章-概念阶段 1. 对象定义 2. 网路安全目标 3. 网络安全概念 第十章 - 产品开发 第十…...

fatal error C1083: ޷[特殊字符]ļ: openssl/opensslv.h: No such file or directory

一、环境 1. Visual Studio 2017 2. edk2&#xff1a;202305 3. Python&#xff1a;3.11.4 二、 fatal error C1083: ޷&#xbfab0;ļ: openssl/opensslv.h: No such file or directory 上图出现这个警告&#xff0c;不用管。 出现Done&#xff0c;说明编译成功。 执行上…...

C#System.Threading.Timer定时器意外回收注意事项

System.Threading.Timer定时器使用时会出现意外回收的情况。具体解释如下: 只要在使用 Timer,就必须保留对它的引用。对于任何托管对象,如果没有对 Timer 的引用,计时器会被垃圾回收。即使 Timer 仍处在活动状态,也会被回收。 实例对比测试 实例 定义两个类,其中一个…...

20.Word:小谢-病毒知识的科普文章❗【38】

目录 题目​ NO1.2.3文档格式 NO4.5 NO6.7目录/图表目录/书目 NO8.9.10 NO11索引 NO12.13.14 每一步操作完&#xff0c;确定之后记得保存最后所有操作完记得再次删除空行 题目 NO1.2.3文档格式 样式的应用 选中应用段落段落→开始→选择→→检查→应用一个一个应用ctr…...

vue3底层原理和性能优化

Vue 3 在底层原理和性能优化方面做了许多改进&#xff0c;以下是一些主要的优化点和原理&#xff1a; 1. 虚拟 DOM 的改进 静态树提升&#xff1a;Vue 3 能够检测到静态组件&#xff08;即不依赖响应式数据的组件&#xff09;并将其提升到渲染函数之外&#xff0c;从而减少不…...

Ubuntu介绍、与centos的区别、基于VMware安装Ubuntu Server 22.04、配置远程连接、安装jdk+Tomcat

目录 ?编辑 一、Ubuntu22.04介绍 二、Ubuntu与Centos的区别 三、基于VMware安装Ubuntu Server 22.04 下载 VMware安装 1.创建新的虚拟机 2.选择类型配置 3.虚拟机硬件兼容性 4.安装客户机操作系统 5.选择客户机操作系统 6.命名虚拟机 7.处理器配置 8.虚拟机内存…...