java基础语法

JVM,JDK,JRE三者的关系

概念

JVM(Java Virtual Machine,Java虚拟机)、JDK(Java Development Kit,Java开发工具包)、JRE(Java Runtime Environment,Java运行环境)

  1. JVM (Java Virtual Machine): JVM是Java程序的运行环境核心,它是一个抽象化的计算机,能够执行Java字节码。JVM负责将编译后的字节码转换为特定硬件平台上的机器指令并执行。每个Java应用都是在JVM上运行的,这使得Java具有“一次编写,到处运行”的跨平台能力。

  2. JRE (Java Runtime Environment): JRE是运行Java应用程序所必需的环境。它包含了JVM以及Java类库(也就是Java SE API),提供运行Java程序的基础。JRE使用户能够在没有开发需求的计算机上运行Java应用程序,但它不包含开发工具,如编译器或调试器。

  3. JDK (Java Development Kit): JDK是面向Java开发者的工具包,它不仅包含了JRE的所有内容(即JVM和运行Java程序所需的类库),还额外提供了编译器(javac)、调试器(jdb)、文档生成工具(javadoc)以及其他开发工具,使得开发者能够编写、编译、调试和部署Java应用程序。简单来说,如果你想编写Java程序,就需要安装JDK。

总结:

  • 层次结构上,JDK位于最顶层,它包含了JRE;而JRE又包含了JVM。
  • 功能区分上,JDK服务于开发过程,提供编译、调试等开发工具;JRE服务于程序运行,提供运行环境;JVM是运行Java字节码的引擎,是这一切的基础。
  • 安装关系上,安装JDK时会自动安装JRE和JVM,因为开发过程中既需要运行环境也需要开发工具。而如果你只需要运行Java程序,则只需安装JRE,此时也会自动包含JVM。

基本数据类型

java的基本数据类型有8种,分别是byte,short ,int,long,float,double,char,boolean.

符号位中,0代表正数,1代表负数。

  1. 数值型

    • byte: 8位有符号整数。默认值为0。

    • short: 16位有符号整数。默认值为0。

    • int: 32位有符号整数。默认值为0。

    • long: 64位有符号整数。在数值后加"L"表示长整型。

    • float: 32位单精度浮点数。默认值为0.0f,数值后加"F"。

    • double: 64位双精度浮点数,提供更高的精度。Java中默认的浮点数类型。默认值为0.0,无需后缀。

  2. 字符型

    • char: 16位无符号Unicode字符。可以存储任何字符,包括字母、数字、标点符号等。
  3. 布尔型

    • boolean: 逻辑类型,只接受两个值:true 或 false。默认值未明确指定,但在实际编程中,未初始化的布尔变量应避免使用。

为了能在泛型集合或需要对象的地方使用这些基本类型,Java提供了相应的包装类,比如 Byte, Short, Integer, Long, Float, Double, Character, 和 Boolean。这些包装类作为对象存在,提供了丰富的操作方法,并能与基本类型进行自动装箱和拆箱操作。 

 类型转换

Java中的类型转换主要分为两种情况:自动类型转换(隐式转换) 和 强制类型转换(显式转换)

自动类型转换(隐式转换)

自动类型转换发生在两种场景:
1. 小范围类型向大范围类型转换:例如,将`byte`、`short`、`char`类型自动转换为`int`类型,或者将`int`类型转换为`long`、`float`、`double`类型。这是因为大类型能容纳小类型的所有可能值。
2. 从低级原始类型向高级原始类型转换:如`int`转`long`、`float`转`double`等,这不会造成数据丢失。

强制类型转换(显式转换)

强制类型转换需要开发人员显式地指明类型转换的方向,通常用于将大范围类型转换为小范围类型,或者将对象转换为其超类或接口类型。这可能导致数据丢失或精度下降。

注意事项:


- 强制类型转换可能导致数据溢出或精度损失。
- 当将一个对象转换为其父类或实现了的接口类型时,这种转换是安全的,不需要显式转换。
- 将父类对象转换为子类类型(向下转型)时,必须确保该对象实际上是目标子类的实例,否则会抛出`ClassCastException`异常。

类型转换与包装类

Java还提供了基本类型与其对应的包装类之间的自动装箱和拆箱操作,这也是类型转换的一种形式:
自动装箱:自动将基本类型转换为对应的包装类实例,如 `int i = 10; Integer num = i;`
自动拆箱:自动将包装类实例转换为基础类型,如 `Integer num = 10; int i = num;`

标识符

标识符是用户编程时使用的名字,用于给类、方法、变量、常量等命名。

Java中标识符的组成规则:

由字母、数字、下划线“_”、美元符号“$”组成,第一个字符不能是数字。

不能使用java中的关键字作为标识符。

标识符对大小写敏感(区分大小写)。

Java中标识符的命名约定:

小驼峰式命名:变量名、方法名

首字母小写,从第二个单词开始每个单词的首字母大写。

大驼峰式命名:类名

每个单词的首字母都大写。

另外,标识符的命名最好可以做到见名知意

例如:username、studentNumber等。

 运算符

和别的语言大差不差,就是+-*/自增自减大于小于。 

符号作用说明
&逻辑与a&b,a和b都是true,结果为true,否则为false
|逻辑或a|b,a和b都是false,结果为false,否则为true
^逻辑异或a^b,a和b结果不同为true,相同为false
!逻辑非!a,结果和a的结果正好相反

 

&&短路与作用和&相同,但是有短路效果        
||短路或作用和\|相同,但是有短路效果

具有短路效果。只要有一个表达式的值为false,那么结果就可以判定为false了,没有必要将所有表达式的值都计算出来,短路与操作就有这样的效果,可以提高效率。同理在逻辑或运算中,一旦发现值为true,右边的表达式将不再参与运算。

三元运算符

关系表达式 ? 表达式1 : 表达式2;

解释:问号前面的位置是判断的条件,判断结果为boolean型,为true时调用表达式1,为false时调用表达式2。其逻辑为:如果条件表达式成立或者满足则执行表达式1,否则执行第二个。

int a = 10;
int b = 20;
int c = a > b ? a : b; // 判断 a>b 是否为真,如果为真取a的值,如果为假,取b的值

分支结构

if结构

if (关系表达式) {
    语句体;	
}
if (关系表达式) {
    语句体1;	
} else {
    语句体2;	
}
if (关系表达式1) {
    语句体1;	
} else if (关系表达式2) {
    语句体2;	
} 
…
else {
    语句体n+1;
}

括号里判断为真执行。

switch语句

switch (表达式) {
	case 1:
		语句体1;
		break;
	case 2:
		语句体2;
		break;
	...
	default:
		语句体n+1;
		break;
}

执行流程:

* 首先计算出表达式的值 
* 其次,和case依次比较,一旦有对应的值,就会执行相应的语句,在执行的过程中,遇到break就会结 束。 
* 最后,如果所有的case都和表达式的值不匹配,就会执行default语句体部分,然后程序结束掉。

case穿透

 case穿透是如何产生的?
 如果switch语句中,case省略了break语句, 就会开始case穿透.
 现象:
 当开始case穿透,后续的case就不会具有匹配效果,内部的语句都会执行
直到看见break,或者将整体switch语句执行完毕,才会结束。

class Demo{
public static void main(String[] args){
show(0);
show(1);
}
public static void show(int i){
switch(i){
default:
i+=2;
case 1:
i+=1;
case 4:
i+=8;
case 2:
i+=4;
}
System.out.println("i="+i);
}
}

 结果是15,14。代码会先执行default,但是没有break,所以会顺序执行完全部代码,第二个数同理,从case 1执行完到结束。

优缺点

if 分支语句 和 switch 语句 都是用来实现条件逻辑控制的结构,但它们有各自的特点、优势和局限性。下面是两者的对比优缺点:

if 分支语句

优点:
1. 灵活性高:if语句可以处理任意布尔表达式,支持复杂的条件逻辑,包括区间判断和逻辑组合。
2. 适应性强:适用于多种条件判断场景,特别是当条件判断不是基于几个离散值时,if语句能够更好地适应。
3. 嵌套使用:可以通过嵌套使用形成多层逻辑判断,实现复杂的决策树结构。

缺点:
1. 可读性差:当条件分支增多时,if语句嵌套可能会导致代码结构混乱,难以阅读和维护。
2. 性能考量:在分支众多且条件判断复杂时,可能不如switch语句高效,因为每次条件判断都需要计算和比较。

 switch 语句

优点:
1. 结构清晰:当处理多个基于同一变量的离散值判断时,switch语句能够提供清晰、易于理解的结构。
2. 执行效率高:对于大量分支的情况,尤其是基于常量值的判断,switch语句可能经过编译器优化,生成更高效的代码。
3. 代码精简:相较于if语句的多重嵌套,switch语句通过case直接对应不同的处理逻辑,使得代码更加简洁。

缺点:
1. 限制条件:switch表达式只能处理有限的几个常量值或枚举类型,不支持范围判断或复杂的布尔逻辑。
2. 默认支持:仅有一个default分支来处理所有未匹配的情况,不适用于需要基于区间或复合条件判断的场景。

总结

- 选择依据:如果条件判断基于几个明确的离散值,且逻辑较为简单,switch语句是更好的选择,因为它更高效且易于阅读。而面对复杂的条件逻辑、区间判断或需要灵活的条件组合时,if语句提供了必要的灵活性。
- 性能考虑:在分支较少或逻辑复杂时,if语句的性能差异可能不明显;但当分支增多,特别是处理等值判断时,switch语句通常具有更好的性能表现。
- 编码实践:根据具体情况权衡,选择最适合当前需求的结构。在实际编程中,合理利用这两种结构,可以让代码既高效又易于维护。

循环结构

* 跳转控制语句(break)
  * 跳出循环,结束循环
* 跳转控制语句(continue)
  * 跳过本次循环,继续下次循环

for循环

for (初始化语句;条件判断语句;条件控制语句) {
	循环体语句;
}
  • 格式解释:

    • 初始化语句: 用于表示循环开启时的起始状态,简单说就是循环开始的时候什么样

    • 条件判断语句:用于表示循环反复执行的条件,简单说就是判断循环是否能一直执行下去

    • 循环体语句: 用于表示循环反复执行的内容,简单说就是循环反复执行的事情

    • 条件控制语句:用于表示循环执行中每次变化的内容,简单说就是控制循环是否能执行下去

  • 执行流程:

    ①执行初始化语句

    ②执行条件判断语句,看其结果是true还是false

    如果是false,循环结束

    如果是true,继续执行

    ③执行循环体语句

    ④执行条件控制语句

    ⑤回到②继续

 

class Demo{
public static void main(String[] args){
int x = 1;
for(show('a'); show('b') && x<3; show('c')){
show('d'); 
x++;
}
}
public static boolean show(char ch){
System.out.print(ch);
return true;
}
}

 结果abdcbdcb 。

解析

1. 初始化:`show('a')`
   - 打印 `a`

2. 条件判断:`show('b') && x < 3`
   - `show('b')` 打印 `b` 并返回 `true`
   - `x < 3` 判断为 `true`,因为此时 `x` 为 1
   - 条件为真,进入循环体

3. 循环体:`show('d'); x++;`
   - `show('d')` 打印 `d`
   - `x++`,此时 `x` 变为 2

4. 更新部分:`show('c')`
   - `show('c')` 打印 `c`

现在循环重复:

1. 条件判断:`show('b') && x < 3`
   - `show('b')` 打印 `b` 并返回 `true`
   - `x < 3` 判断为 `true`,因为此时 `x` 为 2
   - 条件为真,进入循环体

2. 循环体:`show('d'); x++;`
   - `show('d')` 打印 `d`
   - `x++`,此时 `x` 变为 3

3. 更新部分:`show('c')`
   - `show('c')` 打印 `c`

再次检查条件:

1. 条件判断:`show('b') && x < 3`
   - `show('b')` 打印 `b` 并返回 `true`
   - `x < 3` 判断为 `false`,因为此时 `x` 为 3
   - 条件为假,循环终止

while循环

初始化语句;
while (条件判断语句) {
	循环体语句;
    条件控制语句;
}

while循环执行流程:

①执行初始化语句

②执行条件判断语句,看其结果是true还是false

​             如果是false,循环结束

​             如果是true,继续执行

③执行循环体语句

④执行条件控制语句

⑤回到②继续

dowhile循环

初始化语句;
do {
	循环体语句;
	条件控制语句;
}while(条件判断语句);

 

  • 执行流程:

    ① 执行初始化语句

    ② 执行循环体语句

    ③ 执行条件控制语句

    ④ 执行条件判断语句,看其结果是true还是false

    如果是false,循环结束

    如果是true,继续执行

    ⑤ 回到②继续

三种循环区别

  • 三种循环的区别

    • for循环和while循环先判断条件是否成立,然后决定是否执行循环体(先判断后执行)

    • do...while循环先执行一次循环体,然后判断条件是否成立,是否继续执行循环体(先执行后判断)

  • for循环和while的区别

    • 条件控制语句所控制的自增变量,因为归属for循环的语法结构中,在for循环结束后,就不能再次被访问到了

    • 条件控制语句所控制的自增变量,对于while循环来说不归属其语法结构中,在while循环结束后,该变量还可以继续使用

优缺点

`for`循环和`while`循环都是编程中常用的循环结构,它们各有特点和适用场景,下面是它们的一些对比和优缺点:

### for循环

优点:
1. 结构紧凑:`for`循环通常用于已知迭代次数的情况,它的语法结构将初始化、条件检查、迭代更新集中在一行,使得循环结构看起来更为简洁。
2. 易于理解:特别是在处理数组或集合遍历时,`for`循环(特别是增强型`for`循环,如Java中的`for-each`循环)能够清晰地表达遍历意图,提高代码的可读性。

缺点:
1. 灵活性较低:相比`while`循环,`for`循环的结构较为固定,对于一些复杂的循环条件或非线性的迭代过程,可能不如`while`循环灵活。
2. 限制较多:如果迭代逻辑复杂,需要多次更改循环控制变量,`for`循环的自动更新部分可能不够直观或适用。

while循环

优点:
1. 高度灵活:`while`循环提供最大的灵活性,几乎可以用来实现任何类型的循环逻辑,特别适合于循环条件或迭代步骤不那么规律的情况。
2. 条件控制自由:可以在循环体内部任意位置改变控制循环的条件变量,使得循环控制逻辑更加灵活多变。

缺点:
1. 可读性较差:特别是在循环控制复杂时,`while`循环的条件和迭代更新分散在循环体内外,可能使得代码较难理解。
2. 易出错:由于循环控制的自由度高,如果循环条件或迭代更新逻辑设置不当,容易出现无限循环的错误。

总结

选择`for`循环还是`while`循环,通常取决于具体的编程需求:
- 当循环次数在循环开始时就可以确定,或者循环逻辑相对简单且迭代次数与控制变量的更新直接相关时,`for`循环更为合适。
- 对于循环条件不明确、迭代逻辑复杂,或需要在循环过程中动态改变循环条件的情况,`while`循环提供了更大的灵活性。

 

  • 34
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值