自用笔记,整理自韩顺平老师的视频。
一、学习路线
编程导航 - 程序员一站式编程学习交流社区,做您编程学习路上的导航员
二、基础知识
java语言的跨平台性
(1)JVM
( java virtual machine java虚拟机)
1.jvm是虚拟的计算机,具有指令集并使用不同的存储区域,负责执行指令,管理数据,内存,寄存器,包含在JDK中。
2.对于不同的平台,有不同的JVM
3.java虚拟机屏蔽了底层运行平台的差别,实现了“一次编译,到处运行”
(2)JDK
JDK (java development kit java开发工具包)包含java的开发工具,也包含JRE
(3)JRE
1.(java Runtime Enviroment java运行环境)
2. JRE = JVM + java核心类库
3.如果只想运行一个开发好的java文件,安装jre即可。
JDK,JRE,JVM的包含关系
1. JDK = JRE + 开发工具集
2. JRE = JVM + java SE标准类库
3.JDK = JVM + java SE标准类库 + 开发工具集
4.如果只想运行开发好的.class文件,只需要JRE
(4)JDK安装和配置
当前执行的程序在当前目录下如果不存在,win10系统会在系统中已有的一个名为Path的环境变量指定的目录中查找。
环境变量的作用
环境变量的作用是为了在dos的任意目录去使用java和javac命令
环境变量配置过程:
1.我的电脑--属性--高级系统设置--环境变量
2.增加JAVA_HOME环境变量,指向jdk的安装目录C:\Program Files\Java\jdk-1.8
3.编辑path环境变量,增加%JAVA_HOME%\bin
4.打开DOS命令行,任意目录下输入javac或java,如果出现参数信息,则成功。
(5)快捷键
快捷键 | 说明 | 备注 |
CTRL + / | 快捷多行注释 |
(6)实用网站
网址 | 说明 | 备注 |
https://www.matools.com/ | API在线文档 | |
三、java学习01-基础
(1)基础骨架 Hello world
//1.public static helloworld 表示helloworld是一个类,是一个public共有的类
//2.helloworld{}表示程序的开始和结束
//3.public static void main(String[] args)表示一个主方法,即程序的入口
//4.main(){} 表示方法的开始和结束
//5.System.out.println("hello world"); 表示输出“hello world”到屏幕
//6.分号;表示一个一个语句的结束
public class helloworld {
//编写一个主方法
public static void main(String[] args){
System.out.println("hello world");
}
}
.java文件为源文件,.class文件为字节码文件,字节码文件是可以直接执行的文件。
DOS窗口中,编译命令(javac) 运行命令(java)
(2)学习方法
(3)转义字符
转义字符 | 作用 | 备注 |
\n | 换行符,自动换行 | |
\t | 制表位,用于对齐 | |
\ | 输出特殊字符,如\," | |
\r | 一个回车 | 把光标放到本行最前面,后续字符会覆盖前面的字符 |
// \t 制表符 输出:一行文字 在这里
System.out.println("一行文字\t在这里");
// \n 换行符 输出: 一行文字(下一行)在这里
System.out.println("一行文字\n在这里");
// \r 回车符 输出:在这里
System.out.println("一行文字\r在这里");
// \\ 输出一个\ 输出:一行文字\在这里
System.out.println("一行文字\\在这里");
(4)注释
用于提高代码的可阅读性
- 单行注释 //
- 多行注释 /**/
- 文档注释
生成一个以网页形式展示的注释。
//在类中开头写
/*
*@author 约德尔
*@version 1.0
*/
//在DOS命令中输入 javadoc -d 文件夹名 -author -version 文件名.java
(5)java编写7个规范
- 类,方法的注释,使用javadoc的方式,即文档注释
- 非javadoc注释,往往是对代码的说明,说明如何修改,注意事项
- 使用tab,价整体将代码右移,使用shift+tab整体左移
- 运算符和=两边,給空格。
- 源码文件使用 utf-8 编码
- 行款字符不要超过 80
- 代码编程风格有 次行风格 行尾风格
(6)java的重要特点
- java语言是面向对象的(oop)
- java语言是健壮的。java的强类型机制、异常处理、垃圾的自动回收机制等
- java语言是跨平台行的。一个编译好的.class文件可以在多个操作系统下运行
- java语言是解释型的
四、java学习02-数据类型
(1)变量概念
变量是程序的基本组成单位,变量相当于内存中一个存储空间的表示。
变量有三个基本要素:类型+名称+值。
内存中会储存变量值,变量名称相当于一个地址,执行代码时,会根据地址找到变量值。
(2)变量的使用
//01.变量的声明-- 变量类型 变量名;
int a;
//02.变量的赋值-- 变量名 变量值;
a = 25;
//03.变量的定义(在声明同时进行赋值)-- 变量类型 变量名 = 变量值;
int a = 25;
//04.变量的使用
System.out.println(a);
(3)变量使用注意事项
- 变量表示内存中的一个存储区域,不同变量所占的存储空间大小不同,如int 4个字节,double 8个字节
- 该区域有自己的名称(变量名)和类型(数据类型)
- 变量必须先声明,后使用
- 该区域的数据可以在同一类型范围内不断变化
- 变量在同一个作用域内不能重名
- 变量=变量名+值+数据类型
(4)+号的使用
- 当左右两边都是数值型时,做加法运算
- 当左右两边有一方为字符串时,做拼接运算
System.out.println(100+98); //198
System.out.println("100"+98); //10098
System.out.println("100"+98+3); //100983
System.out.println(100+98+"3"); //1983
(5)数据类型
整型细节
- java各整数类型有固定的范围和字段长度,不受具体操作系统的影响,保证java程序的可移植性
- java的整型常量默认为int类型,声明long类型常量需要在后面加"l"或"L"
- java程序中变量常声明为int型,除非不足以表示大数,才使用long
- bit:计算机中的最小存储单位。byte:计算机中基本存储单元,1byte=8bit
浮点型细节
- 与整数类型类似,java浮点类型也有固定的范围和字段长度,不受os的影响。[float类型 4 哥字节,double类型 8个字节]
- java的浮点型常量默认为double类型,声明flaot类型常量需要在值后加"f"或"F"
- 浮点型常量有两种表示形式十进制: 如:5.12 512.0f .512 科学计数法:如5.12e2[e为10的n次方]
- 通常情况下应使用double类型,double类型比float类型更精密
- 浮点数使用陷阱:2.7 与 8.1/3的比较。 机器计算浮点型的除法会生成一个接近结果的浮点数,如果要比较是否相等,则需要验证两个浮点型之差的绝对值是否在一个精密的范围内。
-
DecimalFormat类的format()方法可以格式化浮点数小数点后个数
double n1 = 2.7;
double n2 = 8.1/3;
System.out.println(n1); //输出2.7
System.out.println(n2); //输出2.6999999999999997
//验证两个变量是否相等
if(Math.abs(n1-n2)<0.000000001){
System.out.println("变量n1与变量n2相等");
}
字符类型细节
- 字符类型是用单引号('')括起来的单个字符
- java中允许使用转义字符'\'来将其后的字符转变为特殊字符型常量
- 在java中,char的本质是一个整数,在输出时,与unicode编码对照
- 可以直接给char类型赋值一个整数,输出时会按照unicode字符输出
- char类型允许计算,相当于一个整数
字符类型(char)字符类型本质探讨
1.字符型 存储到计算机中,需要将字符对应的码值(整数)找出来,比如'a'存储:'a'==> 码值 97 ==> 二进制(1100001)==> 存储读取:二进制(110 0001) => 97 ===>'a'=> 显示
2.字符和码值的对应关系是通过字符编码表决定的(是规定好)
字符编码表
ASCII (ASCII编码表一个字节表示,一个128个字符,实际上一个字节可以表示256个字符,只用128个)
Unicode (Unicode 编码表 固定大小的编码 使用两个字节来表示字符,字母和汉字统一都是占用两个字节,这样浪费空间)
utf-8(编码表,大小可变的编码 字母使用1个字节,汉字使用3个字节)
gbk(可以表示汉字,而且范围广,字母使用1个字节,汉字2个字节)
gb2312 (可以表示汉字,gb2312 < gbk)
big5 码(繁体中文,台湾,香港)
布尔类型
- 布尔类型也叫boolean类型,只允许取值true和false,不允许数值类型和null
- boolean类型占一个字节
- 布尔类型适用于逻辑计算
自动类型转换
自动类型转换细节
- 有多种类型的数据混合运算时,系统首先将所有数据类型转换成容量最大的那种数据类型,然后计算
- 如果把精度大的数据类型赋值給精度小的数据类型,系统会报错
- (byte、short)和char之间不会自动转换
- boolean不参与转换
- 自动提升原则:表达式结果的类型自动提升为 操作数中最大的类型
- byte,short,char 他们三者可以计算,计算前会统一转换成int类型
强制类型转换
自动类型转换的逆过程,将容量大的数据类型转换成容量小的数据类型。使用时加上强制转换符(),且可能造成数据精度损失或数据溢出。
//将int类型强制转换成byte类型
int n1 = 15;
byte n2 = (byte)n1;
细节:
- 当进行数据的大小从 大------>小,就需要使用到强制类型转换
- 强转符号只针对于最近的操作数有效,往往会使用小括号提升优先级
- char类型可以保存int的常量值,但不能保存int的变量值,需要强转
- byte和short类型在进行运算时,当做int类型处理
基本数据类型与字符串之间的转换
基本类型转String类型:
将基本类型的值+""即可
int n1 = 100;
String n2 = n1+"";
String类型转基本类型:
通过基本类型的包装类调用parseXX方法即可
int num1 = Integer.parseInt("100");
double num2 = Double.parseDouble("54.47");
float num3 = Float.parseFloat("7.5f");
long num4 = Long.parseLong("655");
byte num5 = Byte.parseByte("5");
short num6 = Short.parseShort("7");
boolean num7 = Boolean.parseBoolean("true");
//String类型转char类型,需要用到String类型的构造方法charAt(index)
String a = "abc";
char n1 = a.charAt(2);
System.out.println(n1); //输出'c'
(6)API
API (Application Programming Interface,应用程序接口)是java提供的基本编程接口。
五、java学习03-运算符
(1)算术运算符
(2)关系运算符
关系运算符的结果都是boolean型的,要么是true,要么是fasle
(3)逻辑运算符
用于连接多个条件,结果是boolean类型
短路与 和 逻辑与的区别
- 短路与&&的第一个条件若为false,则直接结束,不会判定第二个条件
- 逻辑与&的第一个条件即使为false,仍然会判定第二个条件
- 短路或,逻辑或同理,取决于第一个条件是否为true
(4)三元运算符
语法:
条件表达式?表达式1:表达式2;
运算规则:
如果条件表达式为true,运算后的结果是表达式1
如果条件表达式为false,运算后的结果是表达式2
//条件表达式"2>1"为true,所以返回?后第一个表达式,即11,将11赋值給变量c
int c = 2>1 ?11:12;
System.out.println(c);
三元运算符细节
- 表达式1和表达式2要为可以赋给接受变量的类型(或可以自动转换的类型)
- 三元运算符可以转成 if--else 语句
(5)运算符优先级
(6)标识符
概念:
java对各种变量、方法和类等命名时使用的字符序列称为标识符
规则:
- 由26个英文字母大小写,0-9,_或$组成
- 不可以用数字开头
- 不可以使用关键字和保留字
- java中严格区分大小写,长度无限制
- 标识符不能有空格
规范:
- 包名:多单词组成时所有字母都小写: aaa.bbb.ccc //比如com.hsp.crm
- 类名、接口名:多单词组成时,所有单词的首字母大写:XxxYyyZzz比如:TankShotGame
- 变量名、方法名:多单词组成时,第一个单词首字母小写,第二个单词开始每个单词首字母大写: xxxYyyZzz比如:tankShotGame
- 常量名:所有字母都大写。多单词时每个单词用下划线连接:XXX_YYY_ZZZ比如 :定义一个所得税率 TAX_RATE5. 后面我们学习到 类,包,接口,等时,我们的命名规范要这样遵守,更加详细的看文档.
(7)键盘输入语句
步骤:
- 导入该类的所在包,java.util.*
- 创建该类对象
- 调用里面的功能
//引入该类所在的包
import java.util.Scanner;
public class scanf {
public static void main(String[] args) {
int a;
//创建该类的实例
Scanner myscan = new Scanner(System.in);
//调用scan实体的netInt()方法,将返回值赋值給变量a
a = scan.nextInt(); //int类型
char temp = myscan.next().charAt(0); //char类型
short a = myscan.nextShort(); //short类型
long b = myscan.nextLong(); //long类型
float c = myscan.nextFloat(); //float类型
double d = myscan.nextDouble(); //double类型
boolean e = myscan.nextBoolean(); //boolean类型
byte f = myscan.nextByte(); //byte类型
String g = myscan.next(); //String类型
}
}
六、java学习04-控制结构
(1)分支控制 if-else
1)单分支
当条件表达式为true时,就会执行{}中代码,当{}中只有一条语句时,可不写{}
if(条件表达式){
执行代码块;
}
2)双分支
当条件表达式为true时,就会执行{}中代码,否则执行else{}中的代码块
if(条件表达式){
执行代码块1;
}else{
执行代码块2;
}
3)多分支
当条件表达式为true时,就会执行{}中代码,如果为false,就会按顺序执行下一个else if中的条件表达式,如果都不为true,则执行else{}中的代码块
if(条件表达式1){
执行代码块1;
}
else if(条件表达式2){
执行代码块2;
}
...
else{
执行代码块3;
}
4)嵌套分支
在一个分支结构中又完整地嵌套了另一个完整地分支结构,内部的分支结构称为内层分支,外部的称为外层分支。
//举例:判断一个数是否在4和7之间
int a = 6;
if(a>4){
if(a<7){
System.out.println("变量a在4-7之间");
}
}
5)switch分支
语法:
- switch 关键字,表示switch分支
- 表达式 对应一个值
- case 常量1:当表达式的值等于常量1,就执行语句块1
- break :表示退出switch
- 如果和case常量1匹配,就执行语句块1,如果没有匹配,就继续匹配常量2,以此类推
- 如果一个都没匹配上,就执行default
switch(表达式){
case 常量1:
语句块1;
break;
case 常量2:
语句块2;
break;
...
default:
语句块n;
break;
}
细节:
- 表达式数据类型,应和case后的常量类型一致,或者可以自动转成可以比较的类型
- switch(表达式)中表达式的返回值必须是:(byte、short、int、char、enum、String)
- case子句是可选地,当没有匹配的case时,执行default
- break语句用来执行完一个case分之后使程序跳出switch语句,如果没有break,则会执行下一个case子句或default
(2)循环结构
1)for循环
基础语法:
- for关键字,表示循环控制
- for有四要素:(1)循环变量初始化(2)循环条件(3)循环操作(4)循环变量迭代
- 循环操作,这里可以有多条语句,也就是循环执行的代码
- 如果循环操作只有一条语句,可以省略{}
for(循环变量初始化;循环条件;循环变量迭代){
循环操作;
}
细节:
- 循环条件是返回一个布尔值的表达式
- for(;循环判断条件;)中的初始化和变量迭代可以省略,但是分号不可以省略
- 循环初始值可以有多条初始化语句,但要求类型一样,中间用逗号隔开,变量迭代同理
2)while循环
基础语法:
- while循环也有四要素
while(循环条件){
循环体;
循环变量迭代;
}
3)do-while循环
基础语法:
- do 、while是关键字
- do-while有四要素
- 先执行,再判断,一定会执行一次
- 最后有一个分号
do{
循环体;
循环遍历迭代;
}while(循环条件);
4)嵌套循环
将一个循环放在另一个循环体内,形成内层循环和外层循环
//举例:一共执行最内层输出语句5*5=25次
for(int i = 1;i<=5;i++){
for(int j = 1;j<=5;j++){
System.out.println("");
}
}
5)break语句
介绍:break语句用于终止某个语句块的执行,一般使用在switch或者循环中
语法:
{
...
break;
...
}
细节:
- break语句出现在多层嵌套的语句块中时,可以通过标签指明要终止的是哪一层语句块
- 标签的基本使用,如果没有标签,默认退出最近的循环体
label1:{... label2: {... label3: {... break label2; ...} } }
6)continue语句
介绍:
- continue语句用于结束本次循环,继续执行下一次循环
- continue语句出现在多层嵌套的循环语句体中时,可以通过标签指明要跳过的是哪一层循环,这个和前面的标签的使用的规则是一样的
语法:
{
...
continue;
...
}
7)return语句
如果return写在main方法,退出程序。
七、java学习05-数组
(1)数组基础
基础介绍:
- 数组可以存放多个同一类型的数据,数组也是一种数据类型,是引用类型。
-
/* 1)常量之间用,号隔开 2)数组下标(索引)从0开始按顺序代表数组中数据,0代表第一个,1代表第二个,以此类推。 3)数组定义时,[]可以放在数组名前,也可以放在数组名后 4)数组只有在 new 操作后才会分配空间,也可以先声明,后面再定义 */ //数组的定义 数据类型[] 数组名 = {常量1,常量2,常量3,...}; //静态初始化 或者 数据类型[] 数组名 = new 数据类型[数组大小]; //动态初始化 double[] hens = {10.2,22.5,23,24,25,26}; //定义一个hens数组,代表每只鸡的体重 double[] chicken = new double[6] //定义一个chicken数组,有6个double类型的大小 //数组的调用 数组名[索引] = 5; hens[2] = 25; //将数组中第3只鸡的体重修改为25 //数组长度获取 数组名.length; //使用.length返回数组长度
数组细节:
- 数组是多个相同类型数据的组合,实现对这些数据的统一管理
- 数组中的元素可以是任何数据类型,包括基本类型和引用类型,但是不能混用
- 数组创建后,如果没有赋值,有默认值,(int 0 ,short 0 ,byte 0,long 0,float 0.0 double 0.0 ,char \u0000 ,boolean false ,String null)
- 使用数组的步骤:1)声明数组并开辟空间 2)給数组各个元素赋值 3)使用数组
- 数组的下标从0开始
- 数组下标必须在指定范围内使用,否则报:下标越界异常
- 数组属于引用类型,数组型数据是对象(object)
- 数组名.length 可以返回数组长度
赋值机制:
- 基本数据类型赋值,这个值就是具体的数据,互相不影响
- 数组在默认情况下是引用传递,赋的值是地址
/*基础类型赋值的是值,b变量的变化不会影响到a变量*/
int a = 1;
int b = a;
b = 3;
System.out.print(a+" "+b); //a=1,b=3
System.out.println();
/*引用类型赋值的是地址,变量arr2的变化会影响到arr1变量*/
int[] arr1 = {1,2,3};
int[] arr2 = arr1;
arr2[1] = 51;
System.out.print(arr1[1]+" "+arr2[1]); //arr1[1]=51,arr2[1]=51
(2)二维数组
相当于一维数组里的每个元素都是一个一维数组。
//二维数组定义
1)数据类型[][] 数组名 = new int[行][列];
2)数据类型[][] 数组名 = {{},{},...}
3)数据类型[][] 数组名;
数组名 = new 数据类型[行][];
数组名[行] = new 数据类型[列];
//二维数组元素的调用
数组名[行][列];
//二维数组长度的获取
arr.length; //二维数组中一维数组的个数
arr[1].length; //二维数组第二组的数组长度
八、java学习06-面向对象
(1)类与对象
将现实中的事物抽象成属性和行为,归类,该类别中一个个具体事物称之为类的实例,即对象。如张三是人类的一个实例,是一个对象,他有自己的属性(身高,体重,性别,年龄),也有自己的行为(跑,跳,说话,工作)
类和对象的区别和联系:
- 类是抽象的,概念的,代表一类事物,比如人类,猫类,即它是数据类型
- 对象是具体的,实际的,代表一个具体事物,比如张三,王五,即实例
- 类是对象的模板,对象是类的一个个体,对应一个实例
1)类的定义
//类的定义
class 类名 {
数据类型 属性名;
修饰访问符 返回值数据类型 方法名(形参列表){代码行;};
}
//类的实例化(创建对象)
{...
//1)直接创建
类名 对象名 = new 类名();
//2)先声明再创建
类名 对象名;
对象名 = new 类名();
}...
//对象属性的调用
{...
对象名.属性名;
...}
//对象方法的调用
{...
对象名.方法名();
...}
-------------------------------------------------------------------------
//举例:Cat类的定义和使用
public class object_1 {
public static void main(String[] args) {
//创建Cat类实例
Cat xiaoHua = new Cat();
//定义对象xiaoHua的属性值
xiaoHua.name = "xiaoHua";
xiaoHua.color = "yellow";
xiaoHua.age = 4;
System.out.println("名字:"+xiaoHua.name+" 年龄:"+xiaoHua.age+" 花色:"+xiaoHua.color);
}
}
//定义Cat类
class Cat{
//定义Cat类的属性
String name;
int age;
String color;
}
类和对象的内存分配机制:
- 栈:一般存放基本数据类型(局部变量)
- 堆:存放对象(Cat cat,数组等)
- 方法区:常量池(常量,比如字符串),类加载信息
2)对象的创建
//类的实例化(创建对象)
{...
//直接创建
类名 对象名 = new 类名();
//先声明再创建
类名 对象名;
对象名 = new 类名();
}...
细节:
- 对象创建的流程
加载Person类信息
默认初始化、显示初始化、构造器初始化
返回对象的地址
(2)属性
概念:
- 属性=成员变量=field(字段)
- 属性是类的一个组成部分,一般是基本数据类型,也可以是引用类型。
细节:
- 属性的定义语法同变量,示例:访问修饰符 属性类型 属性名
访问修饰符:控制属性的访问范围
1)public 2)protected 3)默认 4)private - 属性的定义类型可以为任意类型,包括基础类型和引用类型
- 属性如果不赋值,有默认值,规则和数组一致
(3)成员方法
1)成员方法内存执行机制
好处:
- 提高代码的复用性
- 可以将实现的细节封装起来,可以直接供其他用户使用
2)成员方法的定义
访问修饰符 返回数据类型 方法名(形参列表){
执行语句;
return 返回值;
}
- 形参列表:表示成员方法输入
- 数据类型(返回类型):表示成员方法输出,void没有输出
- 方法主体:表示为了实现某一功能代码块
- return语句不是必需的
3)返回数据类型的细节
- 一个方法最多有一个返回值
- 返回类型可以为任意类型,包含基本类型或引用类型(数组、对象)
- 如果方法有要求有返回数据类型,则方法体最后的执行语句必须为return 值;而且要求返回值类型必须和return的值类型一致或兼容
- 如果方法是void,则方法体中可以没有return语句,或者只写return;
- 方法名使用驼峰命名法(如果由词组组成,则第二个单词开始,首字母大写,getNum),最好见名知意
4)形参列表的细节
- 一个方法可以有0个参数,也可以有多个参数,中间用逗号隔开
- 参数类型可以为任意类型,包含基本类型和引用类型
- 调用带参数的方法时,一定对应着参数列表传入相同类型或兼容类型的参数
- 方法定义时的参数称为形式参数,简称形参;方法调用时的额参数称为实际参数,简称实参,行参与形参的类型要一致或兼容,顺序必须一致
5)方法体的细节
- 方法不能嵌套定义
6)方法调用细节
- 同一个类中的方法调用,直接调用即可。(方法名();)
- 跨类中的方法,A类调用B类的方法:需要通过对象名调用。(对象名.方法名();)
- 跨类的调用和方法的访问修饰符有关
7)方法传参机制
- 如果参数的类型是基本类型,传递的是值本身,形参的修改不会影响实参
如果参数的类型是引用类型,传递的是引用地址,形参的修改会影响实参
8)方法递归调用
递归就是方法自己调用自己,每次调用时传入不同的变量
递归重要规则
- 执行一个方法时,就创建一个新的受保护的独立空间(栈空间)
- 方法的局部变量是独立的,不会相互影响,比如n变量
- 如果方法中使用的是引用类型变量,就会共享该引用类型的数据
- 递归必须向退出递归的条件逼近,否则就会无线递归
- 当一个方法执行完毕,或者遇到return,就会返回,遵守谁调用,就将结果返回给谁,同时当方法执行完毕或者返回时,该方法也就执行完毕
9)方法的重载(Overload)
介绍:java中允许同一个类中,多个同名方法的存在,但要求 形参列表不一致
重载的好处:减轻了起名的麻烦,减轻了记名的麻烦
重载的细节:
- 方法名:必须相同
- 参数列表:必须不同(参数类型、个数、顺序,有一样不同即可)
- 返回类型:无要求
10)可变参数
概念:java允许将同一个类中多个同名同功能但参数个数不同的方法,封装成一个方法
基本语法:
访问修饰符 返回类型 方法名(数据类型... 形参名){}
细节:
- 可变参数的实参可以为0个或任意多个
- 可变参数的实参可以为数组
- 可变参数的本质就是数组
- 可变参数可以和普通类型的参数一起放在形参列表,但必须保证可变参数在最后
- 一个形参列表只能出现一个可变参数
例题17
11)作用域
概念:
- 在java编程中,主要的变量就是属性(成员变量)和局部变量
- 局部变量一般指在成员方法中定义的变量
- java中作用域的分类
全局变量:即属性,作用域为整个类体
局部变量:除了属性外的其他变量,作用域为定义它的代码块中 - 全局变量可以不赋值,直接使用,因为有默认值,局部变量必须赋值才能使用
细节:
- 属性和局部变量可以重名,访问时遵循就近原则
- 在同一个作用域中,比如在同一个成员方法中,两个局部变量不能重名
- 属性生命周期较长,伴随着对象的创建而创建,伴随着对象的死亡而销毁。局部变量,生命周期较短,伴随着它的代码块的执行而创建,伴随着代码块的结束而销毁。
- 作用域范围
全局变量:可以被本类使用,或其他类使用
局部变量:只能在本类中对应的方法中使用 - 修饰符不同
全局变量/属性可以加修饰符
局部变量不可以加修饰符
例题18
12)构造器(constructor)
介绍:完成对新对象的初始化(当对象被创建后,自动初始化操作)
基础语法:
[修饰符] 方法名(形参列表){方法体;}
- 构造器的修饰符可以默认,也可以是public、protected、private
- 构造器没有返回值
- 方法名和类名必须一致
- 参数列表和成员方法一样的规则
- 构造器的调用由系统完成
构造器细节:
- 一个类可以定义多个不同的构造器,即构造器重载
- 构造器是完成对象的初始化,不是创建对象
- 在创建对象时,系统自动调用该类的构造方法
- 如果程序员没有定义构造方法,系统会自动給类生成一个没有任何功能的默认构造器
- 一旦定义了自己的构造器,默认的构造器就覆盖了,就不能再使用默认的无参构造器,除非显式定义一下(程序员创建出来)
例题19
javap 反编译命令,可以反编译.class文件
13)this关键字
this 指向所在对象的地址,即等于对象本身。
哪个对象调用,this就属于哪个对象
this使用细节:
- this关键字可以用来访问本类的属性、方法、构造器
- this用于区分当前类的属性和局部变量
- 访问成员方法的语法:this.方法名(参数列表);
- 调用其他构造器语法:this(参数列表);
只能在构造器中使用(如果使用这条调用其他构造器的语句,必须放在该作用域第一条语句位置) - this不能在类定义的外部使用,只能在类定义的方法中使用
例题19