Java基础概念和语法
变量,数据类型,标识符,关键字,常量,注释,进制转换,运算符,+用法,分支语句,循环语句,跳转控制语句,数组基础
数据类型
|整数类型:byte、short、int、long
|数值型-||
| |浮点型:float、double
|基本数据类型-|字符型:char
| |
| |布尔型:boolean
数据类型-|
|
| |类:class
|引用数据类型-|接口:interface
(所有非基本数据类型都是引用数据类型)|数组类型
|枚举类型
|字符串类型
|注解类型
|等等
基本数据类型
数值类型:
byte short int long 整型
float double 小数
对于不同类型的数据类型,保存数据的长度范围不一样
为什么需要用不同类型,如果使用Python的方式,所有整数都在int中,对于python是做科学计算,对于计算结果得到后,整个代码结束
对于Java语言来说,通常用于编写应用程序,而应用程序需要长时间运行,并且对于内存会做大量的管理
字节占用:
byte(1字节) short(2字节) int (4字节) long(8字节)
float(4字节) double(8字节)
字符类型:
char可以存数字
char赋值
char a=‘a’; //任意单个字符,加单引号。
char a=‘中’;//任意单个中文字,加单引号。
char a=111;//整数。0~65535。十进制、八进制、十六进制均可。输出字符编码表中对应的字符。
注:只能放单个字符。
注意:
用单引号’ '标识,只能放单个字符。
char+char,char+int——类型均提升为int,附值char变量后,输出字符编码表中对应的字符。
为什么char类型的变量可以赋值为整型数字?
char在java中是unicode编码
Java中对char型数据,在内存中存的就是整数,对应一张ASCII码表 ,比如说字符知 ‘A’ 对应的是65
字符 ‘a’ 对应的是97 ,道所以char c1 = ‘A’ ; 等效于 char c1 = 65 ;
正是因为这样,所以字符型数据既可以作为一个字符使用,也可以作为一个整数使用,所以char型数据可以和int型数据进行运算!
比如 ‘A’ + 1 的结果如果用char型变量接收就是 ‘B’ , 用int型变量接收就是66
char c = ‘A’+1; 最后c为’B’
int i = ‘A’ + 1 ; 最后i为 66
虽然char型是以整数存储,但是和int型还是有一定区别的,表现在取值范围上,
char型 占2个字节 无符号 范围是0~65535
所以char c = 65536 就会报错了,专因为越界了
布尔类型
boolean 对应值为 true false
注意:
①对于浮点类型数据,默认类型为double
②对于float类型数据的值可以在末尾使用 F或 f进行标记
③对于double类型数据的值可以在末尾使用 d或D 进行标记
④对于整数数值Java中默认为int类型
⑤对于Long类型数据其值要求在末尾添加 L或者l进行标记
类型转换
数据类型转换必须满足如下规则:
-
- 不能对boolean类型进行类型转换。
-
- 不能把对象类型转换成不相关类的对象。
-
- 在把容量大的类型转换为容量小的类型时必须使用强制类型转换。
-
- 转换过程中可能导致溢出或损失精度
自动类型转换:精度小的自动转换精度大的
byte-short—int—long—float—double
char—int—long—float—double
整数运算:
如果两个操作数有一个为long,则结果也为long;
没有long时,结果为int。即使操作数全为short、byte,结果也是int。
浮点运算:
如果两个操作数有一个为double,则结果为double;
只有两个操作数都是float,则结果才为float。
注意:int 与 float 运算,结果为 float。
强制类型转换
转换的类型 变量名 = (转换的类型)变量
注意:从高精度向低精度转换时会丢失部分信息导致数据错误
向上类型转换:
向上类型转换时不会发生精度丢失,并且不需要强制类型转换
强制类型转换
局限性:对于基本数据类型,其内部直接可以通过强制类型转换,除了boolean型
对于引用数据类型,制转换主要发生在父类和子类之间,或者在实现接口的类之间。这种强制转换需要满足继承或接口实现的关系,否则编译时会报错。
“+”在数值中的转换
public class DemoVariable3 {
public static void main(String[] args) {
// + 数值计算过程中的表现
// ① 对于byte类型数据相加 那么会先将其转成 int类型,再做加法运算
byte byteVariable1 = 10;
byte byteVariable2 = 4;
int intVariable = byteVariable1 + byteVariable2;
System.out.println(intVariable);
byte resVariable = (byte)(byteVariable1 + byteVariable2); // 强制类型转换
System.out.println(resVariable);
}
}
拓展:
SQL语言中对数据可以进行排序操作,通常情况下对于数值进行排序,但是有时也会对字符串进行做排序
那么对于字符串进行排序的规则?
字典序:
如果是字符串,将对应位置的字符取出,再找到对应ASC码表中位置的int值,再按位置比较其大小
如果第一个位置相同,那么会再比较第二个位置,直到其能比较出来前后顺序
"abc" => 'a' | "abc" => 'a' 比较第二个位置数据 => 'b'
"bc" => 'b' | "ac" => 'a' => 'c
引用数据类型
引用数据类型非常多,大致包括:类、 接口类型、 数组类型、 枚举类型、 注解类型、 字符串型
例如,String类型就是引用类型,还有Double,Byte,Long,Float,Char,Boolean,Short(注意这里和基本类型相比首字母是大写)
简单来说,所有的非基本数据类型都是引用数据类型
所有引用数据类型初始值为null
引用数据类型意思为:其保存的数据为一个内存地址的引用信息
区别
1.储存位置
java中的基本数据类型一定存储在栈中的,这句话是错的!
(1)在方法中声明的变量
该变量是局部变量,每当程序调用方法时,系统都会为该方法建立一个方法栈,其所在方法中声明的变量就放在方法栈中,当方法结束系统会释放方法栈,其对应在该方法中声明的变量随着栈的销毁而结束,这就局部变量只能在方法中有效的原因
在方法中声明的变量可以是基本类型的变量,也可以是引用类型的变量。
- 当声明是基本类型的变量的时,其变量名及值(变量名及值是两个概念)是放在JAVA虚拟机栈中
- 当声明的是引用变量时,所声明的变量(该变量实际上是在方法中存储的是内存地址值)是放在JAVA虚拟机的栈中,该变量所指向的对象是放在堆类存中的。
(2)在类中声明的变量
在类中声明的变量是成员变量,也叫全局变量,放在堆中的(因为全局变量不会随着某个方法执行结束而销毁)。
同样在类中声明的变量即可是基本类型的变量 也可是引用类型的变量
- 当声明的是基本类型的变量其变量名及其值放在堆内存中的
- 引用类型时,其声明的变量仍然会存储一个内存地址值,该内存地址值指向所引用的对象。引用变量名和对应的对象仍然存储在相应的堆中
2. 传递方式
基本变量类型:在方法中定义的非全局基本数据类型变量,调用方法时作为参数是按数值传递的
//基本数据类型作为方法参数被调用
public class Main{
public static void main(String[] args){
int msg = 100;
System.out.println("调用方法前msg的值:\n"+ msg); //100
fun(msg);
System.out.println("调用方法后msg的值:\n"+ msg); //100
}
public static void fun(int temp){
temp = 0;
}
}
引用变量类型:引用数据类型变量,调用方法时作为参数是按引用传递的
//引用数据类型作为方法参数被调用
class Book{
String name;
double price;
public Book(String name,double price){
this.name = name;
this.price = price;
}
public void getInfo(){
System.out.println("图书名称:"+ name + ",价格:" + price);
}
public void setPrice(double price){
this.price = price;
}
}
public class Main{
public static void main(String[] args){
Book book = new Book("Java开发指南",66.6);
book.getInfo(); //图书名称:Java开发指南,价格:66.6
fun(book);
book.getInfo(); //图书名称:Java开发指南,价格:99.9
}
public static void fun(Book temp){
temp.setPrice(99.9);
}
}
引用数据类型是基本数据类型的包装类
3.补充知识点
- 一切的引用数据类型都可以使用Objec进行接收,具体可参考
public class Test {
public static void main(String[] args) {
int[] list1 = {1, 2, 3};
//因为数组也是引用,此处可以接收这里的数组应用list1
Object list2 = list1;
//但是这里输出时,就需要判断下是否是整型数组,然后再进行输出操作
if (list2 instanceof int[]){
//执行向下转型操作
int[] list3 = (int[]) list2;
for (int i : list3) {
System.out.println(i);
}
}
}
}
标识符
标识符概述
就是给类,接口,方法,变量等起名字时使用的字符序列
标识符的组成要求
1.大小写字符
2.数字字符
3.$和_
注意事项:
1.不能以数字开头
2.不能时Java中的关键字
3.区分大小写
常见的命名规则
包: 一个单词对应一个层级,一般情况下不会使用多个单词作为一个层级 层级之间使用.隔开,对应每个层级实际上是一个目录 包名称一般为小写 包只能在source标记的目录下创建
类:在.java文件内部使用class修饰的,称为类名,类名一般和文件名称一致 一个单词:首字母大写 多个单词:每个单词的首字母大写相连
方法和变量:在类中定义的函数或者用于保存数值的变量 一个单词:所有都小写 多个单词:第一个单词都小写,其他单词首字母大写相连
常量:用于保存一个不变的值 一个单词:所有单词都大写 多个单词:每个单词大写,并且多个单词间使用_相连
注释
Java中注释分类格式
单行注释
格式: //注释文字
多行注释
格式: /* 注释文字 */
文档注释
格式:/** 注释文字 */
HelloWord.java解释
代码:
package com.test.demo1; // 用于标记当前.java文件所在的包路径 包路径开始的位置为 从source标记的目录下开始
// 解释HelloWorld程序
// public修饰的当前类的权限 class表示类的标记信息 HelloWorld类名称 编译后可以生成类名称.class文件
public class HelloWorld {
// public 修饰的当前函数的权限 static 用于修饰当前函数是一个静态 void 表示为没有返回值 main函数名称 (String[] args)表示函数的参数以及参数名称
// {}表示当前函数的代码块区域 或者是称为作用域
public static void main(String[] args) {
// 对System类中调用println函数并传入 hello Java 的字符串值 进行打印
System.out.println("hello java...");
}
// 编写代码时,idea提供了快捷方式 main / sout
}
关键字
关键字概述
被Java语言赋予特定含义的单词
关键字特点
组成关键字的字母全部小写
关键字注意事项
goto和const作为保留字存在,目前并不使用
类似IDEA这样的集成工具,针对关键字有特殊的颜色标记,非常直观
类别 | 关键字 | 说明 |
---|---|---|
访问控制 | private | 私有的 |
访问控制 | protected | 受保护的 |
访问控制 | public | 公共的 |
访问控制 | default | 默认 |
类、方法和变量修饰符 | abstract | 声明抽象 |
类、方法和变量修饰符 | class | 类 |
类、方法和变量修饰符 | extends | 扩充、继承 |
类、方法和变量修饰符 | final | 最终值、不可改变的 |
类、方法和变量修饰符 | implements | 实现(接口) |
类、方法和变量修饰符 | interface | 接口 |
类、方法和变量修饰符 | native | 本地、原生方法(非Java实现) |
类、方法和变量修饰符 | new | 创建 |
类、方法和变量修饰符 | static | 静态 |
类、方法和变量修饰符 | strictfp | 严格浮点、精准浮点 |
类、方法和变量修饰符 | synchronized | 线程、同步 |
类、方法和变量修饰符 | transient | 短暂 |
类、方法和变量修饰符 | volatile | 易失 |
程序控制语句 | break | 跳出循环 |
程序控制语句 | case | 定义一个值以供switch选择 |
程序控制语句 | continue | 继续 |
程序控制语句 | do | 运行 |
程序控制语句 | else | 否则 |
程序控制语句 | for | 循环 |
程序控制语句 | if | 如果 |
程序控制语句 | instanceof | 实例 |
程序控制语句 | return | 返回 |
程序控制语句 | switch | 根据值选择 |
程序控制语句 | while | 循环 |
错误处理 | assert | 断言表达式是否为真 |
错误处理 | catch | 捕捉异常 |
错误处理 | finally | 有没有异常都执行 |
错误处理 | throw | 抛出一个异常对象 |
错误处理 | throws | 声明一个异常可能被抛出 |
错误处理 | try | 捕获异常 |
包相关 | import | 引入 |
包相关 | package | 包 |
基本类型 | boolean | 布尔型 |
byte | 字节型 | |
char | 字符型 | |
double | 双精度浮点 | |
float | 单精度浮点 | |
int | 整型 | |
long | 长整型 | |
short | 短整型 | |
变量引用 | super | 父类、超类 |
this | 本类 | |
void | 无返回值 | |
保留关键字 | goto | 是关键字,但不能使用 |
const | 是关键字,但不能使用 |
**注意:**Java 的 null 不是关键字,类似于 true 和 false,它是一个字面常量,不允许作为标识符使用。
常量
常量的概述
对于储存的数据并不发生改变的量
常量类型
字面值常量
字符串常量
用双引号括起来的内容
public static void main(String[] args){
String STR = "This is String"; //字符串常量
}
整数常量
所有整数
public static void main(String[] args){
int NUM = 10; //整数常量
}
小数常量
所有小数
public static void main(String[] args){
float FloatNum = 3.14F; //小数常量(此处F是因为默认为双精度以此来标识此处为单精度)
}
字符常量
用单引号括起来的内容
public static void main(String[] args){
char CH = 'a'; //字符常量
}
布尔常量
较为特有,只有true和false
public static void main(String[] args){
boolean BOOL = true; //布尔常量
}
空常量
public static void main(String[] args){
String NULL = null; // 空常量 表示字符串中的常量值为空} //没有空常量的标识符这里用String
自定义常量(面向对象部分讲)
进制转换
进制:表示某一位置上的数运算时是逢X进一位。二进制就是逢二进一,八进制是逢八进一,十进制是逢十进一,十六进制是逢十六进一。
二进制:0b110 => 0*2^0 + 1*2^1 +1*2^2 => 6
八进制: 07 => 7
十进制: 2345 => 5*10^0 + 4*10^1 + 3*10^2 + 2*10^3
十六进制: (0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f) 0x12 => 2*16^0 + 1*16^1 => 18
其他进制转换成十进制:
系数:就是每一位上的数据。
基数:X进制,基数就是X。
权:在右边,从0开始编号,对应位上的编号即为该位的权。
结果:把系数*基数的权次幂相加即可。
十进制到其他进制:
把52分别表示成二进制: 对52进行除以2进行不断取余,得到的除得的结果加上最后的一个余数进行反转就可以得到对应二进制的结果
把52分别表示成八进制: 同二进制一样
把52分别表示成十六进制: 同二进制一样
十进制和二进制的快速转换
1 1 1 1 1 1 1
64 32 16 8 4 2 1
二进制: 1000100 64 + 4 => 68
二进制和八进制之间的转换
方式1:以十进制作为桥梁 先将二进制转换成 十进制,再由十进制转换成 八进制
1000100 =十进制> 68 =八进制> 104
方式2:将二进制数据三个分为一组 分别计算组内的十进制数值 再将计算后的结果拼接到一起 分组时如果不满足三个,那么对其进行左边补0
1 000 100 => 001 000 100 => 104
二进制和十六进制之间的转换
方式1:以十进制作为桥梁 先将二进制转换成 十进制,再由十进制转换成 十六进制
1000100 =十进制> 68 =十六进制> 44
方式2:将二进制数据4个作为一组 ,分别计算组内数据的十进制,再将计算结果拼接到一起,如果组内数据不满足4个左边补0
1 000 100 => 0100 0100 => 44
对于数据在计算过程中都是以二进制的机器码进行计算的
以正整数为例:
7+1 => 000111 + 000001 => 001000
以负数为例:
对于负数要想表示成二进制的形式,所以需要使用 原码 反码 补码
原码: 就是二进制定点表示法,即最高位为符号位,“0”表示正,“1”表示负,其余位表示数值的大小
反码: 正数的反码与其原码相同;负数的反码是对其原码逐位取反,但符号位除外。
补码: 正数的补码与其原码相同;负数的补码是在其反码的末位加1。
-7+1 =>
原码:
符号位 数值位
-7的 1 0000111
1的 0 0000001
反码:
符号位 数值位
-7的 1 1111000
1的 0 0000001
补码:
符号位 数值位
-7的 1 1111001
1的 0 0000001
相加的结果:
补码:
符号位 数值位
1 1111010
由于符号位为1 那么补码和反码不同 原先反码=> 补码 要求加1 所以 补码 => 反码 要求 -1
反码:
符号位 数值位
1 1111001
由于符号位为1 反码转源码是将数值位中的数据进行取反
原码:
符号位 数值位
1 0000110
由二进制转成10进制
-6
变量
变量概述
程序执行的过程中,在某个范围内其值可以发生改变的量
Java是一个静态类型语言(编写代码时需要指定当前变量中的数据类型,并且定义后不能改变类型)
而Python是动态类型语言(在代码执行过程中,根据数据的类型来进行推断)
变量定义格式
变量类型 变量名 = 值;
变量类型
-
**局部变量(Local Variables):**局部变量是在方法、构造函数或块内部声明的变量,它们在声明的方法、构造函数或块执行结束后被销毁,局部变量在声明时需要初始化,否则会导致编译错误。
public void exampleMethod() { int localVar = 10; // 局部变量 // ... }
-
**实例变量(Instance Variables):**实例变量是在类中声明,但在方法、构造函数或块之外,它们属于类的实例,每个类的实例都有自己的副本,如果不明确初始化,实例变量会被赋予默认值(数值类型为0,boolean类型为false,对象引用类型为null)。
public class ExampleClass { int instanceVar; // 实例变量 }
-
**静态变量或类变量(Class Variables):**类变量是在类中用 static 关键字声明的变量,它们属于类而不是实例,所有该类的实例共享同一个类变量的值,类变量在类加载时被初始化,而且只初始化一次。
public class ExampleClass { static int classVar; // 类变量 }
-
**参数变量(Parameters):**参数是方法或构造函数声明中的变量,用于接收调用该方法或构造函数时传递的值,参数变量的作用域只限于方法内部。
public void exampleMethod(int parameterVar) { // 参数变量 // ... }
运算符
Java中的数都是有符号的 当计算机运算时,都是以补码的方式来运算的
算术运算符
操作符 | 描述 | 例子 |
---|---|---|
+ | 加法 - 相加运算符两侧的值 | A + B 等于 30 |
- | 减法 - 左操作数减去右操作数 | A – B 等于 -10 |
* | 乘法 - 相乘操作符两侧的值 | A * B等于200 |
/ | 除法 - 左操作数除以右操作数 | B / A等于2 |
% | 取余 - 左操作数除以右操作数的余数 | B%A等于0 |
++ | 自增: 操作数的值增加1 | B++ 或 ++B 等于 21(区别详见下文) |
– | 自减: 操作数的值减少1 | B-- 或 --B 等于 19(区别详见下文) |
public class Test {
public static void main(String[] args) {
int a = 10;
int b = 20;
int c = 25;
int d = 25;
System.out.println("a + b = " + (a + b) );
System.out.println("a - b = " + (a - b) );
System.out.println("a * b = " + (a * b) );
System.out.println("b / a = " + (b / a) );
System.out.println("b % a = " + (b % a) );
System.out.println("c % a = " + (c % a) );
System.out.println("a++ = " + (a++) );
System.out.println("a-- = " + (a--) );
// 查看 d++ 与 ++d 的不同
System.out.println("d++ = " + (d++) );
System.out.println("++d = " + (++d) );
}
}
结果:
a + b = 30
a - b = -10
a * b = 200
b / a = 2
b % a = 0
c % a = 5
a++ = 10
a-- = 11
d++ = 25
++d = 27
注意:前缀自增自减法(++a,–a): 先进行自增或者自减运算,再进行表达式运算。
后缀自增自减法(a++,a–): 先进行表达式运算,再进行自增或者自减运算
public static void main(String[] args) {
int a = 0;
System.out.println((a++)==0); //先取值判断在加
System.out.println(a++);
System.out.println(a);
System.out.println(++a); //先加在取值
System.out.println(a);
}
结果:
true
1
2
3
3
比较运算符
== | 检查如果两个操作数的值是否相等,如果相等则条件为真。 | (A == B)为假。 |
---|---|---|
!= | 检查如果两个操作数的值是否相等,如果值不相等则条件为真。 | (A != B) 为真。 |
> | 检查左操作数的值是否大于右操作数的值,如果是那么条件为真。 | (A> B)为假。 |
< | 检查左操作数的值是否小于右操作数的值,如果是那么条件为真。 | (A <B)为真。 |
>= | 检查左操作数的值是否大于或等于右操作数的值,如果是那么条件为真。 | (A> = B)为假。 |
<= | 检查左操作数的值是否小于或等于右操作数的值,如果是那么条件为真。 | (A <= B)为真 |
instanceof | 检查是否是类 的对象 | (“hello” instanceof String)为真 |
注意:"=="比较的是地址
public class Test {
public static void main(String[] args) {
String a = "abc";
String b = "abc";
String c = "112";
String d = "112";
String e = new String("aa");
String f = new String("aa");
System.out.println(a==b );
System.out.println(c==d);
System.out.println(e==f);
System.out.println(e.equals(f));
}
}
结果:
true
true
false
true
位运算符
操作符 | 描述 | 例子 |
---|---|---|
& | 如果相对应位都是1,则结果为1,否则为0 | (A&B),得到12,即0000 1100 |
| | 如果相对应位都是 0,则结果为 0,否则为 1 | (A | B)得到61,即 0011 1101 |
^ | 如果相对应位值相同,则结果为0,否则为1 | (A ^ B)得到49,即 0011 0001 |
〜 | 按位取反运算符翻转操作数的每一位,即0变成1,1变成0。 | (〜A)得到-61,即1100 0011 |
<< | 按位左移运算符。左操作数按位左移右操作数指定的位数。 | A << 2得到240,即 1111 0000 |
>> | 按位右移运算符。左操作数按位右移右操作数指定的位数。 | A >> 2得到15即 1111 |
>>> | 按位右移补零操作符。左操作数的值按右操作数指定的位数右移,移动得到的空位以零填充。 | A>>>2得到15 |
位运算符的细节 | |
---|---|
<< | 空位补0,被移除的高位丢弃。 |
>> | 被移位的二进制最高位是0,右移后,空缺位补0;最高位是1,最高位补1。 |
>>> | 被移位二进制最高位无论是0或者是1,空缺位都用0补。 |
& | 任何二进制位和0进行&运算,结果是0;和1进行&运算结果是原值。 |
| | 任何二进制位和0进行 | 运算,结果是原值;和1进行 | 运算结果是1。 |
^ | 任何相同二进制位进行 ^ 运算,结果是0;不相同二进制位 ^ 运算结果是1。 |
注意: 左移 左移N位 相当于对于当前值*2^N
逻辑运算符
操作符 | 描述 | 例子 |
---|---|---|
&& | 称为逻辑与运算符。当且仅当两个操作数都为真,条件才为真。 | (A && B)为假。 |
| | | 称为逻辑或操作符。如果任何两个操作数任何一个为真,条件为真。 | (A | | B)为真。 |
! | 称为逻辑非运算符。用来反转操作数的逻辑状态。如果条件为true,则逻辑非运算符将得到false。 | !(A && B)为真。 |
| | 或 两边相同为true | |
^ | 异或 两边相同为false |
注意:
逻辑运算符用于连接布尔型表达式,在Java中不可以写成3<x<6,应该写成x>3 & x<6 。
“&”和“&&”的区别:
单&时,左边无论真假,右边都进行运算;
双&时,如果左边为真,右边参与运算,如果左边为假,那 么右边不参与运算。
“|”和“||”的区别同理,双或时,左边为真,右边不参与运算。
public class Test2 {
public static void main(String[] args) {
short s1= 1;
s1=s1+1; ---------->此处错误因为s1+1变成int型,应该为int s2 =s1+1; 不能重新定义s1为int即不能重新定义同一变量
s1+=1;
System.out.println(s1);
}
}
三目运算符
格式
(关系表达式)?表达式1:表达式2;
如果条件为true,运算后的结果是表达式1;
如果条件为false,运算后的结果是表达式2;
示例:
获取两个数中大数。
int x=3,y=4,z;
z = (x>y)?x:y;//z变量存储的就是两个数的大数。
**注意:**三目运算符必须要有个返回值
不能使用(3>4)?System.out.println(3):System.out.println(4);
short A = 5;
int B = 4;
int C = (A > B) ? A : B;
System.out.println(C);
注意:此处C 必须位int 因为short类型比int类型范围小
+ 用法
1.对于数值来说,那就是加法
2.对于字符char类型来说,在计算之前,char会被提升成为int,然后再计算
3.对于字符串String(首字母大写,并不是关键字)来说,加号代表字符串连接操作,任何数据类型和字符串进行连接的时候,结果都会变成字符串
package com.xiaoye.operator;
public class Demo02 {
public static void main(String[] args) {
int a = 10;
int b = 20;
// 字符串连接符 + String
// 只要运算中出现了字符串,则会相当于字符串拼接起来
System.out.println(" "+ a + b); // 相当于 " "+"10"+"20"
System.out.println(a + b + ""); // 相当于 30+""
System.out.println(""+ a + b); // 相当于 ""+"10"+"20"
System.out.println("" + a * b); // 相当于 ""+ "10×20"
}
}
分支语句
if语句
三种结构
if(判断语句){
执行代码块 按照顺序结构执行
执行代码块 按照顺序结构执行
执行代码块 按照顺序结构执行
}
if(判断语句){
执行代码块 按照顺序结构执行
执行代码块 按照顺序结构执行
执行代码块 按照顺序结构执行
}else{
判断语句为false执行代码块
判断语句为false执行代码块
判断语句为false执行代码块
}
if(判断语句1){
执行代码块 按照顺序结构执行
执行代码块 按照顺序结构执行
执行代码块 按照顺序结构执行
}else if(判断语句2){
判断语句2为true执行代码块
判断语句2为true执行代码块
判断语句2为true执行代码块
}else { // 可选项
上述条件都不满足 执行代码
上述条件都不满足 执行代码
}
注意:
1.关系表达式无论简单还是复杂,结果必须是boolean类型
2.对于IF语句如果不加{} 默认下一行为if语句中的执行语句,其他行数据不算在内 推荐使用{}
对于文件多个if要优化代码
优化代码 专业词汇: 代码重构
switch语句
switch(表达式) {
case 值1:
语句体1;
break;
case 值2:
语句体2;
break;
…
default:
语句体n+1;
break;
switch 穿透 :在case语句中没有设置break 之后依照顺序继续执行下一个case中的语句
对于default语句一般情况下放在末尾,但是位置不影响其执行结果
break:表示停止执行当前的switch语句
default: 所有case都没有匹配上则运行该部分代码
循环语句
for循环(for-each)
For循环语句:
fori:
for(初始化语句;判断语句;控制语句){
循环体语句;
循环体语句;
}
初始化语句: 定义一个变量 该变量可以记录循环执行的次数
判断语句: 对当前是否要继续执行进行判断
控制语句: 对判断语句中的变量进行做限制
循环体语句: 每次循环要执行的代码块
注意:初始化语句定义在for循环之外,可以最终获取到其变量的结果 for循环内部定义的变量只能在其内部使用
顺序:
for循环执行过程
① 执行初始化语句
② 执行判断语句,同时如果为false那么退出循环,为true那么执行{}中的循环体语句
③ 执行控制语句
④ 之后再去执行判断语句,同时如果为false那么退出循环,为true那么执行{}中的循环体语句
⑤ 循环 ② ③ ④
对于初始化语句和控制语句都可以不在for()中
for-each语句:可用于遍历数组
Java 增强 for 循环语法格式如下:
for(声明语句 : 表达式) {
//代码句子
}
声明语句:
声明新的局部变量,该变量的类型必须和数组元素的类型匹配。其作用域限定在循环语句块,其值与此时数组元素的值相等。
表达式:
表达式是要访问的数组名,或者是返回值为数组的方法。
while循环
While循环格式:
初始化语句;
while(判断条件){
循环代码体;
控制语句;
}
特殊写法 空while运行,让程序不终止
while (true) {
}
do…while
do.. while()
格式:
初始化变量;
do {
循环体;
控制语句;
}while(判断语句)
和while循环的区别:
do while是先执行{}中的代码块,之后再执行判断语句
while 是先执行判断语句再执行{}中的代码块
跳转控制语句
break
continue
return
public static void main(String[] args) {
/*
Continue 和 while 代码:
*/
int i = 0;
while (i <= 10) {
i += 1;
if (i == 3) {
// 当执行过程中遇到 continue 那么会直接执行 while中的 判断语句
continue;
}
System.out.println("i:" + i);
}
System.out.println("***********************************");
i = 0;
while (i <= 10) {
i += 1;
if (i == 3) {
// 一旦遇到break操作,那么会终止 while 循环
break;
}
System.out.println("i:" + i);
}
}
}
结果:
i:1
i:2
i:4
i:5
i:6
i:7
i:8
i:9
i:10
i:11
***********************************
i:1
i:2
数组
声明数组变量
首先必须声明数组变量,才能在程序中使用数组。
dataType[] arrayRefVar; //首选的方法
int intArr[]; //来自于c语言 可用
实例:
double[] myList;
创建数组
// 动态赋值:定义数组时先给定数组的长度
数组变量的声明,和创建数组可以用一条语句完成:
dataType[] arrayRefVar = new dataType[arraySize];
还可以使用如下的方式创建数组:
// 静态赋值: 定义数组时直接给定具体的值
dataType[] arrayRefVar = {value0, value1, ..., valuek};
数据类型[] 变量名 = new 数据类型[]{数组元素值1、数组元素值2、数组元素值3...}
**注意:**数组的元素是通过索引访问的。数组索引从 0 开始,所以索引值从 0 到 arrayRefVar.length-1
当使用动态赋值时,一开始数组的数据大欧式当前数据类型的默认值
实例:
double[] myList = new double[size];
myList[0] = 5.6; //赋值操作
注意:
Array数据的类型就是 引用数据类型意思为:其保存的数据为一个内存地址的引用信息
对于两个变量保存的内存地址如果一致,那么当其中一个变量对内存地址中的数据进行修改, 也会影响到另外一个变量的结果数据
遍历数组
public static void main(String[] args) {
int[] aArr={45,45,878,545,45,45,45,45,12,14,64,5,165,4156,441,561,4};
// 方式一:for
for (int i = 0; i <aArr.length ; i++) {
System.out.println(aArr[i]);
}
//方式二:for-each
for (int i : aArr) {
System.out.println(i);
}
//方式三:while
int index=0;
while (index<aArr.length){
System.out.println(aArr[index]);
index++;
}
}
二维数组
二维数组定义:
注意 float[][] f[][]= new float[6][];
对于多维数组定义动态需要给第一维数组定义长度
数据类型[][] 变量名 = new 数据类型[m] [n];
float []f[] = new float[6][6];
float[][] f = new float[6][];
遍历:
int num = 1;
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
d2Arr[i][j] = num;
num ++;
}
}
// 遍历取值
// 增强for取值
for (int[] ints : d2Arr) {
for (int elem : ints) {
System.out.println("elem:"+elem);
}
}
数组后面添加数据
Java中的数组是一种固定长度的数据结构,一旦创建后,其长度就无法改变。如果需要在数组中添加新的元素,需要创建一个新的数组,将原数组中的数据复制到新数组中,并添加新元素。
Java中可以使用以下两种方法向数组中添加元素:
**1.**使用Arrays.copyOf()方法创建一个新的数组,将原数组中的元素和新元素一起复制到新数组中,最后返回新数组。例如:
int[] oldArray = {1, 2, 3};
int[] newArray = Arrays.copyOf(oldArray, oldArray.length + 1);
newArray[newArray.length - 1] = 4;
上述代码将原数组{1, 2, 3}复制到新数组中,并向新数组中添加一个元素4,最终得到新数组{1, 2, 3, 4}。
**2.**使用ArrayList类来代替数组,ArrayList是一种动态数组,其大小可以根据需要动态增加。例如:
ArrayList list = new ArrayList<>(Arrays.asList(1, 2, 3));
list.add(4);
上述代码使用ArrayList来存储整型数据,先将数据{1, 2, 3}转换为ArrayList,然后使用add()方法向ArrayList中添加一个新元素4,最终得到ArrayList{1, 2, 3, 4}。
需要注意的是,第一种方法虽然可以在原数组基础上进行修改,但是由于需要复制数组,因此效率可能不如ArrayList。因此,如果需要频繁添加或删除元素,建议使用ArrayList类来代替数组。
静态导入概述及使用
在Java中,静态导入是一种用于导入类中静态成员(静态字段和静态方法)的机制。通过使用静态导入,你可以在代码中直接使用静态成员的名称,而无需使用类名来限定。
静态导入的概述
在Java中,通常我们使用import语句来导入类或包,以便在代码中使用其中的成员。而静态导入是在Java 5及其以上版本引入的新特性,允许我们直接导入类中的静态成员,从而可以在代码中直接使用这些静态成员的名称。
语法格式如下:
javaCopy code
import static packageName.className.staticMember;
其中,packageName
是包的名称,className
是类的名称,staticMember
是静态成员的名称。使用静态导入后,你可以在代码中直接使用staticMember
,而不需要使用className.staticMember
来限定。
静态导入的使用示例
以下是一个使用静态导入的简单示例,假设有一个MathUtil
工具类,其中包含了一些静态方法:
javaCopy code// MathUtil.java
package utils;
public class MathUtil {
public static int add(int a, int b) {
return a + b;
}
public static int subtract(int a, int b) {
return a - b;
}
}
现在,如果你想在另一个类中使用MathUtil
中的静态方法,可以使用静态导入:
javaCopy code// MainClass.java
import static utils.MathUtil.*;
public class MainClass {
public static void main(String[] args) {
int result1 = add(5, 3); // 直接使用静态方法名
int result2 = subtract(8, 4); // 直接使用静态方法名
System.out.println("Result of addition: " + result1);
System.out.println("Result of subtraction: " + result2);
}
}
在这个例子中,通过import static utils.MathUtil.*;
语句,我们可以直接在MainClass
中使用add
和subtract
方法,而无需写出MathUtil.add
和MathUtil.subtract
。
需要注意的是,静态导入可能会导致命名冲突和代码可读性降低,因此在使用时要谨慎选择。通常建议只导入需要使用的特定静态成员,而不是使用通配符*
导入所有静态成员。
可变参数概述及使用
可变参数(Variable Arguments)是Java中的一项特性,它允许方法接受可变数量的参数。在方法声明中,使用省略号(…)来表示可变参数,使得方法可以接受任意个数的参数。
可变参数的概述
在Java中,可变参数主要应用于方法的参数列表中。可变参数的声明方式如下:
javaCopy codepublic returnType methodName(type... parameterName) {
// 方法体
}
其中,type
是参数的类型,parameterName
是参数的名称,而省略号...
表示该参数可以接受任意个数的值,包括零个。
可变参数的使用示例
以下是一个使用可变参数的简单示例,演示了如何定义和使用带有可变参数的方法:
javaCopy codepublic class VarargsExample {
// 方法接受可变数量的整数参数,并计算它们的和
public static int sum(int... numbers) {
int result = 0;
for (int number : numbers) {
result += number;
}
return result;
}
public static void main(String[] args) {
// 调用 sum 方法,传入不定数量的参数
int result1 = sum(1, 2, 3, 4, 5);
int result2 = sum(10, 20, 30);
int result3 = sum();
// 输出计算结果
System.out.println("Result 1: " + result1); // 输出:Result 1: 15
System.out.println("Result 2: " + result2); // 输出:Result 2: 60
System.out.println("Result 3: " + result3); // 输出:Result 3: 0
}
}
在这个示例中,sum
方法的参数列表中使用了可变参数int... numbers
,可以接受任意数量的整数参数。在main
方法中,我们分别调用了sum
方法,并传入不同数量的参数,演示了可变参数的使用。
需要注意的是,可变参数只能作为方法的最后一个参数,而且一个方法只能有一个可变参数。在方法内部,可变参数被视为一个数组,因此可以使用数组的相关操作对其进行处理。