- 第3章 变量
-
- 程序中+号的使用
-
- 数据类型
-
- 整数类型
-
-
- 整型的类型
-
-
-
- 整型的使用细节IntDetail.java
-
-
- 浮点类型
-
-
- 浮点型的分类
-
-
-
- 浮点型使用细节FloatDetail.java
-
-
- Java API 文档
-
- 字符类型(char)
-
-
- 字符类型使用细节
-
-
-
- 字符本质探讨
-
-
- 布尔类型:boolean
-
- 基本数据类型转换
-
-
- 自动类型转换
-
-
-
- 自动类型转换注意和细节
-
-
-
- 强制类型转换
-
-
- 基本数据类型和String 类型的转换
-
-
- 介绍和使用
-
-
-
- 注意事项
-
第3章 变量
程序中+号的使用
1.当左右两边都是数值型时,则做加法运算
2.当左右两边有一方为字符串,则做拼接运算
数据类型
- java 数据类型分为两大类 基本数据类型 与 引用类型
- 基本数据类型有8种
-
- 数值型[byte , short , int , long , float ,double]
-
- char
-
- boolean
- 引用类型[类,接口, 数组]
整数类型
整型的类型
整型的使用细节IntDetail.java
Java各整数类型有固定的范围和字段长度,不受具体OS[操作系统]的影响,以保证java程序的可移植性。
Java的整型常量(具体值)默认为int型,声明long型常量须后加l
或L
浮点类型
浮点型的分类
- 关于浮点数在机器中存放形式的简单说明, 浮点数=符号位+指数位+尾数位
- 尾数部分可能丢失,造成精度损失(小数都是近似值)。
浮点型使用细节FloatDetail.java
与整数类型类似,Java浮点类型也有固定的范围和字段长度,不受具体OS的影响。
Java的浮点型常量(具体值)默认为double型,声明float型常量,须后加‘f或‘F'
浮点型常量有两种表示形式
- 十进制数形式:如:5.12 512.0f .512(必须有小数点)
- 科学计数法形式:如:5.12e2[5.12*10的2次方]5.12E-2[5.12/10的2次方]
通常情况下,应该使用double型,因为它比float型更精确。
double num9 = 2.1234567851;
float num10= 2.1234567851F;
浮点数使用陷阱:2.7和8.1/3比较
public class FloatDetail {
//编写一个main方法
public static void main(String[] args) {
//Java 的浮点型常量(具体值)默认为double型,声明float型常量,须后加‘f’或‘F'
//float num1 = 1.1; //对不对?错误
float num2 = 1.1F; //对的
double num3 = 1.1; //对
double num4 = 1.1f; //对
//十进制数形式:如:5.12 512.0f .512 (必须有小数点)
double num5 = .123; //等价 0.123
System.out.println(num5);
//科学计数法形式:如:5.12e2 [5.12 * 10的2次方 ] 5.12E-2 []
System.out.println(5.12e2);//512.0
System.out.println(5.12E-2);//0.0512
//通常情况下,应该使用double型,因为它比float型更精确。
//[举例说明]double num9 = 2.1234567851;float num10 = 2.1234567851F;
double num9 = 2.1234567851;
float num10 = 2.1234567851F;
System.out.println(num9);
System.out.println(num10);
//浮点数使用陷阱: 2.7 和 8.1 / 3 比较
//看看一段代码
double num11 = 2.7;
double num12 = 2.7; //8.1 / 3; //2.7
System.out.println(num11);//2.7
System.out.println(num12);//接近2.7的一个小数,而不是2.7
//得到一个重要的使用点: 当我们对运算结果是小数的进行相等判断时,要小心
//应该是以两个数的差值的绝对值,在某个精度范围类判断
if( num11 == num12) {
System.out.println("num11 == num12 相等");
}
//正确的写法 , ctrl + / 注释快捷键, 再次输入就取消注释
if(Math.abs(num11 - num12) < 0.000001 ) {
System.out.println("差值非常小,到我的规定精度,认为相等...");
}
// 可以通过java API 来看 下一个视频介绍如何使用API
System.out.println(Math.abs(num11 - num12));
//细节:如果是直接查询得的的小数或者直接赋值,是可以判断相等
}
}
当我们对运算结果是小数的进行相等判断时,要小心应该是以两个数的差值的绝对值,在某个精度范围类判断。
Java API 文档
API (Application Programming Interface,应用程序编程接口)是Java提供的基本编程接口(java提供的类还有相关的方法)。中文在线文档: 码工具 - 代码在线工具箱
Java语言提供了大量的基础类,因此 Oracle公司也为这些基础类提供了相应的API文档,用于告诉开发者如何使用这些类,以及这些类里包含的方法。
Java类的组织形式[图]
查询 ArrayList 类有哪些方法:
- 包->类->方法
- 直接索引 Math
字符类型(char)
字符类型可以表示单个字符,字符类型是char,char 是两个字节(可以存放汉字),多个字符用字符串String
字符类型使用细节
字符常量是用单引号('')括起来的单个字符
Java中还允许使用转义字符来将其后的字符转变为特殊字符型常量。
例如:char c3 = '\n'; 表示换行符
在java中,char的本质是一个整数,在输出时,是 unicode码对应的字符
Unicode编码转换 - 站长工具
char类型是可以进行运算的,相当于一个整数,因为它都对应有Unicode码.
字符本质探讨
字符型存储到计算机中,需要将字符对应的码值(整数)找出来,比如'a'
- 存储:`a'==>码值97 ==>二进制(110 0001) ==>存储
- 读取:二进制(110 0001)=>97 ===> 'a'=>显示
字符和码值的对应关系是通过字符编码表决定的(是规定好)
介绍一下字符编码表
- ASClI (ASCIl编码表一个字节表示,一个128个字符,实际上一个字节可以表示256个字符,只用128个)
- Unicode ( Unicode 编码表固定大小的编码使用两个字节来表示字符,字母和汉字统一都是占用两个字节这样浪费空间 )
-
- Unicode的好处: 一种编码,将世界上所有的符号都纳入其中。每一个符号都给予一个独一无二的编码,使用 Unicode 没有乱码的问题。
-
- Unicode 的缺点: 一个英文字母和一个汉字都占用2个字节,这对于存储空间来说是浪费。
-
- 2的16次方是65536,所以最多编码是65536个字符
-
- 编码0-127的字符是与ASCII的编码一样.比如'a'在ASCII码是0x61,在unicode码是
0x0061,都对应97.因此 Unicode码兼容ASCII码.
- 编码0-127的字符是与ASCII的编码一样.比如'a'在ASCII码是0x61,在unicode码是
- utf-8(编码表,大小可变的编码字母使用1个字节,汉字使用3个字节)gbk(可以表示汉字,而且范围广,字母使用1个字节,汉字2个字节)gb2312(可以表示汉字,gb2312 <gbk)
-
- UTF-8是在互联网上使用最广的一种Unicode的实现方式(改进)
-
- UTF-8是一种变长的编码方式。它可以使用1-6个字节表示一个符号,根据不同的符号而变化字节长度。
-
- 使用大小可变的编码字母占1个字节,汉字占3个字节
- big5码(繁体中文,台湾,香港)
布尔类型:boolean
布尔类型也叫boolean类型,booolean类型数据只允许取值true和false,无null
boolean类型占1个字节。
基本数据类型转换
自动类型转换
当java程序在进行赋值或者运算时,精度小的类型自动转换为精度大的数据类型,这个就是自动类型转换。
自动类型转换注意和细节
- 有多种类型的数据混合运算时,系统首先自动将所有数据转换成容量最大的那种数据类型,然后再进行计算。
- 当我们把精度(容量)大的数据类型赋值给精度(容量)小的数据类型时,就会报错,反之就会进行自动类型转换。
- (byte, short)和char之间不会相互自动转换。byte,short,char他们三者可以计算,在计算时首先转换为int类型。
- boolean不参与转换
- 自动提升原则:表达式结果的类型自动提升为操作数中最大的类型
强制类型转换
自动类型转换的逆过程,将容量大的数据类型转换为容量小的数据类型。使用时要加上强制转换符( ),但可能造成精度降低或溢出,格外要注意。
char类型可以保存int的常量值,但不能保存int的变量值,需要强转
public class ForceConvertDetail {
//编写一个main方法
public static void main(String[] args) {
//演示强制类型转换
//强转符号只针对于最近的操作数有效,往往会使用小括号提升优先级
//int x = (int)10*3.5+6*1.5;//编译错误: double -> int
int x = (int)(10*3.5+6*1.5);// (int)44.0 -> 44
System.out.println(x);//44
char c1 = 100; //ok
int m = 100; //ok
//char c2 = m; //错误
char c3 = (char)m; //ok
System.out.println(c3);//100对应的字符, d字符
}
}
基本数据类型和String 类型的转换
介绍和使用
在程序开发中,我们经常需要将基本数据类型转成String类型。或者将String类型转成基本数据类型。
- 基本类型转String类型语法:将基本类型的值+""即可
- String类型转基本数据类型语法:通过基本类型的包装类调用parseXX方法即可
public class StringToBasic {
//编写一个main方法
public static void main(String[] args) {
//String->对应的基本数据类型
String s5 = "123";
//会在 OOP 讲对象和方法的时候回详细
//解读 使用 基本数据类型对应的包装类的相应方法,得到基本数据类型
int num1 = Integer.parseInt(s5);
double num2 = Double.parseDouble(s5);
float num3 = Float.parseFloat(s5);
long num4 = Long.parseLong(s5);
byte num5 = Byte.parseByte(s5);
boolean b = Boolean.parseBoolean("true");
short num6 = Short.parseShort(s5);
System.out.println("===================");
System.out.println(num1);//123
System.out.println(num2);//123.0
System.out.println(num3);//123.0
System.out.println(num4);//123
System.out.println(num5);//123
System.out.println(num6);//123
System.out.println(b);//true
//怎么把字符串转成字符char -> 含义是指 把字符串的第一个字符得到
//解读 s5.charAt(0) 得到 s5字符串的第一个字符 '1'
System.out.println(s5.charAt(0));
}
}
注意事项
在将String 类型转成基本数据类型时,要确保String类型能够转成有效的数据 ,比如我们可以把"123" , 转成一个整数,但是不能把"hello" 转成一个整数。如果格式不正确,就会抛出异常,程序就会终止。
第3章 变量
程序中+号的使用
- 当左右两边都是数值型时,
+
作为加法运算符使用。 - 当左右两边有一方为字符串时,
+
作为字符串拼接运算符使用。
数据类型
- Java 数据类型分为两大类:基本数据类型与引用类型。
- 基本数据类型 包括:
-
- 数值型:
byte
,short
,int
,long
,float
,double
- 字符类型:
char
- 布尔类型:
boolean
- 数值型:
- 引用类型 包括:类、接口、数组。
整数类型
整型的类型
byte
: 8位,范围-128
到127
。short
: 16位,范围-32,768
到32,767
。int
: 32位,范围-2,147,483,648
到2,147,483,647
。long
: 64位,范围-9,223,372,036,854,775,808
到9,223,372,036,854,775,807
。
整型的使用细节 (IntDetail.java
)
- Java 的整数类型有固定的范围和字段长度,不受操作系统的影响,以保证 Java 程序的可移植性。
- Java 的整型常量默认为
int
型,声明long
型常量须后加l
或L
。
浮点类型
浮点型的分类
float
: 32位,大约7位有效数字。double
: 64位,大约15位有效数字。- 浮点数在机器中的存放形式由符号位、指数位和尾数位组成。
- 尾数部分可能会丢失,造成精度损失。
浮点型使用细节 (FloatDetail.java
)
- 与整数类型类似,Java 浮点类型也有固定的范围和字段长度,不受操作系统的影响。
- Java 的浮点型常量默认为
double
型,声明float
型常量须后加'f'
或'F'
。 - 浮点型常量有两种表示形式:
-
- 十进制数形式:如
5.12
、512.0f
、.512
。 - 科学计数法形式:如
5.12e2
、5.12E-2
。
- 十进制数形式:如
- 通常情况下,应该使用
double
型,因为它比float
型更精确。
Java API 文档
- Java 提供了大量的基础类,Oracle 公司为此提供了相应的 API 文档,用于告诉开发者如何使用这些类及类里的方法。
- 在线文档链接:码工具 - 代码在线工具箱
- 查询
ArrayList
类有哪些方法:
-
- 包->类->方法:进入 Java 的文档页面,找到
java.util
包,点击ArrayList
类,查看该类的方法列表。 - 直接索引:在文档首页的搜索框中输入
Math
,可以直接跳转到Math
类的文档页面。
- 包->类->方法:进入 Java 的文档页面,找到
字符类型 (char
)
- 字符类型可以表示单个字符,
char
是两个字节(可以存放汉字)。 - 字符常量是用单引号(
'
'
)括起来的单个字符。 - Java 中还允许使用转义字符来将其后的字符转变为特殊字符型常量,例如:
char c3 = '\n';
表示换行符。 - 在 Java 中,
char
的本质是一个整数,因为它们都对应有 Unicode 码。 char
类型是可以进行运算的,相当于一个整数。- 字符和码值的对应关系:是通过字符编码表决定的。
- 字符编码表:
-
- ASCII:一个字节表示,共 128 个字符。实际上一个字节可以表示 256 个字符,但只用了 128 个。
- Unicode:
-
-
- 固定大小的编码,使用两个字节来表示字符,字母和汉字统一都是占用两个字节,这样可能会浪费空间。
- 好处:一种编码,将世界上所有的符号都纳入其中。每一个符号都给予一个独一无二的编码,使用 Unicode 没有乱码的问题。
- 缺点:一个英文字母和一个汉字都占用 2 个字节,这对于存储空间来说是浪费。
- 最大编码数:2 的 16 次方是 65536,所以最多编码 65536 个字符。
- 兼容性:编码 0-127 的字符是与 ASCII 的编码一样的。例如
'a'
在 ASCII 码是0x61
,在 Unicode 码是0x0061
,都对应 97。
-
-
- UTF-8:
-
-
- 是在互联网上使用最广的一种 Unicode 的实现方式。
- 是一种变长的编码方式。它可以使用 1-6 个字节表示一个符号,根据不同的符号而变化字节长度。
- 使用大小可变的编码:字母占 1 个字节,汉字占 3 个字节。
-
-
- GBK:
-
-
- 可以表示汉字,而且范围广,字母使用 1 个字节,汉字使用 2 个字节。
- GB2312 < GBK
-
-
- Big5:繁体中文,主要用于台湾和香港。
布尔类型:boolean
- 布尔类型也叫
boolean
类型,boolean
类型数据只允许取值true
和false
,无null
。 boolean
类型占 1 个字节。
基本数据类型转换
自动类型转换
- 当 Java 程序在进行赋值或者运算时,精度小的类型自动转换为精度大的数据类型,这个过程称为自动类型转换。
- 注意事项:
-
- 有多种类型的数据混合运算时,系统首先自动将所有数据转换成容量最大的那种数据类型,然后再进行计算。
- 当把精度(容量)大的数据类型赋值给精度(容量)小的数据类型时,就会报错。
byte
,short
和char
之间不会相互自动转换。它们可以计算,在计算时首先转换为int
类型。boolean
不参与转换。- 自动提升原则:表达式结果的类型自动提升为操作数中最大的类型。
强制类型转换
- 自动类型转换的逆过程,将容量大的数据类型转换为容量小的数据类型。
- 使用时要加上强制转换符
()
,但可能造成精度降低或溢出,需要格外注意。 - 示例代码 (
ForceConvertDetail.java
):
public class ForceConvertDetail {
public static void main(String[] args) {
// 强制类型转换
int x = (int)(10*3.5+6*1.5); // (int)44.0 -> 44
System.out.println(x); // 输出 44
char c1 = 100; // ok
int m = 100; // ok
char c3 = (char)m; // ok
System.out.println(c3); // 输出 'd'
}
}
基本数据类型和 String
类型的转换
介绍和使用
- 基本类型转
String
类型:将基本类型的值+ ""
即可。 String
类型转基本数据类型:通过基本类型的包装类调用parseXX
方法即可。- 示例代码 (
StringToBasic.java
):
public class StringToBasic {
public static void main(String[] args) {
// String 类型转基本数据类型
String s5 = "123";
int num1 = Integer.parseInt(s5);
double num2 = Double.parseDouble(s5);
float num3 = Float.parseFloat(s5);
long num4 = Long.parseLong(s5);
byte num5 = Byte.parseByte(s5);
boolean b = Boolean.parseBoolean("true");
short num6 = Short.parseShort(s5);
System.out.println(num1); // 输出 123
System.out.println(num2); // 输出 123.0
System.out.println(num3); // 输出 123.0
System.out.println(num4); // 输出 123
System.out.println(num5); // 输出 123
System.out.println(num6); // 输出 123
System.out.println(b); // 输出 true
System.out.println(s5.charAt(0)); // 输出 '1'
}
}
注意事项
- 在将
String
类型转成基本数据类型时,要确保String
类型能够转成有效的数据,例如可以把"123"
转成一个整数,但不能把"hello"
转成一个整数。如果格式不正确,就会抛出异常,程序就会终止。
在Java编程中,数据类型和变量是非常基础且重要的概念。接下来,我们将对您提到的每个部分进行详细解释,并尽可能地拓展相关信息。
程序中+
号的使用
解释:
在Java中,+
号有多种用途,主要取决于其操作数的类型。如果操作数都是数值类型(如int
, double
等),那么+
号用作加法运算符。如果至少有一个操作数是字符串类型(String
),那么+
号则作为字符串拼接运算符使用。
int a = 5;
int b = 3;
System.out.println(a + b); // 输出 8
String s1 = "Hello, ";
String s2 = "World!";
System.out.println(s1 + s2); // 输出 Hello, World!
数据类型
解释:
Java的数据类型分为两大类:基本数据类型和引用类型。
- 基本数据类型包括:
-
- 数值型:
byte
,short
,int
,long
,float
,double
。 - 字符类型:
char
。 - 布尔类型:
boolean
。
- 数值型:
- 引用类型包括:
-
- 类(Class)。
- 接口(Interface)。
- 数组(Array)。
整数类型
解释:
整数类型在Java中固定为特定的字节数,不受操作系统的影响,从而保证了Java程序的可移植性。
byte
: 8位,范围-128
到127
。short
: 16位,范围-32,768
到32,767
。int
: 32位,范围-2,147,483,648
到2,147,483,647
。long
: 64位,范围-9,223,372,036,854,775,808
到9,223,372,036,854,775,807
。
拓展:
- Java中整型常量默认为
int
类型,如果需要指定为long
类型,则需在数值后加L
或l
。 int
类型足以满足大多数情况下的需求,但在需要更大范围或更高精度的情况下,可以选择使用long
类型。
浮点类型
解释:
浮点类型用于表示带小数点的数值。
float
: 32位,大约7位有效数字。double
: 64位,大约15位有效数字。
浮点数在计算机中是以符号位、指数位和尾数位的形式存储的,这可能导致在某些情况下出现精度损失。
float f = 1.1f; // 需要在数值后加 'f' 或 'F' 指定为 float 类型
double d = 1.1; // 默认为 double 类型
拓展:
- 浮点数在比较时应避免直接使用
==
运算符,因为精度损失可能导致两个理论上相等的浮点数在实际表示上略有差异。应当比较两者差值的绝对值是否在一个很小的范围内。
字符类型(char
)
解释:
char
类型用于表示单个字符,使用两个字节存储,可以存放汉字。
- 字符常量用单引号括起来。
char
类型本质上是一个整数,因为每个字符都对应Unicode码表中的一个位置。
char c = 'A'; // 字符常量
拓展:
- Java中的字符可以进行算术运算,这是因为字符在内存中是以它们的Unicode码值存储的。
- 了解不同字符编码(如ASCII、Unicode、UTF-8等)之间的区别对于处理国际化文本非常重要。
布尔类型(boolean
)
解释:
布尔类型只有两个值:true
和false
。
boolean
类型通常用于条件判断和逻辑运算。
拓展:
boolean
类型在内存中占用的空间不是固定的,而是由JVM实现决定的。- 在进行逻辑运算时,熟悉短路逻辑运算符(如
&&
,||
)的使用可以帮助优化性能。
类型转换
解释:
类型转换分为自动类型转换和强制类型转换。
- 自动类型转换:当精度较小的数据类型赋值给精度较大的数据类型时,会自动转换。
- 强制类型转换:将精度较高的数据类型转换为精度较低的数据类型时,需要显式地使用转换符。
int i = 10;
double d = i; // 自动类型转换
int j = (int) 10.5; // 强制类型转换,结果为 10
拓展:
- 在进行类型转换时,特别是在强制类型转换时,要特别注意可能发生的溢出或精度损失。
- 了解Java中的装箱和拆箱机制,即基本类型与它们的包装类之间的自动转换,也是很有帮助的。
基本数据类型与String
类型的转换
解释:
将基本数据类型转换为String
类型,可以通过将基本类型与空字符串拼接来实现。
int num = 123;
String strNum = "" + num; // 结果为 "123"
将String
类型转换为基本数据类型,则需要使用相应基本类型的包装类中的parseXxx
方法。
String strNum = "123";
int num = Integer.parseInt(strNum); // 结果为 123
拓展:
- 在处理用户输入或其他不确定的数据源时,确保进行适当的错误检查,防止转换过程中出现异常。
- 使用
try-with-resources
语句或异常处理机制来安全地处理潜在的转换错误。
Java标准库包含了大量有用的类和接口,这些类和接口覆盖了从基本的数据结构到网络通信等各种功能。下面是一些常用的类和接口的概览,这些类和接口被广泛应用于Java应用程序中:
数据结构相关的类和接口
- 集合框架(Collection Framework):
-
List
:有序集合,如ArrayList
和LinkedList
。Set
:不允许重复元素的集合,如HashSet
和TreeSet
。Map
:键值对映射,如HashMap
和TreeMap
。Queue
:队列,如PriorityQueue
。Deque
:双端队列,如ArrayDeque
。Stack
:栈,继承自Vector
,但已过时,建议使用Deque
实现。
基础类
Object
:所有类的基类,提供了诸如toString()
,equals()
,hashCode()
等方法。String
:不可变的字符序列,提供了许多用于字符串操作的方法。StringBuilder
和StringBuffer
:可变的字符序列,前者线程不安全但效率较高,后者线程安全但效率稍低。Integer
,Double
,Long
,Character
,Boolean
等:基本数据类型的包装类,提供了如parseInt()
,parseDouble()
等静态方法用于基本类型和字符串之间的转换。
输入输出(IO)相关的类和接口
InputStream
,OutputStream
:处理字节流的抽象类。Reader
,Writer
:处理字符流的抽象类。FileInputStream
,FileOutputStream
:处理文件的输入输出。BufferedReader
,BufferedWriter
:带有缓冲区的字符流。DataInputStream
,DataOutputStream
:用于读写基本数据类型。ObjectInputStream
,ObjectOutputStream
:用于对象的序列化和反序列化。PrintStream
:用于标准输出和错误输出。
文件和目录管理
File
:表示文件和目录的类。Path
,Paths
:新的路径和文件系统API的一部分,提供了更强大的文件路径处理能力。Files
:提供了一系列静态方法来操作文件和目录。
线程和并发
Thread
:表示线程的类。Runnable
:线程可以实现的接口。ExecutorService
,Executors
:用于创建线程池。Future
,FutureTask
:用于异步计算的结果。Semaphore
,CountDownLatch
,CyclicBarrier
:控制多个线程间的同步。BlockingQueue
:阻塞队列,用于多线程间的通信。AtomicInteger
,AtomicLong
:原子变量,用于无锁编程。
日历和日期
Calendar
:提供日期和时间的高级视图。Date
:表示日期和时间的类。LocalDate
,LocalTime
,LocalDateTime
:新的日期时间API,提供了更清晰的时间模型。Instant
:表示UTC时刻。Duration
:表示两个时间点之间的持续时间。Period
:表示两个日期之间的间隔。
网络编程
Socket
:客户端套接字。ServerSocket
:服务器端套接字。DatagramSocket
,DatagramPacket
:用于UDP协议的套接字和数据包。InetAddress
:表示IP地址。URLConnection
:提供访问URL资源的方法。
安全性和加密
SecurityManager
:控制程序的权限。KeyPairGenerator
,KeyPair
:生成密钥对。Cipher
:用于加密和解密数据。MessageDigest
:生成消息摘要。SecureRandom
:生成安全随机数。
反射和代理
Class
:表示类的类。Field
,Method
,Constructor
:分别表示类的字段、方法和构造函数。Proxy
:创建动态代理。
序列化
Serializable
:标记一个类可以被序列化。ObjectInputStream
,ObjectOutputStream
:用于读写对象的序列化形式。
GUI编程
Swing
:轻量级组件库,用于创建图形用户界面。AWT
:重量级组件库,提供了低级图形功能。
日志记录
Logger
,LogManager
:用于记录应用程序的日志信息。
SQL支持
java.sql.*
:提供与数据库交互的功能,如Connection
,Statement
,PreparedStatement
,ResultSet
等。
动态语言支持
ScriptEngineManager
,ScriptEngine
:用于执行脚本语言。
当然,我们可以继续深入探讨Java的知识。以下是几个关键领域的扩展:
高级特性
Java作为一个成熟的编程语言,随着时间的发展引入了许多高级特性,这些特性提高了开发者的生产力和代码的可维护性。
Lambda 表达式和流(Streams)
Lambda表达式允许你传递行为作为方法的参数,即可以将代码当作一个参数传递到一个方法中。这使得代码更加简洁易读。
List<String> list = Arrays.asList("a", "b", "c");
list.stream().forEach(System.out::println);
函数式接口(Functional Interfaces)
函数式接口是指仅仅只有一个抽象方法的接口,可以用来定义lambda表达式的类型。
@FunctionalInterface
interface MyFunc {
int apply(int x, int y);
}
选项类型(Optional)
Optional
类是为了避免空指针异常而提供的解决方案,它代表了一个可能含有也可能不含非空值的容器对象。
Optional<String> optional = Optional.ofNullable(null);
optional.ifPresent(System.out::println);
方法引用(Method References)
方法引用提供了引用已有Java类或对象(实例)的方法或构造器的能力。方法引用可以使语言的构造更紧凑简洁。
List<String> list = Arrays.asList("a", "b", "c");
list.sort(String::compareTo);
类型推断(局部变量类型推断)
从Java 10开始,可以使用var关键字声明局部变量,编译器会根据上下文推断出变量的类型。
var number = 10; // number的类型为int
设计模式
设计模式是软件工程中的一种通用解决方案,用于解决常见的设计问题。Java中有许多设计模式,例如:
单例模式(Singleton Pattern)
确保一个类只有一个实例,并提供一个全局访问点。
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}
工厂模式(Factory Pattern)
提供创建对象的接口,但让子类决定实例化哪一个类。
public interface Shape {
void draw();
}
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Rectangle::draw()");
}
}
public class ShapeFactory {
public static Shape getShape(String shapeType){
if(shapeType == null){
return null;
}
if(shapeType.equalsIgnoreCase("RECTANGLE")){
return new Rectangle();
}
return null;
}
}
观察者模式(Observer Pattern)
当对象的状态发生改变时,所有依赖它的对象都会得到通知。
import java.util.Observable;
import java.util.Observer;
public class ObserverExample {
public static void main(String[] args) {
Observable observable = new Observable();
Observer observer = new Observer() {
@Override
public void update(Observable o, Object arg) {
System.out.println("Observer notified!");
}
};
observable.addObserver(observer);
observable.setChanged();
observable.notifyObservers();
}
}
并发编程
Java并发编程涉及到多线程、线程安全、同步机制等方面,这些是构建高性能应用的关键。
线程池(Thread Pool)
使用ExecutorService
来管理和控制线程。
ExecutorService executor = Executors.newFixedThreadPool(5);
executor.submit(new Runnable() {
public void run() {
System.out.println(Thread.currentThread().getName() + " is running");
}
});
锁(Lock)
使用ReentrantLock
来手动控制锁的获取和释放。
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockExample {
private final Lock lock = new ReentrantLock();
public void methodRequiringLock() {
lock.lock();
try {
// 执行临界区代码
} finally {
lock.unlock();
}
}
}
原子操作(Atomic Operations)
使用AtomicInteger
等类来进行线程安全的原子操作。
import java.util.concurrent.atomic.AtomicInteger;
public class AtomicIntegerExample {
private final AtomicInteger count = new AtomicInteger(0);
public void increment() {
count.incrementAndGet();
}
public int getCount() {
return count.get();
}
}
框架和工具
除了Java本身的特性之外,还有大量的框架和工具支持Java开发,如Spring框架、Hibernate ORM、Maven构建工具等。
Spring框架
Spring是一个流行的Java平台,提供了广泛的基础设施支持,简化了企业级应用开发。
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringExample {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
SomeBean someBean = (SomeBean) context.getBean("someBean");
someBean.doSomething();
}
}
Hibernate ORM
Hibernate是一个ORM框架,简化了数据库操作,使开发者能够专注于业务逻辑而非底层数据库交互。
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateExample {
public static void main(String[] args) {
SessionFactory factory = new Configuration().configure().buildSessionFactory();
Session session = factory.openSession();
session.beginTransaction();
// 操作数据库
session.getTransaction().commit();
session.close();
factory.close();
}
}
Java的高级特性随着版本的迭代不断增加,以下是一些额外的高级特性,它们在不同的Java版本中被引入,旨在提高开发者的生产力、增强代码的安全性和可读性、优化性能等:
模块化系统(Jigsaw Project, Java 9)
模块化系统是Java平台的一个重要发展,它允许开发者以模块的形式来组织自己的代码。模块之间可以声明依赖关系,并控制对外部模块的可见性。这有助于大型项目的组织和管理。
module com.example.myapp {
requires java.base;
requires java.logging;
exports com.example.myapp.api to com.example.myapp.impl;
}
记录(Records, Java 14+)
记录是一种特殊的类,它提供了一个便捷的方式来创建不可变的数据承载类。它们是final的,并且自动获得了构造函数、toString()、equals()和hashCode()方法的实现。
record Point(int x, int y) {}
密封类(Sealed Classes, Java 15+)
密封类限制了可以继承它的子类的数量,这对于实现有限的继承层次结构非常有用。
sealed class Shape permits Circle, Square {
// ...
}
文本块(Text Blocks, Java 13+)
文本块允许你定义多行字符串而不需要转义字符。
String message = """
Hello,
Welcome to the Java world!
""";
空值合并运算符(Elvis Operator, Java 7+)
空值合并运算符(? :
)是一种条件运算符,当左侧的操作数为null时,返回右侧的操作数。
String name = user.getName() != null ? user.getName() : "Anonymous";
空安全性(Null Safety)
虽然Java本身没有内置的空安全特性,但是可以通过使用一些工具和技术(如Lombok库、Kotlin语言等)来减少空指针异常的风险。
记录模式匹配(Pattern Matching for Records, Java 18+)
这是一种更简洁的模式匹配语法,可以用于if和switch语句中,以简化逻辑判断。
if (Point recordPoint instanceof Point(int x, int y)) {
// 使用 x 和 y
}
文件I/O改进(Java NIO.2, Java 7+)
NIO.2引入了对文件I/O的重要改进,包括多路复用、非阻塞I/O等。
Path path = Paths.get("/path/to/file");
Files.lines(path).forEach(System.out::println);
字符串模板(Template Strings)
尽管Java目前没有内置的字符串模板功能,但可以通过第三方库实现类似的功能。
垃圾回收器改进
随着时间的推移,Java的垃圾回收器得到了不断的改进,如G1(Garbage First)、ZGC(Z Garbage Collector)和Shenandoah等,这些垃圾回收器旨在减少暂停时间并提高性能。
本地访问终端(LTS)版本的支持
Java每隔几年发布一个新的长期支持(LTS)版本,如Java 8、11、17等,这些版本通常会得到较长时间的支持,适合生产环境部署。
编译器和工具链改进
Java编译器不断优化,支持提前分析、延迟绑定等功能,工具链方面也有各种IDE(如IntelliJ IDEA、Eclipse等)和构建工具(如Maven、Gradle等)的支持。
这些特性不仅提升了Java语言的功能性,还使其更加现代化,适合构建复杂的企业级应用。每一代Java的新特性都是为了应对当前软件开发面临的挑战而设计的。