Java基础
Java入门
入门之一:cmd
- 打开cmd
- 常用CMD命令
/*
盘符名称 + 冒号
说明:盘符切换
举例:E:回车,表示切换到E盘
dir
说明:查看当前路径下的内容
cd目录
说明:进入单级目录
举例:cd itheima
cd ..
说明:回到上一级目录
cd 目录1\目录2\...
说明:进入多级目录。
举例:cd itheima\JavaSE
cd \
说明:回退到盘符目录。
cls
说明:清屏。
exit
说明:退出命令提示符窗口。
*/
入门之二:配置环境变量
Java下载和安装
- 下载jdk
通过官方网站(http://www.oracle.com)获取。
注意:针对不同操作系统,下载对应的安装包
- 安装JDK
傻瓜式安装,下一步即可。
建议1:安装路径中不要包括中文和空格;
建议2:所有的开发工具最好安装目录统一。
- JDK的安装目录
bin:该路径下存放了各种工具命令。其中比较重要的有:javac和java。
conf:该路径下存放了相关配置文件。
include:该路径下存放了一些平台特定的头文件。
jmods:该路径下存放了各种模块。
legal:该路径下存放了各模块的授权文档。
lib:该路径下存放了工具的一些补充JAR包。
第一个HelloWorld小案例
写好的java程序 => 通过编译文件(javac HelloWorld.java)=> 运行程序(java HelloWorld)
//文件HelloWorld.java
public class HelloWorld{
public static void main(String[] ags){
System.out.println("HelloWorld!");
}
}
//DOS命令行
//编译文件
//javac是JDK提供的编译工具
//生成HelloWorld.class字节码文件
javac HelloWorld.java
//运行程序
//java也是JDK提供的一个工具。作用就是用来运行代码的。
//运行生成的字节码文件,不加后缀名
java HelloWorld
案例常见问题
- 中英文符号问题:
英文状态下分号“;”
中文状态下分号“;”
单词拼写问题:
System ———— system
环境变量
- 为什么要配置Path环境变量
配置Path环境变量的目的:
我们想要在任意的目录下都可以打开指定的软件。就可以把软件的路径配置到环境变量中。
Java语言发展
Java能干什么
- Java SE
Java语言的(标准版),用于桌面应用的开发,是JavaEE和JavaME两个版本的基础。
- Java ME
Java语言的(小型版),用于嵌入式电子设备或者小型移动设备。
- Java EE
Java 语言的(企业版),用于Web方向的网站开发。在这个领域是当之无愧的No1。
java能做什么?
- 桌面应用开发(各种税务管理软件,IDEA,clion,Pycharm)
- 企业级应用开发(微服务,springcloud)
- 移动应用开发(鸿蒙,android,医疗设备)
- 科学计算(matlab)
- 大数据开发(hadoop)
- 游戏开发(我的世界 MineCraft)
- Java的主要特性:
面向对象、跨平台、安全性、多线程、跨平台、开源、简单易用
JRE和JDK
JDK (Java Development kit) : Java开发工具包
- JVM (Java Virtual Machine) : Java虚拟机,真正运行Java程序的地方
- 核心类库: Java已经写好的东西,我们可以直接用。
- 开发工具: javac、 java.jdb.jhat…
JRE (Java Runtime Environment) : Java的运行环境
- JVM、核心类库、运行工具
JDK包含JRE,JRE包含JVM
Java基础概念
注释
//单行注释
/*
多行注释
*/
/**
文档注释
*/
注释内容不会参与编译和运行,仅仅是对代码的解释说明
不管是单行注释还是多行注释,在书写的时候都不要嵌套
关键字
关键字:被Java赋予了特定涵义的英文单词
关键字的字母 全部小写。
常用的代码编辑器,针对关键字有特殊的颜色标记,非常直观。
- class关键字
public class HelloWorld{
/*
class:用于(创建/定义)一个类
类是java最基本的组成单元
*/
}
字面量
分类
字面量类型 | 说明 | 举例 |
---|---|---|
整数类型 | 不带小数点的数字 | 666,-88 |
小数类型 | 带小数点的数字 | 13.14 |
字符串类型 | 用双引号括起来的内容 | “hello”,“小米” |
字符类型 | 用单引号括起来的,内容只能有一个 | ‘A’,‘0’,‘我’ |
布尔类型 | 布尔值,表示真假 | 只有两个值:true,false |
空类型 | 一个特殊的值,空值 | 值是:null |
扩展点:特殊字符
‘\t’ ‘\r’ ‘\n’ …
‘\t’ 制表符
在打印的时候,把前面字符串的长度补齐到8,或者8的整数倍。最少补1个空格,最多补8个空格。
public class HelloWorld{
public static void main(String[] args){
System.out.println("abc" + "\t" + "def");
}
}
//输出效果:abc def
变量
//变量的定义格式
//数据类型 变量名 = 数据值;
int first = 1;
变量的注意事项
//错误的使用
//只能存一个值
int a= 3,4;
//变量名不允许重复定义
int b=1;
int b=2;
//一条语句可以定义多个变量
int d=100,e=200;
//变量在使用之前一定要进行赋值
int c=1;
int c;//错误,要进行赋值
//变量的作用域范围
boolean = "a";布尔类型的值只有true和false
数据类型
- 基本数据类型
数据类型 | 关键字 | 取值范围 |
---|---|---|
整数 | byte | -128~127 |
short | -32768~32767 | |
int默认 | -2147483648~2147483647(10位数) | |
long | -9223372036854775808~9223372036854775807(19位数) | |
浮点数 | float | -3.401298e-38到3.402823e+38 |
double默认 | -4.9000000e-324 到1.797693e+308 | |
字符 | char | 0-65535 |
布尔 | boolean | true,false |
//byte
byte a=10;
//short
short b=160;
//int
int c=1230;
//long
long d =123456789L;
//float
float e =3.141592383F;
//double
double f = 3.1424512;
//char
char g = "中";
//boolean
boolean h= true;
整数和小数取值范围大小关系:
double>float>long>int>short>byte
long类型变量:需要加入L标识(大小写都可以)
float类型变量:需要加入F标识(大小写都可以)
标识符
标识符:就是给 类,方法,变量 等起的名字。
- 标识符命名规则:
- 由数字、字母、下划线(_)和美元符($)组成
- 不能以数字开头
- 不能是关键字
- 区分大小写
-
小驼峰命名法: 方法、变量
-
规范1:标识符是一个单词的时候,全部小写
范例1: name
-
规范2:标识符由多个单词组成的时候,第一个单词首字母小写,其他单词首字母大写
范例2: firstName
-
-
大驼峰命名法: 类名
-
规范1∶标识符是一个单词的时候,首字母大写
范例1: Student
-
规范2:标识符由多个单词组成的时候,每个单词的首字母大写
范例2:GoodStudent
-
Scanner键盘录入
Java帮我们写好一个类叫Scanner,这个类就可以接收键盘输入的数字。
//第一步:导包Scanner这个类在哪
import java.util.Scanner;
public class testScanner{
public static void main(String[] args){
//第二步:创建对象 -- 表示我要开始用Scanner这个类
//只有sc是变量可以变,其他的不可变
Scanner sc = new Scanner(System.in);
//步骤三:接收数据 -- 真正开始使用
//只有i是变量可以变,其他的不可变
int i = cs.nextInt();
}
}
运算符
算术运算符
符号 | 作用 |
---|---|
+ | 加 |
- | 减 |
* | 乘 |
/ | 除 |
% | 取模、取余 |
//除法
System.out.println(10 / 2);//5
System.out.println(10 / 3);//3
System.out.println(10.0 / 3);//3.3333....
//取余
System.out.println(10 % 2);//0
System.out.println(10 % 3);//1
//1.整数参与计算,结果只能得到整数
//2.小数参与计算,结果有可能是不精确的,如果我们需要精确计算,那么需要用到后面的知识点。
“+”操作的三种情况
数字相加
类型转换的分类
- 隐式转换
取值范围小的数值 => 取值范围大的数值
int a=10;
double b=10.0;
c=a+b;//数据类型为double
byte e=11;
byte f=12;
g=e+f;//数据类型为int
- 取值范围小的,和取值范围大的进行运算,小的会先提升为大的,再进行运算
- byte short char三种类型的数据在运算的时候,都会直接先提升为int,然后再进行运算
- 强制转换
取值范围大的数值 => 取值范围小的数值
//格式:目标数据类型 变量名 = (目标数据类型) 被强转的数据;
byte b1 = 10;
byte b2 = 30;
//byte b3 =(byte)b1 + b2;//错误写法
byte b3 =(byte)(b1 + b2);//正确写法
------
byte b1 = 100;
byte b2 = 30;
byte b3 =(byte)(b1 + b2);//结果就发生错误了。因为要转换的数据过大。
字符串”+“操作
- 当“+”操作中出现字符串时,这个“+”是字符串连接符,而不是算术运算符了。会将前后的数据进行拼接,并产生一个新的字符串。
“123”+123 => 123123
- 连续进行"+"操作时,从左到右逐个执行。
1+99+“年黑马” => 100年黑马
字符相加
当 ”字符+字符“ 或 ”字符+数字“ 时,会把字符通过ASCII码表查询到对应的数字再进行计算。
char a ='a';
int b=10;
int c=a+b;//97+10=107
自增自减运算符
符号 | 作用 | 说明 |
---|---|---|
++ | 加 | 变量的值加1 |
– | 减 | 变量的值减1 |
注意:++和–既可以放在变量的前边,也可以放在变量的后边
int x=10;
//先++
int y=x++;//y=10 x=11 先用后加
//++后
int z=++x;//x=12 y=12 先加后用
//x:12 y:10 x:12
赋值运算符
符号 | 作用 | 说明 |
---|---|---|
= | 赋值 | int a=10,将10赋值给变量a |
+= | 加后赋值 | a+=b,将a+b的值给a |
-= | 减后赋值 | a-=b,将a-b的值给a |
*= | 乘后赋值 | a*=b,将a×b的值给a |
/= | 除后赋值 | a/=b,将a÷b的商给a |
%= | 取余后赋值 | a%=b,将a÷的余数給a |
注意事项:扩展的赋值运算符隐含了强制类型转换
关系运算符
符号 | 说明 |
---|---|
== | a==b,判断a和b的值是否相等,成立为true,不成立为false |
!= | a!=b,判断a和b的值是否不相等,成立为true,不成立为false |
> | a>b,判断a是否大于b,成立为true,不成立为false |
>= | a>=b,判断a是否大于等于b,成立为true,不成立为false |
< | a<b,判断a是否小于b,成立为true,不成立为false |
<= | a<=b,判断a是否小于等于b,成立为true,不成立为false |
注意事项:
- 关系运算符的结果都是boolean类型,要么是true,要么是false。
- 千万不要把“==”误写成“=”。
逻辑运算符
符号 | 作用 | 说明 |
---|---|---|
& | 逻辑与(且) | 并且,两边都为真,结果才是真 |
| | 逻辑或 | 或者,两边都为假,结果才是假 |
^ | 逻辑异或 | 相同为false,不同为true |
! | 逻辑非 | 取反 |
短路逻辑运算符
符号 | 作用 | 说明 |
---|---|---|
&& | 短路与 | 结果和&相同,但是有短路效果 |
|| | 短路或 | 结果和|相同,但是有短路效果 |
三元运算符
//格式:关系表达式 ? 表达式1 : 表达式2;
int max = a > b ? a : b;//若a>b,max=a,反之max=b
计算规则
- 首先计算关系表达式的值
- 如果值为true,表达式1的值就是运算结果
- 如果值为false,表达式2的值就是运算结果
//例如:178cm,210cm,150cm来判断谁最大
int a =178;
int b =210;
int c =150;
int max=(a>b?a:b)>c?(a>b?a:b):c;
运算符优先级
优先级 | 运算符 |
---|---|
1 | . () {} |
2 | !、-、++、– |
3 | *、/、% |
4 | +、- |
5 | <<、>>、>>> |
6 | <、<=、>、>=、instanceof |
7 | ==、!= |
8 | & |
9 | ^ |
10 | | |
11 | && |
12 | || |
13 | ?: |
14 | =、+=、-=、*=、/=、%=、&=、|=、^=、%=、<<=、>>=、>>>== |
流程控制语句
顺序结构
顺序结构语句是Java程序默认的执行流程,按照代码的先后顺序,从上到下依次执行
分支结构
if语句
- if语句的第一种格式
//if语句的第一种格式
/*
if(关系表达式){
语句体;
}
*/
if(体重 > 150){
System.out.printLn("小伙子,要减肥了!");
}
- if语句的第二种格式
//if语句的第二种格式
/*
if(关系表达式){
条件语句1;
}else{
条件语句2;
}
*/
if(分数 >= 60){
System.out.println("及格");
}else{
System.out.println("不及格");
}
- if语句的第三种格式
//if语句的第三种格式
/*
if(关系表达式1){
语句体1;
}else if(关系表达式2){
语句体2;
}
……
else{
语句体 n +1;
}
*/
if(成绩<60){
System.out.println("准备吃竹笋炒肉!");
}else if(成绩>=60 && 成绩<=70){
System.out.println("逃过一劫!");
}else if(成绩>=70 && 成绩<=85){
System.out.println("准备晚上吃顿好的!");
}else{
System.out.println("明天去游乐园~~");
}
从上往下依次进行判断,只有要有一个判断为真,就执行对应的语句体如果所有的判断都为假,就执行else的语句体
switch语句
//switch语句格式
/*
switch(表达式){
case 值1:
语句体1;
break;
case 值2:
语句体1;
break;
……
default:
语句体 n+1;
break;
}
*/
switch(心里想吃的面){
case:"兰州拉面":
吃拉面;
break;
case:"老坛酸菜牛肉面":
吃面;
break;
case:"油泼面":
吃宽面;
break;
default:
吃方便面;
break;
}
格式说明:
- 表达式:(将要匹配的值)取值为byte、short、int、char。JDK5以后可以是枚举, JDK7以后可以是String。
- case:后面跟的是要和表达式进行比较的值(被匹配的值)。
- break:表示中断,结束的意思,用来结束switch语句。
- default:表示所有情况都不匹配的时候,就执行该处的内容,和if语句的else相似。
- case后面的值只能是字面量,不能是变量VI. case给出的值不允许重复
)
default的位置和省略
1.位置 : defaule不一定是写在最下面的,我们可以写在任意位置。只不过习惯会写在最下面
2.省略: defaule可以省略,语法不会有问题,但是不建议省略。
case穿透
就是语句体中没有写break导致的。
执行流程:
首先还是会拿着小括号中表达式的值跟下面每一个case进行匹配。
如果匹配上了,就会执行对应的语句体,如果此时发现了break,那么结束整个switch语句。
如果没有发现break,那么程序会继续执行下一个case的语句体,一直遇到break或者右大括号为止。
使用场景:
如果多个case的语句体重复了,那么我们考虑利用case穿透去简化代码。
JDK12新特性
switch(number){
case 1 -> System.out.println("一");
case 1 -> System.out.println("二");
case 1 -> System.out.println("三");
case 1 -> System.out.println("四");
default -> System.out.println("没有这种选项");
}
//另一种
switch(number){
case 1 -> {
System.out.println("一");
}
case 1 -> {
System.out.println("二");
}
case 1 -> {
System.out.println("三");
}
case 1 -> {
System.out.println("四");
}
default -> {
System.out.println("没有这种选项");
}
}
switch(week){
case 1,2,3,4,5 -> System.out.println("工作日");
case 6,7 -> System.out.println("休息日");
default -> System.out.println("没有这个星期")
}
switch和if第三种格式各自的使用场景
- if的第三种格式:一股用于对范围的判断
- switch:把有限个数据一一列举出来,让我们任选其一
循环结构
for循环
/*
for (初始化语句;条件判断语句;条件控制语句){
循环体语句;
}
*/
for(int i=1;i<=10;i++){
System.out.println("HelloWorld!");
}
while循环
/*
初始化语句;
while(条件判断语句){
循环体语句;
条件控制语句;
}
*/
int i=1;
while(i<=100){
System.out.println(i);
i++
}
- 初始化语句只执行一次
- 判断语句为true,循环继续
- 判断语句为false,循环结束
for和while的对比
共同点:运行规则都是一样的。
for和while的区别:
- for循环中,控制循环的变量,因为归属for循环的语法结构中,在for循环结束后,就不能再次被访问到了
- while循环中,控制循环的变量,对于while循环来说不归属其语法结构中,在while循环结束后,该变量还可以继续使用
for(int i=0;i<4;i++){
System.out.println(i);
}
//for循环用完后就不能使用变量i
int i=0;
while(i<4){
i++;
}
System.out.println(i);
//while循环用完后还可以使用变量i
for和while的区别2:
- for循环中:知道循环次数或者循环的范围
- while循环:不知道循环的次数和范围,只知道循环的结束条件。
do…while循环
/*
do{
循环体语句;
条件控制语句;
}while(条件判断语句);
*/
先执行后判断
高级循环
无线循环
//第一种
for(;;){
System.out.println("学习");
}
//第二种
while(true){
System.out.println("学习");
}
//第三种
do{
System.out.println("学习");
}while(true);
跳转控制语句
- continue:跳过本次循环,继续执行下次循环。
- break:结束整个循环。
int i=0;
for(;;){
System.out.println(i+"学习");
if(i==10){
//执行跳过
continue;
}
if(i==15){
//执行结束
break;
}
i++;
}
获取随机数Random
//导包--导包的动作必须出现在类定义的上边。
import java.utill.Random;
public static void main(String[] args){
//创建对象--只有r是变量名,可以变,其他的都不允许变。
Random r = new Random();
//生成随机数--只有number是变量名,可以变,其他的都不允许变。
int number = r.nextInt(随机数的范围);
}
//0~9获取随机数
Random r = new Random();
//范围是:包头不包括,包左不包右
for(int i=0;i<10;i++){
int number =r.nextInt(10);//0~9
System.out.println(number);
}
数组
数组介绍
数组:是一种容器,可以用来存储同种数据类型的多个值数
组容器在存储数据的时候,需要结合隐式转换考虑。
例如:int类型的数组容器( bodean(不行) byte short int double(不行))
例如:double类型的数组容器(byte short int long float double)
建议:容器的类型,和存储的数据类型保持一致
数组的定义与静态初始化
数组的定义
//格式一:数据类型[] 数组名
int[] array;
//格式二:数据类型 数组名[]
int array[];
数组的静态初始化
初始化:就是在内存中,为数组容器开辟空间,并将数据存入容器中的过程
//完整格式
//数据类型[] 数组名 = new 数据类型[]{元素1,元素2,...};
int[] array = new int[]{11,12,33};
double[] array2 = new double[]{11.1,22.2,33.3};
//简化格式
//数据类型[] 数组名 ={元素1,元素2,...};
int[] array = {11,12,33};
double[] array2 = {11.1,22.2,33.3};
数组的地址值
int[] arr = {1,2,3,4,5};
system.out.println(arr);//输出[I@6d03e736 --> 地址值
//[:表示当前是一个数组
//I:表示当前数组里面的元素都是int类型的
//@:表示一个间隔符号。(固定格式)
//6d03e736:才是数组真正的地址值,(十六进制)
//平时我们习惯性的会把这个整体叫做数组的地址值。
数组元素访问
//格式:数组名[索引];
int[] arr = {1,2,3,4,5};
System.out.println(arr[0]);//1
///格式:数组名[索引]=具体数据/变量;
arr[2] = 100;
System.out.println(arr[2]);//100
- 索引:也叫做下标,角标。
- 索引的特点:从O开始,逐个+1增长,连续不间断
数组遍历
数组遍历:将数组中所有的内容取出来,取出来之后可以(打印,求和,判断…)
注意:遍历指的是取出数据的过程,不要局限的理解为遍历就是打印!
//利用循环遍历数组
int[] arr = {1,2,3,4,5};
//数组名.length:是获取数组的长度
//数组名.fori:idea提供的快速生成数组遍历
for(int i=0;i<arr.length;i++){
System.out.println(arr[i]);
}
数组动态初始化
动态初始化:初始化时只指定数组长度,由系统为数组分配初始值。
//格式:数据类型[] 数组名 = new 数据类型[数组长度];
String[] arr = new String[3];
//添加
arr[0]="zhangsan";
arr[1]="lisi";
//获取
System.out.println(arr[0]);//zhangsan
System.out.println(arr[1]);//lisi
System.out.println(arr[2]);//默认初始化值:null
//数组默认初始化值的规律
//整数类型:默认初始化值0
//小数类型:默认初始化值0.0
//字符类型:默认初始化值'/uo000'空格
//布尔类型:默认初始化值 false
//引用数据类型:默认初始化值 null
数组动态初始化和静态初始化的区别
动态初始化:手动指定数组长度,由系统给出默认初始化值。
- 只明确元素个数,不明确具体数值,推荐使用动态初始化
举例:使用数组容器来存储键盘录入的5个整数。
int[] arr = { ? ? ? ? ? };
int[] arr = new int[5];
静态初始化:手动指定数组元素,系统会根据元素个数,计算出数组的长度。
- 需求中已经明确了要操作的具体数据,直接静态初始化即可。
举例:将全班的学生成绩存入数组中11,22,33
int[]arr = {11,22,33};
数组常见问题
- 当访问了数组中不存在的索引,就会引发索引越界异常。
public static void main(String[] args){
//1.定义数组
int[] arr ={1,2,3,4,5};
//长度:5
//最小索引:0
//最大索引:4(数组长度-1)
System.out.println(arr[10]);
//报错ArrayIndexOutOfBoundsException
}
数组常见操作
求最值
//定义一个数组
int[] arr={11,24,52,10};
//记录最大值的变量
int max = arr[0];
//通过循环在数组中依次判断谁为最大
for(int i=0;i<arr.length;i++){
if(arr[i]>max){
max=arr[i];
}
}
//记录最小值的变量
int min = arr[0];
//通过循环在数组中依次判断谁为最小
for(int i=0;i<arr.length;i++){
if(arr[i]<min){
min=arr[i];
}
}
System.out.println("最大值:"+max+",最小值:"+min);
求和
//定义一个数组
int[] arr={1,2,3,4,5};
//总和
int sum=0;
//平均数
double average=0;
//通过循环在数组中依次相加,求出总和
for(int i=0;i<arr.length;i++){
sum+=arr[i];
}
//平均数
average = sum / arr.length;
//统计有多少个数据比平均值小
//统计有多少个
int count=0;
for(int i = 0; i<arr.length;i++){
if(arr[i]<average){
count++;
}
}
System.out.println("总和:"+sum+",平均数:"+average+",有多少个小于平均值:"+count);
交换数据
/*
需求:定义一个数组,存入1,2,3,4,5。交换首尾索引对应的元素。
交换前:1,2,3,4,5
交换后:5,2,3,4,1
*/
//定义一个数组
int[] arr={1,2,3,4,5};
//利用循环交换数据
for(int i=0,j = arr.length;i<j;i++,j--){
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
打乱数据
//定义数组
int[] arr={1,2,3,4,5};
//遍历数组,按索引打乱数组
Random r = new Random();
for(int i=0;i<arr.length;i++){
//生成一个随机索引
int randomIndex = r.nextInt(arr.length);
int temp = arr[i];
arr[i] = arr[randomIndex];
arr[randomIndex]=temp;
}
数组的内存图
Java内存分配
Java内存分配:栈、堆、方法区、本地方法栈、寄存器
- 栈:方法运行时使用的内存,比如main方法运行,进入方法栈中执行
- 堆:存储对象或者数组,new来创建的,都存储在堆内存
- 方法区:存储可以运行的class文件
- 本地方法栈:JVM在使用操作系统功能的时候使用,和我们开发无关
- 寄存器:给CPU使用,和我们开发无关
注意:从JDK8开始,取消方法区,新增元空间。把原来方法区的多种功能进行拆分,有的功能放到了堆中,有的功能放到了元空间中。
public static void main(Stirng[] args){
int a= 10;
int b= 10;
int c=a+b;
sout(c);
}
以上代码在内存中的运行:
数组的内存图
public static void main(String[] args){
int[] arr =new int[2];
//获取
//sout是idea中“System.out.println();”的快捷方式
sout(arr);
sout(arr[0]);
sout(arr[1]);
//赋值
arr[0]=11;
arr[1]=22;
sout(arr[0]);
sout(arr[1]);
sout("--------");
//第二个数组
int[] arr2 = {33,44,55};
sout(arr2);
sout(arr2[0]);
sout(arr2[1]);
sout(arr2[2]);
}
- 获取:
- 赋值
- 再创建一个数组
- 只要是new出来的一定是在堆里面开辟了一个小空间
- 如果new了多次,那么在堆里面有多个小空间,每个小空间中都有各自的数据
两个数组指向同一个空间的内存图
public static void main(String[] args){
int[] arr1={11,22};
int[] arr2=arr1;
sout(arr1[0]);
sout(arr2[0]);
arr2[0] = 33;
sout(arr1[0]);
sout(arr2[0]);
}
当两个数组指向同一个小空间时,其中一个数组对小空间中的值发生了改变,那么其他数组再次访问的时候都是修改之后的结果了。
方法
什么是方法?
方法(method)是程序中最小的执行单元。
public class HelloWorld{
//main方法,主方法
public static void main(String[] args){
System.out.println("你好!");
}
}
重复的代码、具有独立功能的代码可以抽取到方法中。
- 可以提高代码的复用性
- 可以提高代码的可维护性
方法的格式
方法定义:把一些代码打包在一起,该过程称为方法定义。
方法调用:方法定义后并不是直接运行的,需要手动调用才能执行,该过程称为方法调用。
最简单的方法定义和调用
//最简单的方法定义和调用
//格式:
pubic static void 方法名(){
方法体(就是打包起来的代码);
}
//调用
方法名();
//范例:
public static void palyGame(){
System.out.println("原神启动!");
}
//调用
playGame();
带参数的方法
//带参数的方法
//单个参数
//格式:
pubic static void 方法名(参数){
....
}
//调用
方法名(变量);
//范例:
public static void method(int number){
System.out.println(number);
}
//调用
method(1);
//多个参数
//格式:
pubic static void 方法名(参数1,参数2,...){
....
}
//调用
方法名(变量1,变量2,...);
//范例:
public static void method(int number1,int number2,...){
System.out.println(number1);
System.out.println(number2);
...
}
//调用
method(1,4,...);
注意:方法调用时,参数的数量与类型必须与方法定义中小括号里面的变量一一对应,否则程序将报错。
形参和实参
- 形参:全称形式参数,是指方法定义中的参数
- 实参:全称实际参数,方法调用中的参数
带返回值方法的定义和调用
//带返回值方法的定义和调用
//格式:
public static 返回值类型 方法名(参数){
方法体;
return 返回值;
}
//调用
//直接调用
方法名(实参);
//赋值调用
整数类型 变量名 = 方法名(实参);
//输出调用
System.out.println(方法名(实参));
//范例
public static int getSum(int a, int b){
int c= a+b;
return c;
}
//调用
//直接调用
getSum(1,3);
//赋值调用
int d=getSum(1,3);
//输出调用
System.out.println(getSum(1,3));
方法的完整定义格式
public static 返回值类型 方法名(参数){
方法体;
return 返回值;
}
方法的注意事项
方法不调用就不执行
方法与方法之间是平级关系,不能互相嵌套定义
方法的编写顺序和执行顺序无关
方法的返回值类型为void,表示该方法没有返回值,
没有返回值的方法可以省略return语句不写。
如果要编写return,后面不能跟具体的数据。
return语句下面,不能编写代码,因为永远执行不到,属于无效的代码
return关键字
- 方法没有返回值:可以省略不写。如果书写,表示结束方法
- 方法有返回值:必须要写。表示结束方法和返回结果
方法的重载
- 在同一个类中,定义了多个同名的方法,这些同名的方法具有同种的功能。
- 每个方法具有不同的参数类型或参数个数,这些同名的方法,就构成了重载关系
- 简单记:同一个类中,方法名相同,参数不同的方法。与返回值无关
- 参数不同:个数不同、类型不同、顺序不同
//范例
public static void sum(int a,int b){
System.out.println("方法参照物");
}
//重载
//第一个
public static void sum(int a,int b,int c){
System.out.println("正确");
}
//第二个(这个是错误,与返回值无关)
public static int sum(int a,int b){
System.out.println("错误");
}
//第三(更改顺序是可以,但不建议这么做)
public static void sum(int b,int a){
System.out.println("正确");
}
//第四个
public static void sum(double a,int b){
System.out.println("正确");
}
...
方法的内存
方法调用的基本内存原理
- 简单
- 复杂
基本数据类型和引用数据类型
基本数据类型:整数类型、浮点数类型、布尔类型、字符类型
引用数据类型:除了基本数据类型的其他所有类型
从内存的角度去解释:
- 基本数据类型:数据值是存储在自己的空间中
- 特点:赋值给其他变量,也是赋的真实的值。
-
引用数据类型:数据值是存储在其他空间中,自己空间中存储的是地址值。
-
特点:赋值给其他变量,赋的地址值。
int[] arr1={1,2,3}; int[] arr2=arr1;
-
方法传递的内存原理
方法传递基本数据类型的内存原理
传递基本数据类型时,传递的是真实的数据,形参的改变,不影响实际参数的值
//上面能够改变的方式
public static void main(String[] args){
int number =100;
sout("调用change方法前:" + number);
//设立change方法有返回值,并且赋值给number
number = change(number);
sout("调用change方法后:" + number);
}
public static int change(int number){
number = 200;
return number;
}
方法传递引用数据类型的内存原理
传递引用数据类型时,传递的是地址值,形参的改变,影响实际参数的值