Java的数据类型分为基本数据类型和引用数据类型;
整数类型用于表示没有小数部分的数值。Java提供了四种整数类型:
注:类型的数值范围记个大概就够了
浮点类型用于表示有小数部分的数值。Java提供了两种浮点类型:
在Java中,引用数据类型是相对于基本数据类型而言的,它们是通过引用来访问的。引用数据类型是Java中除了基本数据类型之外的所有类型,主要包括类(Class)、接口(Interface)、数组(Array)、枚举(Enum)以及特殊的类型如字符串(String,String尽管在Java中String被设计为一个类,但它也常被归类为引用数据类型)和泛型类型(Generic Types)等。
通过引用来访问
引用数据类型不直接存储数据值,而是存储对象的引用(即内存地址),通过引用间接访问对象的数据。
可变性
引用数据类型的变量可以指向不同的对象,即它们的值(实际上是对象的引用)可以在程序运行过程中改变。
空引用
引用数据类型的变量可以引用一个实际的对象,也可以引用NULL
(表示没有任何对象)。
动态分配
引用数据类型的变量所指向的对象是在运行时动态分配的,其生命周期由垃圾回收器管理。
类(Class)
类是Java中最常见的引用数据类型。它定义了一种数据结构,包含字段(属性)和方法(行为)。类是面向对象编程的基础。[访问控制] (abstract) class 类名 (implements){...}
接口(Interface)
接口是一种特殊的引用数据类型,它定义了一组方法,但不提供实现。类可以实现一个或多个接口,以定义特定的行为。接口在Java中使用interface
关键字定义,可以包含抽象方法、默认方法和静态方法。interface用于声明一个接口,例如:
public interface A{
void b();
}
数组(Array)
数组是一种引用数据类型,用于存储固定大小的相同类型元素的集合。数组在创建时需要指定大小,且大小不能更改。
枚举(Enum)
枚举是一种特殊的引用数据类型,它表示一组固定的常量。枚举用于定义一组预定义的值。enum表示枚举,用于限制变量值的类型,例如:
public enum Alpha (implements 接口){
(public static final)a,b,c,d
}
规定对象的实例只能为a,b,c,d其中之一。
枚举类中可以有成员变量和方法。
字符串(String)
字符串在Java中是一个类,专门用来表示字符序列。尽管String是一个类,但它常被归类为引用数据类型。字符串是不可变的,即一旦创建就不能修改。
泛型类型(Generic Types)
泛型类型允许类、接口和方法操作任意类型的数据,这样就可以使用一种通用方法,而不需要为每种数据类型编写特定的方法。
变量是内存中的一个存储区域,该区域的数据可以在同一类型范围内不断变化。变量包含三个基本元素:变量类型、变量名和存储的值。变量用于在内存中保存数据,是程序中最基本的存储单元。
在Java中,每个变量在使用前必须声明其类型,因为Java是一种强类型语言。变量的声明遵循以下格式:
java<数据类型> <变量名称>;
例如,声明一个整型变量int age;
。
变量可以在声明时初始化(即赋值),也可以在之后的代码中赋值。赋值的语法如下:
<变量名称> = <值>;
例如,age = 25;
表示将整数25赋值给变量age
。
变量的作用域决定了变量的可访问范围。根据声明的位置不同,变量可以分为局部变量、实例变量和类变量(静态变量)。
variableName
和VariableName
被视为两个不同的变量名。int
、class
、return
等)。这些关键字有特殊的意义,用于表示语法结构。userName
、customerId
。final
关键字修饰的变量),通常使用全部大写字母和下划线分隔单词的方式命名,例如MAX_SIZE
、PI
。变量可以参与各种运算,包括算术运算、赋值运算、比较运算和逻辑运算。变量名用于访问变量存储的数据。
算术运算符用于执行基本的数学运算,如加法、减法、乘法、除法和取模(取余)等。
+
:加法运算符,用于两个数相加。-
:减法运算符,用于两个数相减。*
:乘法运算符,用于两个数相乘。/
:除法运算符,用于两个数相除。注意,当除数为0时,会出现ArithmeticException
异常。%
:取模运算符,用于求两个数相除的余数。关系运算符用于比较两个值的关系,如等于、不等于、大于、小于等,并返回布尔值(true
或false
)用于条件判断。
==
:等于运算符,用于判断两个值是否相等。!=
:不等于运算符,用于判断两个值是否不相等。>
:大于运算符,用于判断左侧操作数是否大于右侧操作数。<
:小于运算符,用于判断左侧操作数是否小于右侧操作数。>=
:大于等于运算符,用于判断左侧操作数是否大于等于右侧操作数。<=
:小于等于运算符,用于判断左侧操作数是否小于等于右侧操作数。逻辑运算符用于连接两个或多个布尔表达式,并返回一个布尔值。
&&
:逻辑与运算符,当且仅当两个布尔值都为true
时,结果为true
。||
:逻辑或运算符,当且仅当两个布尔值中至少有一个为true
时,结果为true
。!
:逻辑非运算符,用于对布尔值取反。赋值运算符用于将值赋给变量。
=
:基本的赋值运算符,用于将右侧表达式的值赋给左侧的变量。+=
、-=
、*=
、/=
、%=
:复合赋值运算符,它们结合了赋值和算术运算,例如a += b
等价于a = a + b
。自增和自减运算符用于增加或减少变量的值。
++
:自增运算符,将变量的值增加。--
:自减运算符,将变量的值减少。这两种运算符都有前缀和后缀两种形式,它们在表达式中的位置会影响其值何时被计算。
位运算符用于对二进制位进行操作,如按位与、按位或、按位异或、按位取反和位移操作等。
&
:按位与运算符。|
:按位或运算符。^
:按位异或运算符。~
:按位取反运算符。<<
:左移运算符。>>
:带符号右移运算符。>>>
:无符号右移运算符(Java特有)。条件运算符是Java中唯一的三元运算符,用于根据条件选择两个值中的一个。
条件 ? 值1 : 值2
。如果条件为真,则结果为值,否则为值。类型转换运算符用于将值从一种数据类型转换为另一种数据类型。
(类型名)
进行显式转换,可能会导致数据丢失或精度下降。在Java中,+
运算符还可以用于连接两个字符串。
Java还包含一些特殊运算符,如instanceof
(用于判断对象是否是特定类的实例)、new
(用于创建对象的实例)等。
Java中的运算符具有不同的优先级和结合性,这决定了它们在表达式中的计算顺序。通常,算术运算符的优先级高于比较运算符,而赋值运算符的优先级最低。在复杂的表达式中,可以使用括号来改变运算符的优先级
顺序结构是最基础的流程控制结构,程序按照代码的顺序逐行执行。在顺序结构中,没有特定的控制语句,代码按照书写的顺序从上到下依次执行。
选择结构用于根据条件判断执行不同的代码块。Java中主要有以下几种选择结构:
if(表达式){语句}
若表达式为真,则执行后面的语句。
switch(变量){
case value1:语句1;
break;
case value2:语句2;
break;
...
default:语句;
}
若变量和case后的值相等则执行语句。
当语句执行到break时跳到switch块后,如果没有break会产生穿透现象。
default分支必须为最后一个分支,在没有值和case变量相等时执行该语句。
循环结构用于重复执行一段代码,直到满足某个终止条件。Java中主要有以下几种循环结构:
while(判读语句){
循环体...
}
do{
循环体...
}while(判读语句)
for(初始化循环变量; 判断执行条件;更新循环变量){
语句
}
for(变量:数组){
语句
}
跳转结构用于改变程序的执行流程。Java中主要有以下几种跳转语句:
break在switch中用于跳出switch块,停止switch向下穿透的现象。
case value:expression;
break;
break在循环中用于跳出循环。
while(...){
...
break;
}
break也可以在后面接标签,用来跳出一些嵌套比较复杂的循环中。
flag:
for(...){
for(...){
break flag;
}
}
continue用于在循环中跳过本次循环。
while(...){
...
continue;
}
continue也可以在后面接标签,在一些嵌套比较复杂的循环中跳过一次循环。
flag:
for(...){
for(...){
continue flag;
}
}
Java提供了一套完整的异常处理机制,用于处理程序中的错误情况。异常处理结构包括try块、catch块和finally块:
try{
...
}catch(Exception e){
...
}finally{
...
}
通过方法的返回值,可以在某种条件下提前结束方法的执行并返回到调用者,也可以在某种条件下改变方法的执行流程。这是方法设计中的一个重要方面,有助于实现更加灵活和可复用的代码。
标识符是Java语言中用于给变量、类、方法、包等命名的符号。它们可以是字母(A-Z,a-z)、数字(0-9)、下划线(_)或美元符号($)的任意组合,但有一些限制:
1variable
是不合法的标识符,但variable1
是合法的。int
、class
、return
等都不能用作标识符。myVar
和myvar
被视为两个不同的标识符。my variable
不是合法的标识符,但my_variable
或myVariable
是合法的。标识符的命名最好能够反映出其作用,使得代码易于阅读和维护。例如,使用userName
来表示用户名,password
来表示密码。
在Java中,不同类型的标识符有不同的命名约定:
关键字是Java编程语言中预定义的保留字,它们具有特殊的含义和用途,用于表示特定的语言功能或概念。例如,int
用于声明一个整型变量,class
用于声明一个类,return
用于从方法中返回结果等。
Java中的关键字都是小写的,不能用作变量名、类名或其他标识符。Java语言目前定义了多个关键字,包括数据类型关键字(如int
、float
、char
等)、流程控制关键字(如if
、else
、while
等)、访问控制关键字(如public
、private
、protected
等)、异常处理关键字(如try
、catch
、finally
等)以及其他特殊用途的关键字(如null
、this
、super
等)。
需要注意的是,虽然true
、false
、null
等词在Java中有特殊的含义,但它们并不是关键字,而是字面量(Literals)。另外,sizeof
是C/C++中的关键字,但在Java中并不存在。const是Java的一个保留关键字,没有实际意义,但是不能用于做变量名(因为被保留作为关键字了)。在C语言中表示常量,类似Java的final。goto是Java中的保留关键字,没有实际意义,但是不能用做变量名。在C中表示无条件跳转语句。
类作用域指的是在类中声明的变量(也称为成员变量或属性)。这些变量可以在类的任何方法中使用,包括构造方法、实例方法和静态方法。类作用域的变量从定义变量的位置开始,一直持续到类的生命周期结束。成员变量可以是实例变量或静态变量,其中实例变量属于类的每个实例,而静态变量则属于类本身,被类的所有实例共享。
方法作用域指的是在方法中声明的变量(也称为局部变量)。这些变量只能在该方法内部访问,一旦方法执行完毕,这些变量就会被销毁。方法作用域的变量包括在方法体、构造方法体或任何代码块(如if语句、for循环等)中声明的变量。
代码块作用域指的是在代码块(由大括号{}
包围的代码区域)中声明的变量。这些变量只能在定义它们的代码块内部访问。一旦代码块执行完毕,这些变量就会被销毁。代码块可以出现在方法内部、构造方法内部或任何需要局部作用域的地方。
循环作用域实际上可以看作是代码块作用域的一种特殊情况,它指的是在循环(如for循环、while循环等)中声明的变量。这些变量只能在循环体内部访问,并在每次循环迭代时重新初始化(对于for循环中的初始化部分)。然而,需要注意的是,在Java中并没有明确区分“循环作用域”这一概念,它通常被归类为代码块作用域的一种。
局部作用域是一个相对宽泛的概念,它通常指的是在方法、构造方法或代码块中声明的变量的作用域。这些变量只能在其声明的局部作用域内访问。需要注意的是,局部作用域并不是一个独立的作用域类型,而是对方法作用域和代码块作用域的一种统称。
单行注释以双斜杠//
开头,后面跟着注释内容。编译器会忽略从//
开始到该行末尾的所有文本。单行注释通常用于解释或说明一行代码的功能或用途。
示例:
// 这是单行注释 int number = 10; // 这也是单行注释,放在代码行末尾
多行注释以/*
开头,以*/
结束。多行注释可以跨越多行,编译器会忽略/*
和*/
之间的所有文本。多行注释通常用于对代码段进行说明或注释。
注意:多行注释不能嵌套使用,即在一个多行注释内部不能再使用另一个多行注释。
示例:
/* 这是一个多行注释 它可以跨越多行 直到遇到结束标记 */ public class MyClass { // 类体内容... }
文档注释以/**
开头,以*/
结束。文档注释通常用于对类、接口、方法、变量等进行详细的说明,这些注释可以通过Javadoc工具自动生成API文档。
文档注释可以包含HTML标签,并且Javadoc工具可以识别并处理这些标签,以生成格式化的文档。文档注释还可以包含一些特定的Javadoc标签(如@param
、@return
、@throws
等),用于提供更详细的参数说明、返回值说明和异常说明。
示例:
/**
* 这是一个文档注释 * 用于说明MyClass类的功能 * * @author 作者名 * @version 版本号 */ public class MyClass { /** * 计算两个整数的和 * * @param a 第一个加数 * @param b 第二个加数 * @return 返回两个加数的和 */ public int add(int a, int b) { return a + b; } }
自动装箱是指Java编译器在需要时自动将基本数据类型转换为对应的包装类对象的过程。在Java中,基本数据类型包括int
、double
、char
等,而它们对应的包装类则分别是Integer
、Double
、Character
等。
示例:
int i = 10; Integer boxedI = i; // 自动装箱:将基本数据类型int转换为Integer对象
在上面的示例中,虽然我们没有显式地调用Integer.valueOf(i)
来创建Integer
对象,但Java编译器会自动进行这一转换,这就是自动装箱。
自动拆箱则是自动装箱的逆过程,即Java编译器在需要时自动将包装类对象转换为其对应的基本数据类型值的过程。
示例:
Integer boxedI = 10; int i = boxedI; // 自动拆箱:将Integer对象转换为基本数据类型int
在上面的示例中,虽然我们没有显式地调用boxedI.intValue()
来获取int
值,但Java编译器会自动进行这一转换,这就是自动拆箱。
Integer.valueOf(i)
的代码;在自动拆箱时,编译器会插入类似于boxedI.intValue()
的代码。null
,则会自动拆箱失败并抛出NullPointerException
。==
比较包装类对象时,比较的是对象的引用而不是值。因此,在比较包装类对象的值时,应使用.equals()
方法。缓存池是一种存储和管理已创建对象的内存区域。当应用程序需要某个类型的对象时,它会首先尝试从缓存池中获取该对象,而不是直接创建一个新的对象。如果缓存池中有可用的对象,则直接返回该对象;如果没有,则创建一个新对象并将其添加到缓存池中,然后再返回给应用程序。通过这种方式,缓存池减少了对象的创建和销毁次数,提高了系统的性能和资源利用率。
缓存池的工作原理主要包括以下几个步骤:
在Java中,数据类型缓存池的实现方式多种多样,以下是一些常见的实现方式:
ArrayList
、LinkedList
等)来实现简单的缓存池。然而,这种方式通常不够高效,因为它没有提供对象重用和并发控制等高级功能。数据类型缓存池的优势主要包括以下几点: