Java学习
Java
java能做什么
1 | 1.Java是什么? |
Java特性
Java语言是面向对象的(oop)
Java语言是健壮的。Java的强类型机制、异常处理、垃圾的自动收集等是Java程序健壮性的重要保证
Java语言是跨平台性的。[即:一个编译好的.class文件可以在多个系统下运行,这种特性称为跨平台]从而做到一处编译,处处运行
Java语言是解释型的
解释性语言:javascript,PHP,java 编译性语言:c/c++
区别是:解释性语言,编译后的代码,不能直接被机器执行,需要解释器来执行;编译性语言,编译后的代码,可以直接被机器执行, c/c++
1 | 1.Java 语言是简单的: |
jdk介绍
- JDK的下载
这是JDK下载的官方网址 https://www.oracle.com/java/technologies/downloads/
- JDK、JRE和JVM的包含关系
- JDK = JRE +开发工具集(例如Javac,java编译工具等)
- JRE = JVM + Java SE标准类库(java核心类库)
- 如果只想运行开发好的.class文件只需要JRE
Java的跨平台是什么含义,Java如何实现跨平台的?
一次编译、处处可用
我们的程序只需要开发一次,就可以在各种安装了JVM的系统平台上运行。
1 | - 什么是JVM? |
- jdk的选择和安装
要使用Java,必须先安装什么?去哪里下载?
JDK (Java Development Kit)开发者工具包;Oracle官网。LTS版本有哪些?很多企业还在使用哪个JDK版本?
JDK 8、11、17;很多企业还在使用JDK8 / JDK 11。如何验证JDK是否安装成功了?
打开命令行窗口,输入java -version、javac -version看版本号。JDK中最重要的2个命令程序是什么?各自的作用是啥?
javac , java 。
编译工具,执行工具。
配置环境变量path
配置环境变量path的步骤
- 我的电脑–属性–高级系统设置–环境变量
- 增加JAVA_HOME环境变量,指向jdk的安装目录d:\program\hspjdk8
- 编辑path环境变量,增加%JAVA HOME%\bin
- 打开DOS命令行,任意目录下敲入javac/java。如果出现javac的参数信息,配置成功。
1 | 变量设置参数如下: |
什么是Path环境变量?
Path环境变量用于配置程序的路径。
方便我们在命令行窗口的任意目录启动程序。JDK安装时,环境变量需要注意什么?
较新版本的JDK会自动配置PATH环境变量,较老的JDK版本则不会。
建议还是自己配置一下”Path” 、“JAVA_HOME”
Java快速入门
要求开发一个Hello.java程序,可以输出”hello,world!”
编写Java程序的步骤
编写一个Java程序需要经过3个步骤:编写代码,编译代码,运行代码
- 编写代码:任何一个文本编辑器都可以些代码,如Windows系统自带的记事本
- 编译代码:将人能看懂的源代码(.java文件)转换为Java虚拟机能够执行的字节码文件(.class文件)
- 运行代码:将字节码文件交给Java虚拟机执行
● 运行原理示意图
1 | //这是java的快速入内,演示java的开发步骤 |
IDEA
要在IDEA正确的写一个Java程序,必须先认识一下IDEA的管理Java程序的工程结构。
- 第一步:首先得在IDEA中创建一个Project(工程、也叫项目),后面统称为工程。
- 第二步:需要在Project中创建Module(模块),一个工程中可以包含多个模块
- 第三步:需要在Module中新建Package(包),一个模块中可以有多个包
- 第四步:需要在Package中新建Class(类),一个包中可以包含多个类
软件工程其实类似于建筑工程,我们对比建筑工程来理解。
- Project(工程):你可以理解成小区的院子
- Module(模块):你可以理解成小区院子里面的每一栋楼
- Package(包):你可以理解成每一栋楼的一层
- Class(类):你可以理解成每一层的住户
快捷键 | 功能效果 |
---|---|
psvm、sout、… | 快速键入相关代码 |
Ctrl + D | 复制当前行数据到下一行 |
Ctrl + Y | 删除所在行,建议用Ctrl + X |
Ctrl + ALT + L | 格式化代码 |
ALT + SHIFT + ↑ , ALT + SHIFT + ↓ | 上下移动当前代码 |
Ctrl + / , Ctrl + Shift + / | 对代码进行注释 |
注释
用于注解说明解释程序的文字就是注释,注释提高了代码的阅读性
注释有哪几种?格式怎样?
1
2
3
4
5
6
7
8
9
10
11
121.单行注释:
//后面根解释文字
2.多行注释
/*
这里写注释文字
可以写多行
*/
3.文档注释
/**
这里写文档注释
也可以写多行,文档注释可以利用JDK的工具生成帮助文档
*/
再多学一招:每次手动加注释比较麻烦,也可以使用快捷键加注释
1 | Ctrl + / 单行注释(对当前行进行注释) |
字面量
- 编写程序,在命令行打印输出各种类型的字面值
1 | /* |
转义字符
1 | 在控制台,输入tab键,可以实现命令补全 |
变量
变量是程序的基本组成单位
Java 中主要有如下几种类型的变量
- 局部变量
- 类变量(静态变量)
- 成员变量(非静态变量)
变量是什么,变量的完整定义格式是什么样的?
用来存储一个数据的,本质是内存中的一块区域。
数据类型 变量名称 = 数据;为啥要用变量,变量有啥好处?
使用变量记要处理的数据,编写的代码更灵活,管理代码更方便。变量有什么特点?基于这个特点,变量有啥应用场景?
变量里装的数据可以被替换。
变量使用注意事项
- 变量表示内存中的一个存储区域[不同的变量,类型不同,占用的空间大小不同,比如: int 4个字节,double就是8个字节]
- 该区域有自己的名称[变量名]和类型[数据类型]
- 变量必须先声明,后使用,即有顺序
- 该区域的数据可以在同一类型范围内不断变化
- 变量在同一个作用域内不能重名
- 变量 = 变量名+值+数据类型,这一点请大家注意。
关键字
abstract | assert | boolean | break | byte |
---|---|---|---|---|
case | catch | char | class | const |
continue | default | do | double | else |
enum | extends | final | finally | float |
for | goto | if | implements | import |
instanceof | int | interface | long | native |
new | package | private | protected | public |
return | strictfp | short | static | super |
switch | synchronized | this | throw | throws |
transient | try | void | volatile | while |
1 | 关键字的特点: |
什么是关键字?
- 关键字就是Java自己要用到的词,并且有特殊含义的一些词。
- 我们就不能用来为做为: 类名、变量名,否则会报错!
什么是标识符?
- 标识符就是名字。
- 标识符的规则:由数字,字母,下划线,美元符等组成,且不能数字开头,不能用关键字做为名字
四种进制运算
进制
计算机的最小存储单位
计算机中最小的存储单位是字节(Byte),一个字节占8位(bit),也就是说即使这个数据不足8位也需要用8位来存储。
- 进制介绍
对于整数,有四种表示方式:
- 二进制:0,1,满2进1.以Ob或0B开头。
- 十进制:0-9,满10进1。
- 八进制:0-7,满8进1.以数字0开头表示。
- 十六进制:0-9及A(10)-F(15),满16进1.以Ox或0X开头表示。此处的A-F不区分大小写。
- 八进制、十六进制介绍
二进制转换成十进制示例
规则:从最低位(右边)开始,将每个位上的数提取出来,乘以2的(位数-1)次方,然后求和。
- 案例:请将0b1011转成十进制的数
0b1011 = 1 * 2的(1-1)次方+1 * 2的(2-1)次方+0 * 2的(3-1)次方+1 * 2的(4-1)次方法=1 +2+0 +8=11
八进制转换成十进制示例
规则:从最低位(右边)开始,将每个位上的数提取出来,乘以8的(位数-1)次方,然后求和。
- 案例:请将0234转成十进制的数
0234 =4 * 8个0 +3 * 8 ^ 1 +2 * 8 ^ 2= 4+24+ 128=156
十六进制转换成十进制示例
规则:从最低位(右边)开始,将每个位上的数提取出来,乘以16的(位数-1)次方,然后求和。
- 案例:请将0x23A转成十进制的数
0x23A = 10 * 16 ^ 0+ 3 * 16 ^ 1+2 * 16 ^ 2=10 + 48 + 512 = 570
十进制转换成二进制
规则:将该数不断除以2,直到商为0为止,然后将每步得到的余数倒过来,就是对应的二进制。
- 案例:请将34转成二进制= 0B00100010
十进制转换成八进制
规则:将该数不断除以8,直到商为0为止,然后将每步得到的余数倒过来,就是对应的八进制。
- 案例:请将131转成八进制=>0203
十进制转换成十六进制
规则:将该数不断除以16,直到商为0为止,然后将每步得到的余数倒过来,就是对应的十六进制。
- 案例:请将237转成十六进制=>OxED
二进制转换成八进制
规则:从低位开始,将二进制数每三位一组,转成对应的八进制数即可。
- 案例:请将ob11010101转成八进制
ob11(3)010(2)101(5) => 0325
二进制转换成十六进制
规则:从低位开始,将二进制数每四位一组,转成对应的十六进制数即可。
- 案例:请将ob11010101转成十六进制
ob1101(D)0101(5)= OxD5
八进制转换成二进制
规则:将八进制数每1位,转成对应的一个3位的二进制数即可。
- 案例:请将0237转成二进制
02(010)3(011)7(111)= 0b010011111
十六进制转换成二进制
规则:将十六进制数每1位,转成对应的4位的一个二进制数即可。
- 案例:请将0x23B转成二进制
0x2(0010)3(0011)B(1011) = 0b001000111011
原码、反码、补码
二进制在运算中的说明
- 二进制是逢2进位的进位制,0、1是基本算符。
- 现代的电子计算机技术全部采用的是二进制,因为它只使用0、1两个数字符号,非常简单方便,易于用电子方式实现。计算机内部处理的信息,都是采用二进制数来表示的。二进制(Binary)数用0和1两个数字及其组合来表示任何数。进位规则是”逢2进1”,数字1在不同的位上代表不同的值,按从右至左的次序,这个值以二倍递增
网上对原码,反码,补码的解释过于复杂,我这里精简几句话:0对于有符号的而言:
- 二进制的最高位是符号位:0表示正数,1表示负数(口诀:0->0 1->-)
- 正数的原码,反码,补码都一样(三码合一)
- 负数的反码 = 它的原码符号位不变,其它位取反(0->1,1->0)
- 负数的补码 = 它的反码+1,负数的反码 = 负数的补码-1
- 0的反码,补码都是0
- java没有无符号数,换言之,java中的数都是有符号的
- 在计算机运算的时候,都是以补码的方式来运算的.
- 当我们看运算结果的时候,要看他的原码
位运算符
java中有7个位运算(、^、~、>>、<<和>>>)
分别是按位与&、按位或|、按位异或^,按位取反~,它们的运算规则是;
按位与& 两位全为1,结果为1,否则为0
按位或| 两位有一个为1,结果为1,否则为0
按位异或^ 两位一个为0,一个为1,结果为1,否则为0
按位取反~ 0->1,1->0
还有3个位运算符>>、<<和>>>,运算规则:
- 算术右移>>:低位溢出,符号位不变,并用符号位补溢出的高位
- 算术左移<符号位不变,低位补0
>>>
逻辑右移也叫无符号右移,运算规则是:
低位溢出,高位补О4.特别说明:没有<<<符号
int a = 1>>2;
int c = 1<<2;
Java 基本数据类型
变量就是申请内存来存储值。也就是说,当创建变量的时候,需要在内存中申请空间。
内存管理系统根据变量的类型为变量分配存储空间,分配的空间只能用来储存该类型数据。
因此,通过定义不同类型的变量,可以在内存中储存整数、小数或者字符。
Java 的两大数据类型:
- 内置数据类型
- 引用数据类型
内置数据类型
Java语言提供了八种基本类型。六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型。
byte:
- byte 数据类型是8位、有符号的,以二进制补码表示的整数;
- 最小值是 -128(-2^7);
- 最大值是 127(2^7-1);
- 默认值是 0;
- byte 类型用在大型数组中节约空间,主要代替整数,因为 byte 变量占用的空间只有 int 类型的四分之一;
- 例子:byte a = 100,byte b = -50。
short:
- short 数据类型是 16 位、有符号的以二进制补码表示的整数
- 最小值是 -32768(-2^15);
- 最大值是 32767(2^15 - 1);
- Short 数据类型也可以像 byte 那样节省空间。一个short变量是int型变量所占空间的二分之一;
- 默认值是 0;
- 例子:short s = 1000,short r = -20000。
int:
- int 数据类型是32位、有符号的以二进制补码表示的整数;
- 最小值是 -2,147,483,648(-2^31);
- 最大值是 2,147,483,647(2^31 - 1);
- 一般地整型变量默认为 int 类型;
- 默认值是 0 ;
- 例子:int a = 100000, int b = -200000。
long:
- long 数据类型是 64 位、有符号的以二进制补码表示的整数;
- 最小值是 -9,223,372,036,854,775,808(-2^63);
- 最大值是 9,223,372,036,854,775,807(2^63 -1);
- 这种类型主要使用在需要比较大整数的系统上;
- 默认值是 0L;
- 例子: long a = 100000L,long b = -200000L。
“L”理论上不分大小写,但是若写成”l”容易与数字”1”混淆,不容易分辩。所以最好大写。
float:
- float 数据类型是单精度、32位、符合IEEE 754标准的浮点数;
- float 在储存大型浮点数组的时候可节省内存空间;
- 默认值是 0.0f;
- 浮点数不能用来表示精确的值,如货币;
- 例子:float f1 = 234.5f。
double:
double 数据类型是双精度、64 位、符合 IEEE 754 标准的浮点数;
浮点数的默认类型为 double 类型;
double类型同样不能表示精确的值,如货币;
默认值是 0.0d;
例子:
1
2
3
4
5double d1 = 7D ;
double d2 = 7.;
double d3 = 8.0;
double d4 = 8.D;
double d5 = 12.9867;7 是一个 int 字面量,而 7D,7. 和 8.0 是 double 字面量。
boolean:
- boolean数据类型表示一位的信息;
- 只有两个取值:true 和 false;
- 这种类型只作为一种标志来记录 true/false 情况;
- 默认值是 false;
- 例子:boolean one = true。
char:
- char 类型是一个单一的 16 位 Unicode 字符;
- 最小值是 \u0000(十进制等效值为 0);
- 最大值是 \uffff(即为 65535);
- char 数据类型可以储存任何字符;
- 例子:char letter = ‘A’;。
实例
对于数值类型的基本类型的取值范围,我们无需强制去记忆,因为它们的值都已经以常量的形式定义在对应的包装类中了。请看下面的例子:
1 | public class PrimitiveTypeTest { |
编译以上代码输出结果如下所示:
1 | 基本类型:byte 二进制位数:8 |
Float和Double的最小值和最大值都是以科学记数法的形式输出的,结尾的”E+数字”表示E之前的数字要乘以10的多少次方。比如3.14E3就是3.14 × 103 =3140,3.14E-3 就是 3.14 x 10-3 =0.00314。
实际上,JAVA中还存在另外一种基本类型 void,它也有对应的包装类 java.lang.Void,不过我们无法直接对它们进行操作。
类型默认值
下表列出了 Java 各个类型的默认值:
数据类型 | 默认值 |
---|---|
int | 0 |
long | 0L |
short | 0 |
char | ‘\u0000’ |
byte | 0 |
float | 0.0f |
double | 0.0d |
boolean | false |
引用类型(类、接口、数组) | null |
说明:
int
,short
,long
,byte
的默认值是0。char
的默认值是\u0000
(空字符)。float
的默认值是0.0f
。double
的默认值是0.0d
。boolean
的默认值是false
。- 引用类型(类、接口、数组)的默认值是
null
。
实例
1 | public class Test { |
实例输出结果为:
1 | Bool :false |
引用类型
- 在Java中,引用类型的变量非常类似于C/C++的指针。引用类型指向一个对象,指向对象的变量是引用变量。这些变量在声明时被指定为一个特定的类型,比如 Employee、Puppy 等。变量一旦声明后,类型就不能被改变了。
- 对象、数组都是引用数据类型。
- 所有引用类型的默认值都是null。
- 一个引用变量可以用来引用任何与之兼容的类型。
- 例子:Site site = new Site(“Runoob”)。
Java 常量
常量在程序运行时是不能被修改的。
在 Java 中使用 final 关键字来修饰常量,声明方式和变量类似:
1 | final double PI = 3.1415927; |
虽然常量名也可以用小写,但为了便于识别,通常使用大写字母表示常量。
字面量可以赋给任何内置类型的变量。例如:
1 | byte a = 68; |
byte、int、long、和short都可以用十进制、16进制以及8进制的方式来表示。
当使用字面量的时候,前缀 0 表示 8 进制,而前缀 0x 代表 16 进制, 例如:
1 | int decimal = 100; |
和其他语言一样,Java的字符串常量也是包含在两个引号之间的字符序列。下面是字符串型字面量的例子:
1 | "Hello World" |
字符串常量和字符变量都可以包含任何 Unicode 字符。例如:
1 | char a = '\u0001'; |
Java语言支持一些特殊的转义字符序列。
符号 | 字符含义 |
---|---|
\n | 换行 (0x0a) |
\r | 回车 (0x0d) |
\f | 换页符(0x0c) |
\b | 退格 (0x08) |
\0 | 空字符 (0x0) |
\s | 空格 (0x20) |
\t | 制表符 |
\“ | 双引号 |
\‘ | 单引号 |
\\ | 反斜杠 |
\ddd | 八进制字符 (ddd) |
\uxxxx | 16进制Unicode字符 (xxxx) |
自动类型转换
整型、实型(常量)、字符型数据可以混合运算。运算中,不同类型的数据先转化为同一类型,然后进行运算。
转换从低级到高级。
1 | 低 ------------------------------------> 高 |
数据类型转换必须满足如下规则:
1. 不能对boolean类型进行类型转换。
2. 不能把对象类型转换成不相关类的对象。
3. 在把容量大的类型转换为容量小的类型时必须使用强制类型转换。
4. 转换过程中可能导致溢出或损失精度,例如:
1
2int i =128;
byte b = (byte)i;因为 byte 类型是 8 位,最大值为127,所以当 int 强制转换为 byte 类型时,值 128 时候就会导致溢出。
5. 浮点数到整数的转换是通过舍弃小数得到,而不是四舍五入,例如:
1
2(int)23.7 == 23;
(int)-45.89f == -45
自动类型转换
必须满足转换前的数据类型的位数要低于转换后的数据类型,例如: short数据类型的位数为16位,就可以自动转换位数为32的int类型,同样float数据类型的位数为32,可以自动转换为64位的double类型。
- 实例
1
2
3
4
5
6
7
8
9
10public class ZiDongLeiZhuan{
public static void main(String[] args){
char c1='a';//定义一个char类型
int i1 = c1;//char自动类型转换为int
System.out.println("char自动类型转换为int后的值等于"+i1);
char c2 = 'A';//定义一个char类型
int i2 = c2+1;//char 类型和 int 类型计算
System.out.println("char类型和int计算后的值等于"+i2);
}
}
运行结果为:
1 | char自动类型转换为int后的值等于97 |
解析:c1 的值为字符 a ,查 ASCII 码表可知对应的 int 类型值为 97, A 对应值为 65,所以 i2=65+1=66。
强制类型转换
1. 条件是转换的数据类型必须是兼容的。
2. 格式:(type)value type是要强制类型转换后的数据类型 实例:
- 实例
1 | public class ForceTransform { |
运行结果:
1 | int强制类型转换为byte后的值等于123 |
隐含强制类型转换
1、 整数的默认类型是 int。
2. 小数默认是 double 类型浮点型,在定义 float 类型时必须在数字后面跟上 F 或者 f。
Java API文档
API (Application Programming Interface,应用程序编程接口)是Java提供的基本编程接口(java提供的类还有相关的方法)。
中文在线文档:https://www.matools.comJava语言提供了大量的基础类,因此 Oracle公司也为这些基础类提供了相应的API文档,用于告诉开发者如何使用这些类,以及这些类里包含的方法。
常用编码
- UTF-8是在互联网上使用最广的一种 Unicode的实现方式(改进)
- UTF-8是一种变长的编码方式。它可以使用1-6个字节表示一个符号,根据不同的符号而变化字节长度。
- 使用大小可变的编码字母占1个字节,汉字占3个字节
if语句;
while循环控制语句;
do-while循环控制语句;
for循环控制语句
String和基本类型转换
语法:将基本类型的值+””即可
- 在将String类型转成基本数据类型时,要确保String类型能够转成有效的数据,比·如我们可以把”123”,转成一个整数,但是不能把”hello”转成一个整数
- 如果格式不正确,就会抛出异常,程序就会终止,这个问题在异常处理章节中,会处理
Java 变量类型
在 Java 语言中,所有的变量在使用前必须声明。
声明变量的基本格式如下:
1 | type identifier \[ = value\]\[, identifier \[\= value\] ...\] ; |
格式说明:
- type – 数据类型。
- identifier – 是变量名,可以使用逗号 , 隔开来声明多个同类型变量。
以下列出了一些变量的声明实例。注意有些包含了初始化过程。
1 | int a, b, c; // 声明三个int型整数:a、 b、c |
Java 语言支持的变量类型有:
局部变量(Local Variables):局部变量是在方法、构造函数或块内部声明的变量,它们在声明的方法、构造函数或块执行结束后被销毁,局部变量在声明时需要初始化,否则会导致编译错误。
1
2
3
4public void exampleMethod() {
int localVar = 10; // 局部变量
// ...
}实例变量(Instance Variables):实例变量是在类中声明,但在方法、构造函数或块之外,它们属于类的实例,每个类的实例都有自己的副本,如果不明确初始化,实例变量会被赋予默认值(数值类型为0,boolean类型为false,对象引用类型为null)。
1
2
3public class ExampleClass {
int instanceVar; // 实例变量
}静态变量或类变量(Class Variables):类变量是在类中用 static 关键字声明的变量,它们属于类而不是实例,所有该类的实例共享同一个类变量的值,类变量在类加载时被初始化,而且只初始化一次。
1
2
3public class ExampleClass {
static int classVar; // 类变量
}参数变量(Parameters):参数是方法或构造函数声明中的变量,用于接收调用该方法或构造函数时传递的值,参数变量的作用域只限于方法内部。
1
2
3
4public void exampleMethod(int parameterVar) {
// 参数变量
// ...
}
以下实例中定义了一个 RunoobTest 类,其中包含了一个成员变量 instanceVar 和一个静态变量 staticVar。
method() 方法中定义了一个参数变量 paramVar 和一个局部变量 localVar。在方法内部,我们将局部变量的值赋给成员变量,将参数变量的值赋给静态变量,然后打印出这些变量的值。
在 main() 方法中,我们创建了一个 RunoobTest 对象,并调用了它的 method() 方法。
- 实例
1 | public class RunoobTest { |
运行以上代码,输出如下:
1 | 成员变量: 10 |
Java 参数变量
Java 中的参数变量是指在方法或构造函数中声明的变量,用于接收传递给方法或构造函数的值。参数变量与局部变量类似,但它们只在方法或构造函数被调用时存在,并且只能在方法或构造函数内部使用。
Java 方法的声明语法如下:
1 | accessModifier returnType methodName(parameterType parameterName1, parameterType parameterName2, ...) { |
- parameterType – 表示参数变量的类型。
- parameterName – 表示参数变量的名称。
在调用方法时,我们必须为参数变量传递值,这些值可以是常量、变量或表达式。
方法参数变量的值传递方式有两种:值传递和引用传递。
值传递:在方法调用时,传递的是实际参数的值的副本。当参数变量被赋予新的值时,只会修改副本的值,不会影响原始值。Java 中的基本数据类型都采用值传递方式传递参数变量的值。
引用传递:在方法调用时,传递的是实际参数的引用(即内存地址)。当参数变量被赋予新的值时,会修改原始值的内容。Java 中的对象类型采用引用传递方式传递参数变量的值。
以下是一个简单的例子,展示了方法参数变量的使用:
- 实例
1 | public class RunoobTest { |
运行以上代码,输出如下:
1 | a = 10, b = 20 |
Java 局部变量
Java 的局部变量是在方法、构造方法或语句块内部声明的变量,其作用域限制在声明它的代码块内部。
局部变量的声明语法为:
1 | type variableName; |
- type – 表示变量的类型。
- variableName – 表示变量的名称。
说明:
作用域:局部变量的作用域限于它被声明的方法、构造方法或代码块内。一旦代码执行流程离开这个作用域,局部变量就不再可访问。
生命周期:局部变量的生命周期从声明时开始,到方法、构造方法或代码块执行结束时终止。之后,局部变量将被垃圾回收。
初始化:局部变量在使用前必须被初始化。如果不进行初始化,编译器会报错,因为 Java 不会为局部变量提供默认值。
声明:局部变量的声明必须在方法或代码块的开始处进行。声明时可以指定数据类型,后面跟着变量名,例如:
int count;
。赋值:局部变量在声明后必须被赋值,才能在方法内使用。赋值可以是直接赋值,也可以是通过方法调用或表达式。
限制:局部变量不能被类的其他方法直接访问,它们只为声明它们的方法或代码块所私有。
内存管理:局部变量存储在 Java 虚拟机(JVM)的栈上,与存储在堆上的实例变量或对象不同。
垃圾回收:由于局部变量的生命周期严格限于方法或代码块的执行,它们在方法或代码块执行完毕后不再被引用,因此JVM的垃圾回收器会自动回收它们占用的内存。
重用:局部变量的名称可以在不同的方法或代码块中重复使用,因为它们的作用域是局部的,不会引起命名冲突。
参数和返回值:方法的参数可以视为一种特殊的局部变量,它们在方法被调用时初始化,并在方法返回后生命周期结束。
- 实例
1 | public class LocalVariablesExample { |
以上实例中我们声明并初始化了两个局部变量 a 和 b,然后打印出它们的值。注意,如果在使用局部变量之前不初始化它,编译器会报错。
在以下实例中 age 是一个局部变量,定义在 pupAge()方法中,它的作用域就限制在这个方法中:
1 | package com.runoob.test; |
以上实例编译运行结果如下:
1 | 小狗的年龄是: 7 |
在下面的例子中 age 变量没有初始化,所以在编译时会出错:
1 | package com.runoob.test; |
以上实例编译运行结果如下:
1 | Test.java:4:variable number might not have been initialized |
成员变量(实例变量)
- 成员变量声明在一个类中,但在方法、构造方法和语句块之外。
- 当一个对象被实例化之后,每个成员变量的值就跟着确定。
- 成员变量在对象创建的时候创建,在对象被销毁的时候销毁。
- 成员变量的值应该至少被一个方法、构造方法或者语句块引用,使得外部能够通过这些方式获取实例变量信息。
- 成员变量可以声明在使用前或者使用后。
- 访问修饰符可以修饰成员变量。
- 成员变量对于类中的方法、构造方法或者语句块是可见的。一般情况下应该把成员变量设为私有。通过使用访问修饰符可以使成员变量对子类可见。
- 成员变量具有默认值。数值型变量的默认值是0,布尔型变量的默认值是 false,引用类型变量的默认值是 null。变量的值可以在声明时指定,也可以在构造方法中指定;
- 成员变量可以直接通过变量名访问。但在静态方法以及其他类中,就应该使用完全限定名:ObjectReference.VariableName。
成员变量的声明语法为:
1 | accessModifier type variableName; |
- accessModifier –表示访问修饰符,可以是 public、protected、private 或默认访问级别(即没有显式指定访问修饰符)。
- type – 表示变量的类型。
- variableName – 表示变量的名称。
与局部变量不同,成员变量的值在创建对象时被分配,即使未对其初始化,它们也会被赋予默认值,例如 int 类型的变量默认值为 0,boolean 类型的变量默认值为 false。
成员变量可以通过对象访问,也可以通过类名访问(如果它们是静态成员变量)。如果没有显式初始化成员变量,则它们将被赋予默认值。可以在构造函数或其他方法中初始化成员变量,或者通过对象或类名访问它们并设置它们的值。
- 实例
以下实例我们声明了两个成员变量 a 和 b,并对其进行了访问和设置。注意,我们可以通过对象访问成员变量,也可以通过类名访问静态成员变量。
1 | public class RunoobTest { |
以上实例编译运行结果如下:
1 | a = 10 |
以下实例我们声明了两个成员变量 name 和 salary,并对其进行了访问和设置。
- Employee.java 文件代码:
1 | import java.io.*; |
以上实例编译运行结果如下:
1 | $ javac Employee.java |
类变量(静态变量)
Java 中的静态变量是指在类中定义的一个变量,它与类相关而不是与实例相关,即无论创建多少个类实例,静态变量在内存中只有一份拷贝,被所有实例共享。
静态变量在类加载时被创建,在整个程序运行期间都存在。
定义方式
静态变量的定义方式是在类中使用 static 关键字修饰变量,通常也称为类变量。
以下实例中我们定义一个静态变量 count ,其初始值为 0:
- 实例
1 | public class MyClass { |
访问方式
由于静态变量是与类相关的,因此可以通过类名来访问静态变量,也可以通过实例名来访问静态变量。
- 实例
1
2
3MyClass.count = 10; // 通过类名访问
MyClass obj = new MyClass();
obj.count = 20; // 通过实例名访问
生命周期
静态变量的生命周期与程序的生命周期一样长,即它们在类加载时被创建,在整个程序运行期间都存在,直到程序结束才会被销毁。因此,静态变量可以用来存储整个程序都需要使用的数据,如配置信息、全局变量等。
初始化时机
静态变量在类加载时被初始化,其初始化顺序与定义顺序有关。
如果一个静态变量依赖于另一个静态变量,那么它必须在后面定义。
- 实例上面的例子中,count1 要先于 count2 初始化,否则编译时会报错。
1
2
3
4
5public class MyClass {
public static int count1 = 0;
public static int count2 = count1 + 1;
// 其他成员变量和方法
}
常量和静态变量的区别
常量也是与类相关的,但它是用 final 关键字修饰的变量,一旦被赋值就不能再修改。与静态变量不同的是,常量在编译时就已经确定了它的值,而静态变量的值可以在运行时改变。另外,常量通常用于存储一些固定的值,如数学常数、配置信息等,而静态变量通常用于存储可变的数据,如计数器、全局状态等。
总之,静态变量是与类相关的变量,具有唯一性和共享性,可以用于存储整个程序都需要使用的数据,但需要注意初始化时机和与常量的区别。
静态变量的访问修饰符
静态变量的访问修饰符可以是 public、protected、private 或者默认的访问修饰符(即不写访问修饰符)。
需要注意的是,静态变量的访问权限与实例变量不同,因为静态变量是与类相关的,不依赖于任何实例。
静态变量的线程安全性
Java 中的静态变量是属于类的,而不是对象的实例。因此,当多个线程同时访问一个包含静态变量的类时,需要考虑其线程安全性。
静态变量在内存中只有一份拷贝,被所有实例共享。因此,如果一个线程修改了静态变量的值,那么其他线程在访问该静态变量时也会看到修改后的值。这可能会导致并发访问的问题,因为多个线程可能同时修改静态变量,导致不确定的结果或数据一致性问题。
为了确保静态变量的线程安全性,需要采取适当的同步措施,如同步机制、原子类或 volatile 关键字,以便在多线程环境中正确地读取和修改静态变量的值。
静态变量的命名规范
静态变量(也称为类变量)的命名规范通常遵循驼峰命名法,并且通常使用全大写字母,单词之间用下划线分隔,并且要用 static 关键字明确标识。
使用驼峰命名法: 静态变量的命名应该使用驼峰命名法,即首字母小写,后续每个单词的首字母大写。例如:
myStaticVariable
。全大写字母: 静态变量通常使用全大写字母,单词之间用下划线分隔。这被称为”大写蛇形命名法”(Upper Snake Case)。例如:
MY_STATIC_VARIABLE
。描述性: 变量名应该是有意义的,能够清晰地表达该变量的用途。避免使用单个字符或不具有明确含义的缩写。
避免使用缩写: 尽量避免使用缩写,以提高代码的可读性。如果使用缩写是必要的,确保广泛理解,并在注释中进行解释。
- 实例
1
2
3
4
5
6
7
8
9
10
11
12
13public class MyClass {
// 使用驼峰命名法
public static int myStaticVariable;
// 使用大写蛇形命名法
public static final int MAX_SIZE = 100;
// 避免使用缩写
public static final String employeeName;
// 具有描述性的变量名
public static double defaultInterestRate;
}
静态变量的使用场景
静态变量通常用于以下场景:
- 存储全局状态或配置信息
- 计数器或统计信息
- 缓存数据或共享资源
- 工具类的常量或方法
- 单例模式中的实例变量
- 实例
以下实例定义了一个 AppConfig 类,其中包含了三个静态变量 APP_NAME、APP_VERSION 和 DATABASE_URL,用于存储应用程序的名称、版本和数据库连接URL。这些变量都被声明为 final,表示它们是不可修改的常量。
在 main() 方法中,我们打印出了这些静态变量的值。
- AppConfig.java 文件代码:以上实例编译运行结果如下:
1
2
3
4
5
6
7
8
9
10
11public class AppConfig {
public static final String APP_NAME = "MyApp";
public static final String APP_VERSION = "1.0.0";
public static final String DATABASE_URL = "jdbc:mysql://localhost:3306/mydb";
public static void main(String[] args) {
System.out.println("Application name: " + AppConfig.APP_NAME);
System.out.println("Application version: " + AppConfig.APP_VERSION);
System.out.println("Database URL: " + AppConfig.DATABASE_URL);
}
}
1 | Application name: MyApp |
可以看到,这些静态变量存储的全局配置信息可以在整个程序中使用,并且不会被修改。这个例子展示了静态变量的另一个常见应用,通过它我们可以很方便地存储全局配置信息,或者实现其他需要全局共享的数据。
以下实例定义了一个 Counter 类,其中包含了一个静态变量 count,用于记录创建了多少个 Counter 对象。
每当创建一个新的对象时,构造方法会将计数器加一。静态方法 getCount() 用于获取当前计数器的值。
在 main() 方法中,我们创建了三个 Counter 对象,并打印出了计数器的值。
- Counter.java 文件代码:
1 | public class Counter { |
以上实例编译运行结果如下:
1 | 目前为止创建的对象数: 3 |
可以看到,计数器记录了创建了三个对象。这个例子展示了静态变量的一个简单应用,通过它我们可以很方便地统计对象的创建次数,或者记录其他需要全局共享的数据。
本章节中我们学习了Java的变量类型,下一章节中我们将介绍Java修饰符的使用。
Java 运算符
计算机的最基本用途之一就是执行数学运算,作为一门计算机语言,Java也提供了一套丰富的运算符来操纵变量。我们可以把运算符分成以下几组:
- 算术运算符
- 关系运算符
- 位运算符
- 逻辑运算符
- 赋值运算符
- 其他运算符
算术运算符
算术运算符用在数学表达式中,它们的作用和在数学中的作用一样。下表列出了所有的算术运算符。
表格中的实例假设整数变量A的值为10,变量B的值为20:
操作符 | 描述 | 例子 |
---|---|---|
+ | 加法 - 相加运算符两侧的值 | A + B 等于 30 |
- | 减法 - 左操作数减去右操作数 | A – B 等于 -10 |
* | 乘法 - 相乘操作符两侧的值 | A * B等于200 |
/ | 除法 - 左操作数除以右操作数 | B / A等于2 |
% | 取余 - 左操作数除以右操作数的余数 | B%A等于0 |
++ | 自增: 操作数的值增加1 | B++ 或 ++B 等于 21(区别详见下文) |
-- | 自减: 操作数的值减少1 | B– 或 –B 等于 19(区别详见下文) |
实例
下面的简单示例程序演示了算术运算符。复制并粘贴下面的 Java 程序并保存为 Test.java 文件,然后编译并运行这个程序:
实例
1 | 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) ); } } |
以上实例编译运行结果如下:
1 | a + b = 30 |
自增自减运算符
1、自增(++)自减(–)运算符是一种特殊的算术运算符,在算术运算符中需要两个操作数来进行运算,而自增自减运算符是一个操作数。
实例
public class selfAddMinus{ public static void main(String[] args){ int a = 3;//定义一个变量; int b = ++a;//自增运算 int c = 3; int d = –c;//自减运算 System.out.println(“进行自增运算后的值等于”+b); System.out.println(“进行自减运算后的值等于”+d); } }
运行结果为:
1 | 进行自增运算后的值等于4 |
解析:
int b = ++a; 拆分运算过程为: a=a+1=4; b=a=4, 最后结果为b=4,a=4
int d = –c; 拆分运算过程为: c=c-1=2; d=c=2, 最后结果为d=2,c=2
2、前缀自增自减法(++a,–a): 先进行自增或者自减运算,再进行表达式运算。
3、后缀自增自减法(a++,a–): 先进行表达式运算,再进行自增或者自减运算 实例:
实例
public class selfAddMinus{ public static void main(String[] args){ int a = 5;//定义一个变量; int b = 5; int x = 2*++a; int y = 2*b++; System.out.println(“自增运算符前缀运算后a=”+a+”,x=”+x); System.out.println(“自增运算符后缀运算后b=”+b+”,y=”+y); } }
运行结果为:
1 | 自增运算符前缀运算后a=6,x=12 |
关系运算符
下表为Java支持的关系运算符
表格中的实例整数变量A的值为10,变量B的值为20:
运算符 | 描述 | 例子 |
---|---|---|
== | 检查如果两个操作数的值是否相等,如果相等则条件为真。 | (A == B)为假。 |
!= | 检查如果两个操作数的值是否相等,如果值不相等则条件为真。 | (A != B) 为真。 |
> | 检查左操作数的值是否大于右操作数的值,如果是那么条件为真。 | (A> B)为假。 |
< | 检查左操作数的值是否小于右操作数的值,如果是那么条件为真。 | (A <B)为真。 |
>= | 检查左操作数的值是否大于或等于右操作数的值,如果是那么条件为真。 | (A> = B)为假。 |
<= | 检查左操作数的值是否小于或等于右操作数的值,如果是那么条件为真。 | (A <= B)为真。 |
实例
下面的简单示例程序演示了关系运算符。复制并粘贴下面的Java程序并保存为Test.java文件,然后编译并运行这个程序:
Test.java 文件代码:
public class Test { public static void main(String[] args) { int a = 10; int b = 20; System.out.println(“a == b = “ + (a == b) ); 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) ); } }
以上实例编译运行结果如下:
1 | a == b = false |
位运算符
Java定义了位运算符,应用于整数类型(int),长整型(long),短整型(short),字符型(char),和字节型(byte)等类型。
位运算符作用在所有的位上,并且按位运算。假设a = 60,b = 13;它们的二进制格式表示将如下:
1 | A = 0011 1100 |
下表列出了位运算符的基本运算,假设整数变量 A 的值为 60 和变量 B 的值为 13:
操作符 | 描述 | 例子 |
---|---|---|
& | 如果相对应位都是1,则结果为1,否则为0 | (A&B),得到12,即0000 1100 |
如果相对应位都是 0,则结果为 0,否则为 1 | ||
^ | 如果相对应位值相同,则结果为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即0000 1111 |
实例
下面的简单示例程序演示了位运算符。复制并粘贴下面的Java程序并保存为Test.java文件,然后编译并运行这个程序:
Test.java 文件代码:
public class Test { public static void main(String[] args) { int a = 60; /* 60 = 0011 1100 */ int b = 13; /* 13 = 0000 1101 */ int c = 0; c = a & b; /* 12 = 0000 1100 */ System.out.println(“a & b = “ + c ); c = a | b; /* 61 = 0011 1101 */ System.out.println(“a | b = “ + c ); c = a ^ b; /* 49 = 0011 0001 */ System.out.println(“a ^ b = “ + c ); c = a; /*-61 = 1100 0011 */ System.out.println(“a = “ + c ); c = a << 2; /* 240 = 1111 0000 */ System.out.println(“a << 2 = “ + c ); c = a >> 2; /* 15 = 1111 */ System.out.println(“a >> 2 = “ + c ); c = a >>> 2; /* 15 = 0000 1111 */ System.out.println(“a >>> 2 = “ + c ); } }
以上实例编译运行结果如下:
1 | a & b = 12 |
逻辑运算符
下表列出了逻辑运算符的基本运算,假设布尔变量A为真,变量B为假
操作符 | 描述 | 例子 |
---|---|---|
&& | 称为逻辑与运算符。当且仅当两个操作数都为真,条件才为真。 | (A && B)为假。 |
! | 称为逻辑非运算符。用来反转操作数的逻辑状态。如果条件为true,则逻辑非运算符将得到false。 | !(A && B)为真。 |
实例
下面的简单示例程序演示了逻辑运算符。复制并粘贴下面的Java程序并保存为Test.java文件,然后编译并运行这个程序:
实例
public class Test { public static void main(String[] args) { boolean a = true; boolean b = false; System.out.println(“a && b = “ + (a&&b)); System.out.println(“a || b = “ + (a||b) ); System.out.println(“!(a && b) = “ + !(a && b)); } }
以上实例编译运行结果如下:
1 | a && b = false |
短路逻辑运算符
当使用与逻辑运算符时,在两个操作数都为true时,结果才为true,但是当得到第一个操作为false时,其结果就必定是false,这时候就不会再判断第二个操作了。
实例
public class LuoJi{ public static void main(String[] args){ int a = 5;//定义一个变量; boolean b = (a<4)&&(a++<10); System.out.println(“使用短路逻辑运算符的结果为”+b); System.out.println(“a的结果为”+a); } }
运行结果为:
1 | 使用短路逻辑运算符的结果为false |
解析: 该程序使用到了短路逻辑运算符(&&),首先判断 a<4 的结果为 false,则 b 的结果必定是 false,所以不再执行第二个操作 a++<10 的判断,所以 a 的值为 5。
赋值运算符
下面是Java语言支持的赋值运算符:
操作符 | 描述 | 例子 |
---|---|---|
= | 简单的赋值运算符,将右操作数的值赋给左侧操作数 | C = A + B将把A + B得到的值赋给C |
+ = | 加和赋值操作符,它把左操作数和右操作数相加赋值给左操作数 | C + = A等价于C = C + A |
- = | 减和赋值操作符,它把左操作数和右操作数相减赋值给左操作数 | C - = A等价于C = C - A |
* = | 乘和赋值操作符,它把左操作数和右操作数相乘赋值给左操作数 | C * = A等价于C = C * A |
/ = | 除和赋值操作符,它把左操作数和右操作数相除赋值给左操作数 | C / = A,C 与 A 同类型时等价于 C = C / A |
(%)= | 取模和赋值操作符,它把左操作数和右操作数取模后赋值给左操作数 | C%= A等价于C = C%A |
<< = | 左移位赋值运算符 | C << = 2等价于C = C << 2 |
>> = | 右移位赋值运算符 | C >> = 2等价于C = C >> 2 |
&= | 按位与赋值运算符 | C&= 2等价于C = C&2 |
^ = | 按位异或赋值操作符 | C ^ = 2等价于C = C ^ 2 |
= | 按位或赋值操作符 |
实例
下面的简单示例程序演示了赋值运算符。复制并粘贴下面的Java程序并保存为Test.java文件,然后编译并运行这个程序:
Test.java 文件代码:
public class Test { public static void main(String[] args) { int a = 10; int b = 20; int c = 0; c = a + b; System.out.println(“c = a + b = “ + c ); c += a ; System.out.println(“c += a = “ + c ); c -= a ; System.out.println(“c -= a = “ + c ); c *= a ; System.out.println(“c *= a = “ + c ); a = 10; c = 15; c /= a ; System.out.println(“c /= a = “ + c ); a = 10; c = 15; c %= a ; System.out.println(“c %= a = “ + c ); c <<= 2 ; System.out.println(“c <<= 2 = “ + c ); c >>= 2 ; System.out.println(“c >>= 2 = “ + c ); c >>= 2 ; System.out.println(“c >>= 2 = “ + c ); c &= a ; System.out.println(“c &= a = “ + c ); c ^= a ; System.out.println(“c ^= a = “ + c ); c |= a ; System.out.println(“c |= a = “ + c ); } }
以上实例编译运行结果如下:
1 | c = a + b = 30 |
条件运算符(?:)
条件运算符也被称为三元运算符。该运算符有3个操作数,并且需要判断布尔表达式的值。该运算符的主要是决定哪个值应该赋值给变量。
1 | variable x = (expression) ? value if true : value if false |
实例
Test.java 文件代码:
public class Test { public static void main(String[] args){ int a , b; a = 10; // 如果 a 等于 1 成立,则设置 b 为 20,否则为 30 b = (a == 1) ? 20 : 30; System.out.println( “Value of b is : “ + b ); // 如果 a 等于 10 成立,则设置 b 为 20,否则为 30 b = (a == 10) ? 20 : 30; System.out.println( “Value of b is : “ + b ); } }
以上实例编译运行结果如下:
1 | Value of b is : 30 |
instanceof 运算符
该运算符用于操作对象实例,检查该对象是否是一个特定类型(类类型或接口类型)。
instanceof运算符使用格式如下:
1 | ( Object reference variable ) instanceof (class/interface type) |
如果运算符左侧变量所指的对象,是操作符右侧类或接口(class/interface)的一个对象,那么结果为真。
下面是一个例子:
1 | String name = "James"; |
如果被比较的对象兼容于右侧类型,该运算符仍然返回 true。
看下面的例子:
class Vehicle {} public class Car extends Vehicle { public static void main(String[] args){ Vehicle a = new Car(); boolean result = a instanceof Car; System.out.println( result); } }
以上实例编译运行结果如下:
1 | true |
Java运算符优先级
当多个运算符出现在一个表达式中,谁先谁后呢?这就涉及到运算符的优先级别的问题。在一个多运算符的表达式中,运算符优先级不同会导致最后得出的结果差别甚大。
例如,(1+3)+(3+2)*2,这个表达式如果按加号最优先计算,答案就是 18,如果按照乘号最优先,答案则是 14。
再如,x = 7 + 3 * 2;这里x得到13,而不是20,因为乘法运算符比加法运算符有较高的优先级,所以先计算3 * 2得到6,然后再加7。
下表中具有最高优先级的运算符在的表的最上面,最低优先级的在表的底部。
类别 | 操作符 | 关联性 |
---|---|---|
后缀 | () [] . (点操作符) | 左到右 |
一元 | expr++ expr– | 从左到右 |
一元 | ++expr –expr + - ~ ! | 从右到左 |
乘性 | * /% | 左到右 |
加性 | + - | 左到右 |
移位 | >> >>> << | 左到右 |
关系 | > >= < <= | 左到右 |
相等 | == != | 左到右 |
按位与 | & | 左到右 |
按位异或 | ^ | 左到右 |
按位或 | ||
逻辑与 | && | 左到右 |
逻辑或 | ||
条件 | ?: | 从右到左 |
赋值 | = + = - = * = / =%= >> = << =&= ^ = | = |
逗号 | , | 左到右 |
运算符
运算符就是参与运算的符号。Java提供的运算符有很多种,可以分为算术下面几种
- 基本算术运算符
- 自增自减运算符
- 赋值运算符
- 关系运算符
- 逻辑运算符
- 三元运算符
- 程序中+号的使用
- 当左右两边都是数值型时,则做加法运算
- 当左右两边有一方为字符串,则做拼接运算
1
2
3
4
5#下面代码输出什么?
System.out.println(100 + 98); //198
System.out.println("100"+ 98); //10098
System.out.println(100 + 3+ "hello"); //103hello
System.out.println("hello"+ 100 +3); //hello1003
算术运算符
算术运算符有 + - * / %
,其中*
表示乘法,/
表示除法,%
表示取余数
需要我们注意的是:+
符号除了用于加法运算,还可以作为连接符。**+
符号与字符串运算的时候是用作连接符的,其结果依然是一个字符串**。
下面通过代码演示一下各种算术运算符的运算效果
1 | public class OperatorDemo1 { |
自增自减运算符
- 面试题1
1 | int i=1; //i->1 |
问:结果是多少?为什么?
- 面试题2
1 | int i=1; |
- 练习2
1 | int i1 = 10; |
- 练习3
1 | //(1)先定义一个double huaShi变量保存华氏温度 |
赋值运算符
1 | 1.基本赋值运算符: |
关系运算符
- 关系运算符的结果都是boolean型,也就是要么是true,要么是false
- 关系表达式经常用在if结构的条件电或循环结构的条件中
逻辑运算符
逻辑运算符一览
说明逻辑运算规则:
- a&b :&叫逻辑与:规则:当a和 b同时为true ,则结果为true,否则为false
- a&&b : &&叫短路与:规则:当a和 b同时为true ,则结果为true,否则为false
- a|b:|叫逻辑或,规则:当a和b,有一个为true ,则结果为true,否则为false
- a || b:||叫短路或,规则:当a和b,有一个为true ,则结果为true,否则为false
- !a :叫取反,或者非运算。当a为true,则结果为false,当a为false是,结果为true
- a^b :叫逻辑异或,当a和b 不同时,则结果为true,否则为false
开发中基本使用 && 和 ||
三元运算符
基本语法
1 | 关系表达式? 值1 : 值2; |
条件表达式 ? 表达式1 : 表达式2;
运算规则:
- 如果条件表达式为true,运算后的结果是表达式1;
- 如果条件表达式为false,运算后的结果是表达式2;
API介绍、Scanner
API是什么?API文档是什么?
Application Programming Interface,应用程序编程接口:Java写好的程序,咱们可以直接调用。
Java提供的程序使用说明书。Java程序中如何实现接收用户键盘输入的数据?
使用Java提供的Scanner来完成,步骤如下:
1、导包: import java.util.Scanner;
2、抄代码得到扫描器对象: Scanner sc = new Scanner(System.in)
3、抄代码等待接收用户输入的数据:
int age = sc.nextint()string name = sc.next()
1 | public class ScannerDemo1 { |
程序流程控制
顺序控制
程序的流程控制一般分为3种:顺序结构、分支结构、循环结构
顺序结构:就是不加任何控制,代码从main方法开始自上而下执行
分支结构:就是根据条件判断是true还是false,有选择性的执行哪些代码。在Java语言中提供了两个格式if 、 switch
循环结构:就是控制某一段代码重复执行。在Java语言中提供了三种格式,for、while、do-while
分支控制
单分支使用
分支控制if-else
单分支
基本语法
if(条件表达式){
执行代码块;(可以有多条语句.)
}
分支控制if-else
双分支
基本语法
if(条件表达式){执行代码块1;}
else {
执行代码块2;
}
说明:当条件表达式成立,即执行代码块1,否则执行代码块2如果执行代码块只有一条语句,则可以省略,否则,不能省略
多分支使用
多分支
基本语法
if(条件表达式1){
执行代码块1;
}
else if(条件表达式2){
执行代码块2;
}
.……….
else{
执行代码块n;
}
特别说明:
(1)多分支可以没有else,如果所有的条件表达式都不成立,则一个执行入口都没有
(2)如果有else ,如果所有的条件表达式都不成立,则默认执行else代码块
嵌套分支
在一个分支结构中又完整的嵌套了另一个完整的分支结构,里面的分支的结构称为内层分支外面的分支结构称为外层分支。建议:不要超过3层(可读性不好)
基本语法
if(){
if(){
//if-else….
}else{
//if-else
}
}
switch分支结构
基本语法
switch(表达式){
case常量1: //当
语句块1;
break;
case常量2;
语句块2;
break;
…
case常量n;
语句块n;
break;
default:
default语句块
;break;
}
1 | - 1.表达式类型只能是byte、short、int、char |
解读switch
- switch关键字,表示swtich分支
- 表达式对应一个值
- case常量1:当表达式的值等于常量1,就执行语句块1
- break :表示退出swtich
- 如果和case常量1匹配,就执行语句块1,如果没有匹配。就继续匹配case常量2
- 如果一个都没有匹配上,执行default
switch分支结构
- 表达式数据类型,应和case后的常量类型一致,或者是可以自动转成可以相互比较的类型,比如输入的是字符,而常量是int
- switch(表达式)中表达式的返回值必须是:(byte,short,int,char,enum,String)
1 | double c = 1.1; |
- case子句中的值必须是常量,而不能是变量
- default子句是可选的,当没有匹配的case时,执行default
- break语句用来在执行完一个case分支后使程序跳出switch语句块;如果没有写break,程序会顺序执行到switch结尾
switch和if选择
- 如果判断的具体数值不多,而且符合byte、short、int、char, enum, String这6种类型。虽然两个语句都可以使用,建议使用swtich语句。
- 其他情况:对区间判断,对结果为boolean类型判断,使用if,if的使用范围更广
for循环控制
基本语法
1 | //for循环格式: |
说明
- for关键字,表示循环控制
- for有四要素:(1)循环变量初始化(2)循环条件(3)循环操作(4)循环变量迭代
- 循环操作,这里可以有多条语句,也就是我们要循环执行的代码
- 如果循环操作(语句)只有一条语句,可以省略{},建议不要省略
- 注意事项和细节说明
- 循环条件是返回一个布尔值的表达式
- for(;循环判断条件;)中的初始化和变量迭代可以写到其它地方,但是两边的分号不能省略。
- 循环初始值可以有多条初始化语句,但要求类型一样,并且中间用逗号隔开,
循环变量迭代也可以有多条变量迭代语句,中间用逗号隔开。 - 使用内存分析法,老师分析输出下面代码输出什么?
1 | int count = 3; |
i = 0 j = 0
i = 1 j = 2
i = 2 j = 4
while基本语法
基本语法
循环变量初始化;
while(循环条件){
循环体(语句);
循环变量迭代;
}
do..while循环控制
基本语法
循环变量初始化;
do{
循环体(语句);
循环变量迭代;
}while(循环条件);
1 | int i = 0; |
说明:
- do while是关键字
- 也有循环四要素,只是位置不一样
- 先执行,再判断,也就是说,一定会至少执行一次
- 最后有一个分号;
- while和do..while区别举例:要账
多重循环执行流程
介绍
将一个循环放在另一个循环体内,就形成了嵌套循环。其中,for while ,do…while均可以作为外层循环和内层循环。最多不要超过3层
实质上,嵌套循环就是把内层循环当成外层循环的循环体。当只有内层循环的循环条件为false时,才会完全跳出内层循环,才可结束外层的当次循环,开始下一次的循环。
设外层循环次数为m次,内层为n次,则内层循环体实际上需要执行m*n次。
1 | for( int i= 1;i<= 7; i++){ //第一层循环 7 |
三种循环的区别总结
1 | 1. for循环 和 while循环(先判断后执行); |
死循环
1 | //for死循环 |
跳转控制语句-break
- break作用:跳出并结束当前所在循环的执行
- continue作用:结束本次循环,进入下一次循环
基本介绍:
break语句用于终止某个语句块的执行,一般使用在switch或者循环[for , while ,do-while]中基本语法:
{ ….
break
….;
}
- 跳转控制语句:break
注意事项和细节说明:
break语句出现在多层嵌套的语句块中时,可以通过标签指明要终止的是哪一层语句块
标签的基本使用
标签的基本使用
1 | label1: { .... |
(1)break语句可以指定退出哪层
(2)label1是标签,由程序员指定。
(3) break后指定到哪个label 就退出到哪里
(4)在实际的开发中,尽量不要使用标签,
(5)如果没有指定break,默认退出最近的循环体
1 | lable1: |
跳转控制语句-continue
基本介绍:
- continue语句用于结束本次循环,继续执行下一次循环。
- continue语句出现在多层嵌套的循环语句体中时,可以通过标签指明要跳过的是哪一层循环,这个和前面的标签的使用的规则一样.
基本语法:
{ ….
continue;
….
}
跳转控制语句-continue
1 | label1: |
跳转控制语句-return
return使用在方法,表示跳出所在的方法,在讲解方法的时候,会详细的介绍,这里我们简单的提一下。
注意:如果return写在main方法,退出程序..
1 | for(int i=1;i<=5;i++){ |
本章作业
- 判断一个整数是否是水仙花数,所谓水仙花数是指一个3位数,其各个位上数字立方和等于其本身。例如:153 = 111 +333+555
1 | int n = 15; |
输出1-100之间的不能被5整除的数,每5个一行
1
2
3
4
5
6
7
8
9
10
11int count = 0;//统计输出的个数
for(int i = 1; i <= 100; i++) {
if(i % 5 !=) {
count++;
System.out.print(i+" r");
//判断,每满5个,就输出一个换行..
if(count % 5 == ) {
System.out.println();
}
}
}输出小写的a-z以及大写的Z-A
1 | for(char c1 = 'a'; c1 <= 'z'; c1++) { |
- 求出1-1/2+1/3-1/4…..1/100的和
1 | double sum = 0; |
- 求1+(1+2)+(1+2+3)+(1+2+3+4) +….+(1+2+3+..+100)的结果
1
2
3
4
5
6
7int sum = ;
for(int i = 1; i <= 100; i++){
for(int j = 1;j <= i; j++){//内层对1-i进行循环
sum += j;
}
}
System.out.println( "sum=" + sum);
数组
数组的必要性
- 数组可以存放多个同一类型的数据。数组也是一种数据类型,是引用类型。
即:数组就是一组数据
数组有两种初始化的方式,一种是静态初始化、一种是动态初始化。
使用方式1 动态初始化
语法:数据类型 数组名;也可以数据类型[] 数组名;
int a[];或者int[] a;
创建数组
语法:数组名 = new 数据类型[大小];
a = new int[10];
1 | //(1)第一种动态分配方式 |
数组动态初始化案例
1 | 案例需求: |
代码如下
1 | // 1、定义一个动态初始化的数组,负责后期存储6个评委的打分。 |
使用方式2-静态初始化
所谓静态初始化指的是:在定义数组时直接给数组中的数据赋值。
静态初始化标准格式:
1 | 数据类型[] 变量名 = new 数据类型[]{元素1,元素2,元素3}; |
按照格式定义int类型、double类型数组
1 | //定义数组,用来存储多个年龄 |
静态初始化简化格式
1 | 数据类型[] 变量名 = {元素1,元素2,元素3}; |
使用简化格式定义int类型、double类型数组
1 | //定义数组,用来存储多个年龄 |
数组静态初始化案例
1 | 需求:某部门5名员工的销售额分别是:16、26、36、6、100,请计算出他们部门的总销售额。 |
按照分析的思路来写代码
1 | // 1、定义一个数组存储5名员工的销售额 |
数组使用注意事项和细节
数组是多个相同类型数据的组合,实现对这些数据的统一管理
数组中的元素可以是任何数据类型,包括基本类型和引用类型,但是不能混用。
数组创建后,如果没有赋值,有默认值
int 0, short O, byte 0, long 0,
float 0.0,double 0.0, char \u0000,
boolean false,String null使用数组的步骤1.声明数组并开辟空间2给数组各个元素赋值3使用数组
数组的下标是从O开始的。
数组下标必须在指定范围内使用,否则报:下标越界异常,比如
int[]arr=new int[5];则有效下标为0-4数组属引用类型,数组型数据是对象(object)
动态初始化数组的写法是什么样的?有什么特点?
数据类型 [数组名] = new 数据类型 [长度];
int[] ages = new int[4];
- 动态初始化数组后元素的默认值是什么样的?
- byte、short、int , char、long类型数组的元素默认值都是0
- float、double类型数组元素的默认值都是0.0
- boolean类型数组的元素默认值是false、string类型数组的元素的默认值是null
- 两种数组定义的方法各自适合什么业务场景?
- 动态初始化:适合开始不确定具体元素值,只知道元素个数的业务场景。
- 静态初始化:适合一开始就知道要存入哪些元素值的业务场景。
- 多个数组变量,指向同一个数组对象的原因是什么?需要注意什么?
- 多个数组变量中存储的是同一个数组对象的地址。
- 多个变量修改的都是同一个数组对象中的数据。
- 如果某个数组变量中存储的null,代表什么意思?需要注意什么?
- 代表这个数组变量没有指向数组对象。
- 可以输出这个变量,但是不能用这个数组变量去访问数据或者访问数组长度,会报空指针异常:NullPointerException。
数组遍历
所谓遍历意思就是将数组中的元素一个一个的取出来。
1 | int[] ages = {12, 24, 36}; |
数组的执行原理,Java程序的执行原理
Java为了便于虚拟机执行Java程序,将虚拟机的内存划分为 方法区、栈、堆、本地方法栈、寄存器 这5块区域。同学们需要重点关注的是 方法区、栈、堆。
- 方法区:字节码文件先加载到这里
- 栈:方法运行时所进入的内存区域,由于变量在方法中,所以变量也在这一块区域中
- 堆:存储new出来的东西,并分配地址。由于数组是new 出来的,所以数组也在这块区域。
总结一下int a = 10
与 int[] arr = new int[]{11,22,33}的区别
- a是一个变量,在栈内存中,a变量中存储的数据就是10这个值。
- arr也是一个变量,在栈中,存储的是数组对象在堆内存中的地址值
1 | // 这里的int a是一个基本类型变量,存储的是一个数值 |
数组练习1
1 | char[] chars = new char[26]; |
数组练习2
1 | int[] arr = {4,-1,9}; |
数组赋值机制
基本数据类型赋值,这个值就是具体的数据,而且相互不影响。
int n1 = 2;
int n2 = n1;数组在默认情况下是引用传递,赋的值是地址。
int[]arr1 ={1,2,3};
int[]arr2 = arr1;
数组求最值
1 | 需求:定义一个int类型数组,求数组中元素的最大值,并打印最大值 |
1 | 数组求最大值思路: |
1 | public class Test1 { |
总结一下:
通过这个案例,我们主要掌握求最值的思路,以后不管遇到求最大值还是最小值,编程思路都是一样的,不同的可能是数据不同。
数组反转
1 | 需求:某个数组有5个数据:10,20,30,40,50,请将这个数组中的数据进行反转。 |
1 | 1.每次交换,需要有左右两边的两个索引,我们可以用i和j表示 |
具体代码如下
1 | public class Test2 { |
总结一下:
通过上面的案例,需要我们掌握元素互换位置的编程思路;以后遇到数据互换问题,都这样做。
数组扩容
要求:实现动态的给数组添加元素效果,实现对数组扩容。
原始数组使用静态分配int[] arr = {1,2,3}
增加的元素,直接放在数组的最后arr = {1,2,3.4}
用户可以通过如下方法来决定是否继续添加,添加成功,是否继续? y/n
有一个数组{1,2,3,4,5},可以将该数组进行缩减,提示用户是否继续缩减,每次缩减最后哪个元素。当只剩下最后一个元素,提示,不能再缩减。
1 | int[] arr = {1,2,3}; |
排序介绍
排序的介绍
排序是将一群数据,依指定的顺序进行排列的过程。排序的分类:
- 内部排序:
指将需要处理的所有数据都加载到内部存储器中进行排序。包括(交换式排序法、选择式排序法和插入式排序法); - 外部排序法:
数据量过大,无法全部加载到内存中,需要借助外部存储进行排序。包括(合并排序法和直接合并排序法)。
- 冒泡排法
冒泡排序(Bubble Sorting)的基本思想是:通过对待排序序列从后向前(从下标较大的元素开始),依次比较相邻元素的值,若发现逆序则交换,使值较
大的元素逐渐从前移向后部,就象水底下的气泡一样逐渐向上冒。
冒泡排序法案例:
下面我们举一个具体的案例来说明冒泡法。我们将五个无序:
24,69,80,57,13使用冒泡排序法将其排成一个从小到大的有序数列。
1 | int[]arr = {24,69,80,57,13}; |
查找
介绍:
在java中,我们常用的查找有两种:
- 顺序查找 SeqSearch.java
- 二分查找【二分法,我们放在算法讲解】
案例演示:
- 有一个数列:白眉鹰王、金毛狮王、紫衫龙王、青翼蝠王猜数游戏:
从键盘中任意输入一个名称,判断数列中是否包含此名称【顺序查找】要求:如果找到了,就提示找到,并给出下标值。 - 请对一个有序数组进行二分查找{1,8,10,89,1000,1234},输入一个数看看该数组是否存在此数,并且求出下标,如果没有就提示”没有这个数”。
1 | //定义一个字符串数组 |
二维数组
1 | //1.从定义形式上看int[][] |
二维数组的使用
使用方式1:动态初始化
- 语法:类型[][]数组名=new类型[大小][大小]
- 比如: int a[][]=new int[2][3]
- 二维数组在内存的存在形式
使用方式2:动态初始化
- 先声明:类型数组名[][];
- 再定义(开辟空间)数组名=new类型[大小][大小]
- 赋值(有默认值,比如int类型的就是0)
使用方式3:动态初始化-列数不确定
- 看一个需求:动态创建下面二维数组,并输出。
1 |
|
使用方式4:静态初始化
定义类型数组名[][] ={ {值1,值2.},{值1,值2.},{值1,值2.} }
使用即可[固定方式访问]
比如:
int[][]arr = { {1,1,1},{8.8,9},{100} };定义了一个二维数组arr
arr有三个元素(每个元素都是一维数组)
第一个一维数组有3个元素,第二个一维数组有3个元素,第三个一维数组有1个元素
二维数组的应用案例
- 使用二维数组打印一个10行杨辉三角
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5
1……
【提示】
- 第一行有1个元素,第n行有n个元素
- 每一行的第一个元素和最后一个元素都是1
- 从第三行开始,对于非第一个元素和最后一个元素的元素的值.
arr[i][j] = arr[i-1][j] + arr[i-1][j-1];
1 | int[][]yangHui = new int[10][]; |
二维数组使用细节和注意事项
一维数组的声明方式有:
int[]x或者int x[]二维数组的声明方式有:
int[][] y 或者int[] y[]或者int y[][]二维数组实际上是由多个一维数组组成的,它的各个一维数组的长度可以相同,也可以不相同。比如: map[][]是一个二维数组
int map [][]= { {1,2},{3,4,53} }
由map[0]是一个含有两个元素的一维数组,map[1]是一个含有三个元素的一维数组构成,我们也称为列数不等的二维数组。
Debug调试工具
Debug调试工具的使用步骤如下:
1 | 第一步:打断点,如下图的红色小圆点 |
Java 对象和类
Java 作为一种面向对象的编程语言,支持以下基本概念:
1、类(Class):
- 定义对象的蓝图,包括属性和方法。
- 示例:
public class Car { ... }
2、对象(Object):
- 类的实例,具有状态和行为。
- 示例:
Car myCar = new Car();
3、继承(Inheritance):
- 一个类可以继承另一个类的属性和方法。
- 示例:
public class Dog extends Animal { ... }
4、封装(Encapsulation):
将对象的状态(字段)私有化,通过公共方法访问。
示例:
1
2private String name;
public String getName() { return name; }
5、多态(Polymorphism):
- 对象可以表现为多种形态,主要通过方法重载和方法重写实现。
- 示例:
- 方法重载:
public int add(int a, int b) { ... }
和public double add(double a, double b) { ... }
- 方法重写:
@Override public void makeSound() { System.out.println("Meow"); }
- 方法重载:
6、抽象(Abstraction):
- 使用抽象类和接口来定义必须实现的方法,不提供具体实现。
- 示例:
- 抽象类:
public abstract class Shape { abstract void draw(); }
- 接口:
public interface Animal { void eat(); }
- 抽象类:
7、接口(Interface):
- 定义类必须实现的方法,支持多重继承。
- 示例:
public interface Drivable { void drive(); }
8、方法(Method):
- 定义类的行为,包含在类中的函数。
- 示例:
public void displayInfo() { System.out.println("Info"); }
9、方法重载(Method Overloading):
同一个类中可以有多个同名的方法,但参数不同。
示例:
1
2
3
4
5
6
7
8
9public class MathUtils {
public int add(int a, int b) {
return a + b;
}
public double add(double a, double b) {
return a + b;
}
}
本节我们重点研究对象和类的概念。
- 对象:对象是类的一个实例(对象不是找个女朋友),有状态和行为。例如,一条狗是一个对象,它的状态有:颜色、名字、品种;行为有:摇尾巴、叫、吃等。
- 类:类是一个模板,它描述一类对象的行为和状态。
下图中汽车为类(class),而具体的每辆车为该汽车类的对象(object),对象包含了汽车的颜色、品牌、名称等。
Java中的对象
现在让我们深入了解什么是对象。看看周围真实的世界,会发现身边有很多对象,车,狗,人等等。所有这些对象都有自己的状态和行为。
拿一条狗来举例,它的状态有:名字、品种、颜色,行为有:叫、摇尾巴和跑。
对比现实对象和软件对象,它们之间十分相似。
软件对象也有状态和行为。软件对象的状态就是属性,行为通过方法体现。
在软件开发中,方法操作对象内部状态的改变,对象的相互调用也是通过方法来完成。
Java 中的类
类可以看成是创建 Java 对象的模板。
通过上图创建一个简单的类来理解下 Java 中类的定义:
1 | public class Dog { |
一个类可以包含以下类型变量:
- 局部变量:在方法、构造方法或者语句块中定义的变量被称为局部变量。变量声明和初始化都是在方法中,方法结束后,变量就会自动销毁。
- 成员变量:成员变量是定义在类中,方法体之外的变量。这种变量在创建对象的时候实例化。成员变量可以被类中方法、构造方法和特定类的语句块访问。
- 类变量:类变量也声明在类中,方法体之外,但必须声明为 static 类型。
一个类可以拥有多个方法,在上面的例子中:eat()、run()、sleep() 和 name() 都是 Dog 类的方法。
构造方法
每个类都有构造方法。如果没有显式地为类定义构造方法,Java 编译器将会为该类提供一个默认构造方法。
在创建一个对象的时候,至少要调用一个构造方法。构造方法的名称必须与类同名,一个类可以有多个构造方法。
下面是一个构造方法示例:
1 | public class Puppy { |
创建对象
对象是根据类创建的。在Java中,使用关键字 new 来创建一个新的对象。创建对象需要以下三步:
- 声明:声明一个对象,包括对象名称和对象类型。
- 实例化:使用关键字 new 来创建一个对象。
- 初始化:使用 new 创建对象时,会调用构造方法初始化对象。
下面是一个创建对象的例子:
1 | public class Puppy { |
编译并运行上面的程序,会打印出下面的结果:
1 | 小狗的名字是 : tommy |
访问实例变量和方法
通过已创建的对象来访问成员变量和成员方法,如下所示:
1 | /\* 实例化对象 \*/ |
使用 Object 类型声明变量只能在编译时访问 Object 类中的方法和属性,但在运行时,你可以通过强制类型转换将其转换为特定类型,以便访问特定类型的方法和属性。
- 实例
下面的例子展示如何访问实例变量和调用成员方法:
- Puppy.java 文件代码:编译并运行上面的程序,产生如下结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41public class Puppy {
private int age;
private String name;
// 构造器
public Puppy(String name) {
this.name = name;
System.out.println("小狗的名字是 : " + name);
}
// 设置 age 的值
public void setAge(int age) {
this.age = age;
}
// 获取 age 的值
public int getAge() {
return age;
}
// 获取 name 的值
public String getName() {
return name;
}
// 主方法
public static void main(String[] args) {
// 创建对象
Puppy myPuppy = new Puppy("Tommy");
// 通过方法来设定 age
myPuppy.setAge(2);
// 调用另一个方法获取 age
int age = myPuppy.getAge();
System.out.println("小狗的年龄为 : " + age);
// 也可以直接访问成员变量(通过 getter 方法)
System.out.println("变量值 : " + myPuppy.getAge());
}
}
1 | 小狗的名字是 : tommy |
源文件声明规则
在本节的最后部分,我们将学习源文件的声明规则。当在一个源文件中定义多个类,并且还有import语句和package语句时,要特别注意这些规则。
- 一个源文件中只能有一个 public 类
- 一个源文件可以有多个非 public 类
- 源文件的名称应该和 public 类的类名保持一致。例如:源文件中 public 类的类名是 Employee,那么源文件应该命名为Employee.java。
- 如果一个类定义在某个包中,那么 package 语句应该在源文件的首行。
- 如果源文件包含 import 语句,那么应该放在 package 语句和类定义之间。如果没有 package 语句,那么 import 语句应该在源文件中最前面。
- import 语句和 package 语句对源文件中定义的所有类都有效。在同一源文件中,不能给不同的类不同的包声明。
类有若干种访问级别,并且类也分不同的类型:抽象类和 final 类等。这些将在访问控制章节介绍。
除了上面提到的几种类型,Java 还有一些特殊的类,如:内部类、匿名类。
Java 包
包主要用来对类和接口进行分类。当开发 Java 程序时,可能编写成百上千的类,因此很有必要对类和接口进行分类。
import 语句
在 Java 中,如果给出一个完整的限定名,包括包名、类名,那么 Java 编译器就可以很容易地定位到源代码或者类。import 语句就是用来提供一个合理的路径,使得编译器可以找到某个类。
例如,下面的命令行将会命令编译器载入 java_installation/java/io 路径下的所有类
1 | import java.io.*; |
例子
在该例子中,我们创建两个类:Employee 和 EmployeeTest。
首先打开代码编辑器,把下面的代码粘贴进去,将文件保存为 Employee.java。
Employee 类有四个成员变量:name、age、designation 和 salary,该类显式声明了一个构造方法,该方法只有一个参数。
- Employee.java 文件代码:Java 程序都是从 main 方法开始执行,为了能运行这个程序,必须包含 main 方法并且创建一个实例对象。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57import java.io.*;
public class Employee {
private String name;
private int age;
private String designation;
private double salary;
// Employee 类的构造器
public Employee(String name) {
this.name = name;
}
// 设置 age 的值
public void setAge(int age) {
this.age = age;
}
// 获取 age 的值
public int getAge() {
return age;
}
// 设置 designation 的值
public void setDesignation(String designation) {
this.designation = designation;
}
// 获取 designation 的值
public String getDesignation() {
return designation;
}
// 设置 salary 的值
public void setSalary(double salary) {
this.salary = salary;
}
// 获取 salary 的值
public double getSalary() {
return salary;
}
// 打印信息
public void printEmployee() {
System.out.println(this);
}
// 重写 toString 方法
public String toString() {
return "名字: " + name + "\n" +
"年龄: " + age + "\n" +
"职位: " + designation + "\n" +
"薪水: " + salary;
}
}
下面给出 EmployeeTest 类,该类实例化 2 个 Employee 类的实例,并调用方法设置变量的值。
将下面的代码保存在 EmployeeTest.java文件中。
- EmployeeTest.java 文件代码:编译这两个文件并且运行 EmployeeTest 类,可以看到如下结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20import java.io.*;
public class EmployeeTest {
public static void main(String[] args) {
// 使用构造器创建两个对象
Employee empOne = new Employee("RUNOOB1");
Employee empTwo = new Employee("RUNOOB2");
// 调用这两个对象的成员方法
empOne.setAge(26);
empOne.setDesignation("高级程序员");
empOne.setSalary(1000);
empOne.printEmployee();
empTwo.setAge(21);
empTwo.setDesignation("菜鸟程序员");
empTwo.setSalary(500);
empTwo.printEmployee();
}
}
1 | $ javac EmployeeTest.java Employee.java |