Java

java能做什么

1
2
3
4
5
6
7
8
9
10
11
12
13
14
1.Java是什么?
答:Java是一门高级编程语言

2.Java是哪家公司的产品?
答:Java以前是Sun公司的产品,现在Java是属于Oracle公司的产品

3.Java之父是谁?
答:詹姆斯●高斯林

4.Java主流的开发方向是什么?
答:企业级互联网应用开发

5.Java技术平台有哪些?
答:JavaSE(标准版)、JavaEE(企业版)、JavaME(小型版)

Java特性

  1. Java语言是面向对象的(oop)

  2. Java语言是健壮的。Java的强类型机制、异常处理、垃圾的自动收集等是Java程序健壮性的重要保证

  3. Java语言是跨平台性的。[即:一个编译好的.class文件可以在多个系统下运行,这种特性称为跨平台]从而做到一处编译,处处运行

  4. Java语言是解释型的
    解释性语言:javascript,PHP,java 编译性语言:c/c++

区别是:解释性语言,编译后的代码,不能直接被机器执行,需要解释器来执行;编译性语言,编译后的代码,可以直接被机器执行, c/c++

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
1.Java 语言是简单的:
Java 语言的语法与 C 语言和 C++ 语言很接近,使得大多数程序员很容易学习和使用。另一方面,Java 丢弃了 C++ 中很少使用的、很难理解的、令人迷惑的那些特性,如操作符重载、多继承、自动的强制类型转换。特别地,Java 语言不使用指针,而是引用。并提供了自动分配和回收内存空间,使得程序员不必为内存管理而担忧。

2.Java 语言是面向对象的:
Java 语言提供类、接口和继承等面向对象的特性,为了简单起见,只支持类之间的单继承,但支持接口之间的多继承,并支持类与接口之间的实现机制(关键字为 implements)。Java 语言全面支持动态绑定,而 C++语言只对虚函数使用动态绑定。总之,Java语言是一个纯的面向对象程序设计语言。

3.Java语言是分布式的:
Java 语言支持 Internet 应用的开发,在基本的 Java 应用编程接口中有一个网络应用编程接口(java net),它提供了用于网络应用编程的类库,包括 URL、URLConnection、Socket、ServerSocket 等。Java 的 RMI(远程方法激活)机制也是开发分布式应用的重要手段。

4.Java 语言是健壮的:
Java 的强类型机制、异常处理、垃圾的自动收集等是 Java 程序健壮性的重要保证。对指针的丢弃是 Java 的明智选择。Java 的安全检查机制使得 Java 更具健壮性。

5.Java语言是安全的:
Java通常被用在网络环境中,为此,Java 提供了一个安全机制以防恶意代码的攻击。除了Java 语言具有的许多安全特性以外,Java 对通过网络下载的类具有一个安全防范机制(类 ClassLoader),如分配不同的名字空间以防替代本地的同名类、字节代码检查,并提供安全管理机制(类 SecurityManager)让 Java 应用设置安全哨兵。

6.Java 语言是体系结构中立的:
Java 程序(后缀为 java 的文件)在 Java 平台上被编译为体系结构中立的字节码格式(后缀为 class 的文件),然后可以在实现这个 Java 平台的任何系统中运行。这种途径适合于异构的网络环境和软件的分发。

7.Java 语言是可移植的:
这种可移植性来源于体系结构中立性,另外,Java 还严格规定了各个基本数据类型的长度。Java 系统本身也具有很强的可移植性,Java 编译器是用 Java 实现的,Java 的运行环境是用 ANSI C 实现的。

8.Java 语言是解释型的:
如前所述,Java 程序在 Java 平台上被编译为字节码格式,然后可以在实现这个 Java 平台的任何系统中运行。在运行时,Java 平台中的 Java 解释器对这些字节码进行解释执行,执行过程中需要的类在联接阶段被载入到运行环境中。

9.Java 是高性能的:
与那些解释型的高级脚本语言相比,Java 的确是高性能的。事实上,Java 的运行速度随着 JIT(Just-In-Time)编译器技术的发展越来越接近于 C++。

10.Java 语言是多线程的:
在 Java 语言中,线程是一种特殊的对象,它必须由 Thread 类或其子(孙)类来创建。通常有两种方法来创建线程:其一,使用型构为 Thread(Runnable) 的构造子类将一个实现了 Runnable 接口的对象包装成一个线程,其二,从 Thread 类派生出子类并重写 run 方法,使用该子类创建的对象即为线程。值得注意的是 Thread 类已经实现了 Runnable 接口,因此,任何一个线程均有它的 run 方法,而 run 方法中包含了线程所要运行的代码。线程的活动由一组方法来控制。Java 语言支持多个线程的同时执行,并提供多线程之间的同步机制(关键字为 synchronized)。

11.Java 语言是动态的:
Java 语言的设计目标之一是适应于动态变化的环境。Java 程序需要的类能够动态地被载入到运行环境,也可以通过网络来载入所需要的类。这也有利于软件的升级。另外,Java 中的类有一个运行时刻的表示,能进行运行时刻的类型检查。

jdk介绍

  • JDK的下载

这是JDK下载的官方网址 https://www.oracle.com/java/technologies/downloads/

  • JDK、JRE和JVM的包含关系
  1. JDK = JRE +开发工具集(例如Javac,java编译工具等)
  2. JRE = JVM + Java SE标准类库(java核心类库)
  3. 如果只想运行开发好的.class文件只需要JRE

Java的跨平台是什么含义,Java如何实现跨平台的?
一次编译、处处可用
我们的程序只需要开发一次,就可以在各种安装了JVM的系统平台上运行。

1
2
3
4
5
6
7
8
9
10
11
12
- 什么是JVM?
答:JDK最核心的组成部分是JVM(Java Virtual Machine),它是Java虚拟机,真正运行Java程序的地方。一次编译,到处运行

- 什么是核心类库?
答:它是Java本身写好的一些程序,给程序员调用的。 Java程序员并不是凭空开始写代码,是要基于核心类库提供的一些基础代码,进行编程。

- 什么是JRE?
答:JRE(Java Runtime Enviroment),意思是Java的运行环境;它是由JVM和核心类库组成的;如果你不是开发人员,只需要在电脑上安装JRE就可以运行Java程序。

- 什么是开发工具呢?
答:Java程序员写好源代码之后,需要编译成字节码,这里会提供一个编译工具叫做javac.exe,编写好源代码之后,想要把class文件加载到内存中运行,这里需要用到运行工具java.exe。
除了编译工具和运行工具,还有一些其他的反编译工具、文档工具等待...
  • jdk的选择和安装
  1. 要使用Java,必须先安装什么?去哪里下载?
    JDK (Java Development Kit)开发者工具包;Oracle官网。

  2. LTS版本有哪些?很多企业还在使用哪个JDK版本?
    JDK 8、11、17;很多企业还在使用JDK8 / JDK 11。

  3. 如何验证JDK是否安装成功了?
    打开命令行窗口,输入java -version、javac -version看版本号。

  4. JDK中最重要的2个命令程序是什么?各自的作用是啥?
    javac , java 。
    编译工具,执行工具。

配置环境变量path

配置环境变量path的步骤

  1. 我的电脑–属性–高级系统设置–环境变量
  2. 增加JAVA_HOME环境变量,指向jdk的安装目录d:\program\hspjdk8
  3. 编辑path环境变量,增加%JAVA HOME%\bin
  4. 打开DOS命令行,任意目录下敲入javac/java。如果出现javac的参数信息,配置成功。
1
2
3
4
5
6
7
8
9
10
变量设置参数如下:

变量名:JAVA_HOME
变量值:C:\Program Files (x86)\Java\jdk1.8.0_91 // 要根据自己的实际路径配置

变量名:CLASSPATH
变量值:.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar; //记得前面有个"."

变量名:Path
变量值:%JAVA_HOME%\bin; %JAVA_HOME%\jre\bin;
  1. 什么是Path环境变量?
    Path环境变量用于配置程序的路径。
    方便我们在命令行窗口的任意目录启动程序。

  2. JDK安装时,环境变量需要注意什么?
    较新版本的JDK会自动配置PATH环境变量,较老的JDK版本则不会。
    建议还是自己配置一下”Path” 、“JAVA_HOME”

Java快速入门

要求开发一个Hello.java程序,可以输出”hello,world!”

编写Java程序的步骤

编写一个Java程序需要经过3个步骤:编写代码,编译代码,运行代码

  • 编写代码:任何一个文本编辑器都可以些代码,如Windows系统自带的记事本
  • 编译代码:将人能看懂的源代码(.java文件)转换为Java虚拟机能够执行的字节码文件(.class文件)
  • 运行代码:将字节码文件交给Java虚拟机执行

● 运行原理示意图

1
2
3
4
5
6
7
8
9
10
11
12
13
//这是java的快速入内,演示java的开发步骤
public class Hello {
//编写一个main方法
public static void main(string[] args) {
System.out.println( "hello,world~");
}
//1. public class Hello表示Hello是一个类,是一个public公有的类
//2.Hello{ } 表示一个类的开始和结束
//3. public static void main(String[] args)表示一个主方法,即我们程序的入口
//4. main(){}表示方法的开始和结束
//5. System.out.println( "hello,world~" );表示输出"hello, world~"到屏幕
//6.;表示语句结束
}

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
    12
    1.单行注释:
    //后面根解释文字
    2.多行注释
    /*
    这里写注释文字
    可以写多行
    */
    3.文档注释
    /**
    这里写文档注释
    也可以写多行,文档注释可以利用JDK的工具生成帮助文档
    */

再多学一招:每次手动加注释比较麻烦,也可以使用快捷键加注释

1
2
Ctrl + / 	单行注释(对当前行进行注释)
Ctrl + Shift + / 对选中的代码进行多行注释。

字面量

  • 编写程序,在命令行打印输出各种类型的字面值
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
/*
目标:掌握常见数据在程序中的书写格式
*/
public class LiteralDemo{
public static void main(String[] args){
//1.整数
System.out.println(666);

//2.小数
System.out.println(3.66);

//3.字符: 字符必须用单引号引起来
System.out.println('a');
System.out.println('0');
System.out.println('中');
System.out.println(' '); //空格也算字符

//特殊字符:\t表示制表符 \n表示换行
System.out.println('\t'); //这相当于一个tab键,专业叫做制表符
System.out.println('\n'); //这是换行的意思

//4.字符串:字符串是双引号引起来的
System.out.println("我爱你中国abc");

//5.布尔值:只有两个值true和false
System.out.println(true);
System.out.println(false);
}
}

转义字符

1
2
3
4
5
6
7
在控制台,输入tab键,可以实现命令补全
1) \t :一个制表位,实现对齐的功能
2) \n :换行符
3) \\ :一个\
4) \" :一个"
5) \' :一个'
6) \r :一个回车 System.out.println("教育\r北京");

变量

变量是程序的基本组成单位

Java 中主要有如下几种类型的变量

  • 局部变量
  • 类变量(静态变量)
  • 成员变量(非静态变量)
  1. 变量是什么,变量的完整定义格式是什么样的?
    用来存储一个数据的,本质是内存中的一块区域。
    数据类型 变量名称 = 数据;

  2. 为啥要用变量,变量有啥好处?
    使用变量记要处理的数据,编写的代码更灵活,管理代码更方便。

  3. 变量有什么特点?基于这个特点,变量有啥应用场景?
    变量里装的数据可以被替换。

变量使用注意事项

  1. 变量表示内存中的一个存储区域[不同的变量,类型不同,占用的空间大小不同,比如: int 4个字节,double就是8个字节]
  2. 该区域有自己的名称[变量名]和类型[数据类型]
  3. 变量必须先声明,后使用,即有顺序
  4. 该区域的数据可以在同一类型范围内不断变化
  5. 变量在同一个作用域内不能重名
  6. 变量 = 变量名+值+数据类型,这一点请大家注意。

关键字

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
2
3
关键字的特点:
1.关键字都是小写的
2.关键字在idea中有特殊颜色标记(如果你没有修改关键字的颜色,默认是蓝色的)

什么是关键字?

  • 关键字就是Java自己要用到的词,并且有特殊含义的一些词。
  • 我们就不能用来为做为: 类名、变量名,否则会报错!

    什么是标识符?

  • 标识符就是名字。
  • 标识符的规则:由数字,字母,下划线,美元符等组成,且不能数字开头,不能用关键字做为名字

四种进制运算

进制

计算机的最小存储单位

计算机中最小的存储单位是字节(Byte),一个字节占8位(bit),也就是说即使这个数据不足8位也需要用8位来存储。

  • 进制介绍
    对于整数,有四种表示方式:
  1. 二进制:0,1,满2进1.以Ob或0B开头
  2. 十进制:0-9,满10进1。
  3. 八进制:0-7,满8进1.以数字0开头表示
  4. 十六进制: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

原码、反码、补码

二进制在运算中的说明

  1. 二进制是逢2进位的进位制,0、1是基本算符
  2. 现代的电子计算机技术全部采用的是二进制,因为它只使用0、1两个数字符号,非常简单方便,易于用电子方式实现。计算机内部处理的信息,都是采用二进制数来表示的。二进制(Binary)数用0和1两个数字及其组合来表示任何数。进位规则是”逢2进1”,数字1在不同的位上代表不同的值,按从右至左的次序,这个值以二倍递增

网上对原码,反码,补码的解释过于复杂,我这里精简几句话:0对于有符号的而言:

  1. 二进制的最高位是符号位:0表示正数,1表示负数(口诀:0->0 1->-)
  2. 正数的原码,反码,补码都一样(三码合一)
  3. 负数的反码 = 它的原码符号位不变,其它位取反(0->1,1->0)
  4. 负数的补码 = 它的反码+1,负数的反码 = 负数的补码-1
  5. 0的反码,补码都是0
  6. java没有无符号数,换言之,java中的数都是有符号的
  7. 在计算机运算的时候,都是以补码的方式来运算的.
  8. 当我们看运算结果的时候,要看他的原码

位运算符

java中有7个位运算(、^、~、>>、<<和>>>)

分别是按位与&、按位或|、按位异或^,按位取反~,它们的运算规则是;

按位与& 两位全为1,结果为1,否则为0
按位或| 两位有一个为1,结果为1,否则为0
按位异或^ 两位一个为0,一个为1,结果为1,否则为0
按位取反~ 0->1,1->0

还有3个位运算符>>、<<和>>>,运算规则:

  1. 算术右移>>:低位溢出,符号位不变,并用符号位补溢出的高位
  2. 算术左移<符号位不变,低位补0
  3. >>>逻辑右移也叫无符号右移,运算规则是:
    低位溢出,高位补О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
    5
    double   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
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
public class PrimitiveTypeTest {  
public static void main(String[] args) {
// byte
System.out.println("基本类型:byte 二进制位数:" + Byte.SIZE);
System.out.println("包装类:java.lang.Byte");
System.out.println("最小值:Byte.MIN_VALUE=" + Byte.MIN_VALUE);
System.out.println("最大值:Byte.MAX_VALUE=" + Byte.MAX_VALUE);
System.out.println();

// short
System.out.println("基本类型:short 二进制位数:" + Short.SIZE);
System.out.println("包装类:java.lang.Short");
System.out.println("最小值:Short.MIN_VALUE=" + Short.MIN_VALUE);
System.out.println("最大值:Short.MAX_VALUE=" + Short.MAX_VALUE);
System.out.println();

// int
System.out.println("基本类型:int 二进制位数:" + Integer.SIZE);
System.out.println("包装类:java.lang.Integer");
System.out.println("最小值:Integer.MIN_VALUE=" + Integer.MIN_VALUE);
System.out.println("最大值:Integer.MAX_VALUE=" + Integer.MAX_VALUE);
System.out.println();

// long
System.out.println("基本类型:long 二进制位数:" + Long.SIZE);
System.out.println("包装类:java.lang.Long");
System.out.println("最小值:Long.MIN_VALUE=" + Long.MIN_VALUE);
System.out.println("最大值:Long.MAX_VALUE=" + Long.MAX_VALUE);
System.out.println();

// float
System.out.println("基本类型:float 二进制位数:" + Float.SIZE);
System.out.println("包装类:java.lang.Float");
System.out.println("最小值:Float.MIN_VALUE=" + Float.MIN_VALUE);
System.out.println("最大值:Float.MAX_VALUE=" + Float.MAX_VALUE);
System.out.println();

// double
System.out.println("基本类型:double 二进制位数:" + Double.SIZE);
System.out.println("包装类:java.lang.Double");
System.out.println("最小值:Double.MIN_VALUE=" + Double.MIN_VALUE);
System.out.println("最大值:Double.MAX_VALUE=" + Double.MAX_VALUE);
System.out.println();

// char
System.out.println("基本类型:char 二进制位数:" + Character.SIZE);
System.out.println("包装类:java.lang.Character");
// 以数值形式而不是字符形式将Character.MIN_VALUE输出到控制台
System.out.println("最小值:Character.MIN_VALUE="
+ (int) Character.MIN_VALUE);
// 以数值形式而不是字符形式将Character.MAX_VALUE输出到控制台
System.out.println("最大值:Character.MAX_VALUE="
+ (int) Character.MAX_VALUE);
}
}

编译以上代码输出结果如下所示:

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
基本类型:byte 二进制位数:8
包装类:java.lang.Byte
最小值:Byte.MIN_VALUE=-128
最大值:Byte.MAX_VALUE=127

基本类型:short 二进制位数:16
包装类:java.lang.Short
最小值:Short.MIN_VALUE=-32768
最大值:Short.MAX_VALUE=32767

基本类型:int 二进制位数:32
包装类:java.lang.Integer
最小值:Integer.MIN_VALUE=-2147483648
最大值:Integer.MAX_VALUE=2147483647

基本类型:long 二进制位数:64
包装类:java.lang.Long
最小值:Long.MIN_VALUE=-9223372036854775808
最大值:Long.MAX_VALUE=9223372036854775807

基本类型:float 二进制位数:32
包装类:java.lang.Float
最小值:Float.MIN_VALUE=1.4E-45
最大值:Float.MAX_VALUE=3.4028235E38

基本类型:double 二进制位数:64
包装类:java.lang.Double
最小值:Double.MIN_VALUE=4.9E-324
最大值:Double.MAX_VALUE=1.7976931348623157E308

基本类型:char 二进制位数:16
包装类:java.lang.Character
最小值:Character.MIN_VALUE=0
最大值:Character.MAX_VALUE=65535

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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class Test {
static boolean bool;
static byte by;
static char ch;
static double d;
static float f;
static int i;
static long l;
static short sh;
static String str;

public static void main(String[] args) {
System.out.println("Bool :" + bool);
System.out.println("Byte :" + by);
System.out.println("Character:" + ch);
System.out.println("Double :" + d);
System.out.println("Float :" + f);
System.out.println("Integer :" + i);
System.out.println("Long :" + l);
System.out.println("Short :" + sh);
System.out.println("String :" + str);
}
}

实例输出结果为:

1
2
3
4
5
6
7
8
9
Bool     :false
Byte :0
Character:
Double :0.0
Float :0.0
Integer :0
Long :0
Short :0
String :null

引用类型

  • 在Java中,引用类型的变量非常类似于C/C++的指针。引用类型指向一个对象,指向对象的变量是引用变量。这些变量在声明时被指定为一个特定的类型,比如 Employee、Puppy 等。变量一旦声明后,类型就不能被改变了。
  • 对象、数组都是引用数据类型。
  • 所有引用类型的默认值都是null。
  • 一个引用变量可以用来引用任何与之兼容的类型。
  • 例子:Site site = new Site(“Runoob”)。

Java 常量

常量在程序运行时是不能被修改的。

在 Java 中使用 final 关键字来修饰常量,声明方式和变量类似:

1
final double PI = 3.1415927;

虽然常量名也可以用小写,但为了便于识别,通常使用大写字母表示常量。

字面量可以赋给任何内置类型的变量。例如:

1
2
byte a = 68;
char a = 'A'

byte、int、long、和short都可以用十进制、16进制以及8进制的方式来表示。

当使用字面量的时候,前缀 0 表示 8 进制,而前缀 0x 代表 16 进制, 例如:

1
2
3
int decimal = 100;
int octal = 0144;
int hexa = 0x64;

和其他语言一样,Java的字符串常量也是包含在两个引号之间的字符序列。下面是字符串型字面量的例子:

1
2
3
"Hello World"
"two\nlines"
"\"This is in quotes\""

字符串常量和字符变量都可以包含任何 Unicode 字符。例如:

1
2
char a = '\u0001';
String a = "\u0001";

Java语言支持一些特殊的转义字符序列。

符号 字符含义
\n 换行 (0x0a)
\r 回车 (0x0d)
\f 换页符(0x0c)
\b 退格 (0x08)
\0 空字符 (0x0)
\s 空格 (0x20)
\t 制表符
\“ 双引号
\‘ 单引号
\\ 反斜杠
\ddd 八进制字符 (ddd)
\uxxxx 16进制Unicode字符 (xxxx)

自动类型转换

整型、实型(常量)、字符型数据可以混合运算。运算中,不同类型的数据先转化为同一类型,然后进行运算。

转换从低级到高级。

1
2
3
低  ------------------------------------>  高

byte,short,char—> int —> long—> float —> double

数据类型转换必须满足如下规则:

  • 1. 不能对boolean类型进行类型转换。

  • 2. 不能把对象类型转换成不相关类的对象。

  • 3. 在把容量大的类型转换为容量小的类型时必须使用强制类型转换。

  • 4. 转换过程中可能导致溢出或损失精度,例如:

    1
    2
    int 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
    10
    public 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
2
char自动类型转换为int后的值等于97
char类型和int计算后的值等于66

解析:c1 的值为字符 a ,查 ASCII 码表可知对应的 int 类型值为 97, A 对应值为 65,所以 i2=65+1=66。

强制类型转换

  • 1. 条件是转换的数据类型必须是兼容的。

  • 2. 格式:(type)value type是要强制类型转换后的数据类型 实例:

  • 实例
1
2
3
4
5
6
7
public class ForceTransform {
public static void main(String[] args){
int i1 = 123;
byte b = (byte)i1;//强制类型转换为byte
System.out.println("int强制类型转换为byte后的值等于"+b);
}
}

运行结果:

1
int强制类型转换为byte后的值等于123

隐含强制类型转换

  • 1、 整数的默认类型是 int。

  • 2. 小数默认是 double 类型浮点型,在定义 float 类型时必须在数字后面跟上 F 或者 f。

Java API文档

  1. API (Application Programming Interface,应用程序编程接口)是Java提供的基本编程接口(java提供的类还有相关的方法)。
    中文在线文档:https://www.matools.com

  2. Java语言提供了大量的基础类,因此 Oracle公司也为这些基础类提供了相应的API文档,用于告诉开发者如何使用这些类,以及这些类里包含的方法。

常用编码

  1. UTF-8是在互联网上使用最广的一种 Unicode的实现方式(改进)
  2. UTF-8是一种变长的编码方式。它可以使用1-6个字节表示一个符号,根据不同的符号而变化字节长度。
  3. 使用大小可变的编码字母占1个字节,汉字占3个字节

if语句;
while循环控制语句;
do-while循环控制语句;
for循环控制语句

String和基本类型转换

语法:将基本类型的值+””即可

  1. 在将String类型转成基本数据类型时,要确保String类型能够转成有效的数据,比·如我们可以把”123”,转成一个整数,但是不能把”hello”转成一个整数
  2. 如果格式不正确,就会抛出异常,程序就会终止,这个问题在异常处理章节中,会处理

Java 变量类型

在 Java 语言中,所有的变量在使用前必须声明。

声明变量的基本格式如下:

1
type identifier \[ = value\]\[, identifier \[\= value\] ...\] ;

格式说明:

  • type – 数据类型。
  • identifier – 是变量名,可以使用逗号 , 隔开来声明多个同类型变量。

以下列出了一些变量的声明实例。注意有些包含了初始化过程。

1
2
3
4
5
6
int a, b, c;         // 声明三个int型整数:a、 b、c
int d = 3, e = 4, f = 5; // 声明三个整数并赋予初值
byte z = 22; // 声明并初始化 z
String s = "runoob"; // 声明并初始化字符串 s
double pi = 3.14159; // 声明了双精度浮点型变量 pi
char x = 'x'; // 声明变量 x 的值是字符 'x'。

Java 语言支持的变量类型有:

  • 局部变量(Local Variables):局部变量是在方法、构造函数或块内部声明的变量,它们在声明的方法、构造函数或块执行结束后被销毁,局部变量在声明时需要初始化,否则会导致编译错误。

    1
    2
    3
    4
    public void exampleMethod() {
    int localVar = 10; // 局部变量
    // ...
    }
  • 实例变量(Instance Variables):实例变量是在类中声明,但在方法、构造函数或块之外,它们属于类的实例,每个类的实例都有自己的副本,如果不明确初始化,实例变量会被赋予默认值(数值类型为0,boolean类型为false,对象引用类型为null)。

    1
    2
    3
    public class ExampleClass {
    int instanceVar; // 实例变量
    }
  • 静态变量或类变量(Class Variables):类变量是在类中用 static 关键字声明的变量,它们属于类而不是实例,所有该类的实例共享同一个类变量的值,类变量在类加载时被初始化,而且只初始化一次。

    1
    2
    3
    public class ExampleClass {
    static int classVar; // 类变量
    }
  • 参数变量(Parameters):参数是方法或构造函数声明中的变量,用于接收调用该方法或构造函数时传递的值,参数变量的作用域只限于方法内部。

    1
    2
    3
    4
    public void exampleMethod(int parameterVar) {
    // 参数变量
    // ...
    }

以下实例中定义了一个 RunoobTest 类,其中包含了一个成员变量 instanceVar 和一个静态变量 staticVar。

method() 方法中定义了一个参数变量 paramVar 和一个局部变量 localVar。在方法内部,我们将局部变量的值赋给成员变量,将参数变量的值赋给静态变量,然后打印出这些变量的值。

在 main() 方法中,我们创建了一个 RunoobTest 对象,并调用了它的 method() 方法。

  • 实例
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
public class RunoobTest {
// 成员变量
private int instanceVar;
// 静态变量
private static int staticVar;

public void method(int paramVar) {
// 局部变量
int localVar = 10;

// 使用变量
instanceVar = localVar;
staticVar = paramVar;

System.out.println("成员变量: " + instanceVar);
System.out.println("静态变量: " + staticVar);
System.out.println("参数变量: " + paramVar);
System.out.println("局部变量: " + localVar);
}

public static void main(String[] args) {
RunoobTest v = new RunoobTest();
v.method(20);
}
}

运行以上代码,输出如下:

1
2
3
4
成员变量: 10
静态变量: 20
参数变量: 20
局部变量: 10

Java 参数变量

Java 中的参数变量是指在方法或构造函数中声明的变量,用于接收传递给方法或构造函数的值。参数变量与局部变量类似,但它们只在方法或构造函数被调用时存在,并且只能在方法或构造函数内部使用。

Java 方法的声明语法如下:

1
2
3
accessModifier returnType methodName(parameterType parameterName1, parameterType parameterName2, ...) {
// 方法体
}
  • parameterType – 表示参数变量的类型。
  • parameterName – 表示参数变量的名称。

在调用方法时,我们必须为参数变量传递值,这些值可以是常量、变量或表达式。

方法参数变量的值传递方式有两种:值传递引用传递

  • 值传递:在方法调用时,传递的是实际参数的值的副本。当参数变量被赋予新的值时,只会修改副本的值,不会影响原始值。Java 中的基本数据类型都采用值传递方式传递参数变量的值。

  • 引用传递:在方法调用时,传递的是实际参数的引用(即内存地址)。当参数变量被赋予新的值时,会修改原始值的内容。Java 中的对象类型采用引用传递方式传递参数变量的值。

以下是一个简单的例子,展示了方法参数变量的使用:

  • 实例
1
2
3
4
5
6
7
8
9
10
11
12
13
public class RunoobTest {
public static void main(String[] args) {
int a = 10, b = 20;
swap(a, b); // 调用swap方法
System.out.println("a = " + a + ", b = " + b); // 输出a和b的值
}

public static void swap(int x, int y) {
int temp = x;
x = y;
y = temp;
}
}

运行以上代码,输出如下:

1
a = 10, b = 20

Java 局部变量

Java 的局部变量是在方法、构造方法或语句块内部声明的变量,其作用域限制在声明它的代码块内部。

局部变量的声明语法为:

1
type variableName;
  • type – 表示变量的类型。
  • variableName – 表示变量的名称。

说明:

  • 作用域:局部变量的作用域限于它被声明的方法、构造方法或代码块内。一旦代码执行流程离开这个作用域,局部变量就不再可访问。

  • 生命周期:局部变量的生命周期从声明时开始,到方法、构造方法或代码块执行结束时终止。之后,局部变量将被垃圾回收。

  • 初始化:局部变量在使用前必须被初始化。如果不进行初始化,编译器会报错,因为 Java 不会为局部变量提供默认值。

  • 声明:局部变量的声明必须在方法或代码块的开始处进行。声明时可以指定数据类型,后面跟着变量名,例如:int count;

  • 赋值:局部变量在声明后必须被赋值,才能在方法内使用。赋值可以是直接赋值,也可以是通过方法调用或表达式。

  • 限制:局部变量不能被类的其他方法直接访问,它们只为声明它们的方法或代码块所私有。

  • 内存管理:局部变量存储在 Java 虚拟机(JVM)的栈上,与存储在堆上的实例变量或对象不同。

  • 垃圾回收:由于局部变量的生命周期严格限于方法或代码块的执行,它们在方法或代码块执行完毕后不再被引用,因此JVM的垃圾回收器会自动回收它们占用的内存。

  • 重用:局部变量的名称可以在不同的方法或代码块中重复使用,因为它们的作用域是局部的,不会引起命名冲突。

  • 参数和返回值:方法的参数可以视为一种特殊的局部变量,它们在方法被调用时初始化,并在方法返回后生命周期结束。

  • 实例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class LocalVariablesExample {
public static void main(String[] args) {
int a = 10; // 局部变量a的声明和初始化
int b; // 局部变量b的声明
b = 20; // 局部变量b的初始化

System.out.println("a = " + a);
System.out.println("b = " + b);

// 如果在使用之前不初始化局部变量,编译器会报错
// int c;
// System.out.println("c = " + c);
}
}

以上实例中我们声明并初始化了两个局部变量 a 和 b,然后打印出它们的值。注意,如果在使用局部变量之前不初始化它,编译器会报错。

在以下实例中 age 是一个局部变量,定义在 pupAge()方法中,它的作用域就限制在这个方法中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.runoob.test;

public class Test{
public void pupAge(){
int age = 0;
age = age + 7;
System.out.println("小狗的年龄是: " + age);
}

public static void main(String[] args){
Test test = new Test();
test.pupAge();
}
}

以上实例编译运行结果如下:

1
小狗的年龄是: 7

在下面的例子中 age 变量没有初始化,所以在编译时会出错:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.runoob.test;

public class Test{
public void pupAge(){
int age;
age = age + 7;
System.out.println("小狗的年龄是 : " + age);
}

public static void main(String[] args){
Test test = new Test();
test.pupAge();
}
}

以上实例编译运行结果如下:

1
2
3
4
Test.java:4:variable number might not have been initialized
age = age + 7;
^
1 error

成员变量(实例变量)

  • 成员变量声明在一个类中,但在方法、构造方法和语句块之外。
  • 当一个对象被实例化之后,每个成员变量的值就跟着确定。
  • 成员变量在对象创建的时候创建,在对象被销毁的时候销毁。
  • 成员变量的值应该至少被一个方法、构造方法或者语句块引用,使得外部能够通过这些方式获取实例变量信息。
  • 成员变量可以声明在使用前或者使用后。
  • 访问修饰符可以修饰成员变量。
  • 成员变量对于类中的方法、构造方法或者语句块是可见的。一般情况下应该把成员变量设为私有。通过使用访问修饰符可以使成员变量对子类可见。
  • 成员变量具有默认值。数值型变量的默认值是0,布尔型变量的默认值是 false,引用类型变量的默认值是 null。变量的值可以在声明时指定,也可以在构造方法中指定;
  • 成员变量可以直接通过变量名访问。但在静态方法以及其他类中,就应该使用完全限定名:ObjectReference.VariableName。

成员变量的声明语法为:

1
accessModifier type variableName;
  • accessModifier –表示访问修饰符,可以是 public、protected、private 或默认访问级别(即没有显式指定访问修饰符)。
  • type – 表示变量的类型。
  • variableName – 表示变量的名称。

与局部变量不同,成员变量的值在创建对象时被分配,即使未对其初始化,它们也会被赋予默认值,例如 int 类型的变量默认值为 0,boolean 类型的变量默认值为 false。

成员变量可以通过对象访问,也可以通过类名访问(如果它们是静态成员变量)。如果没有显式初始化成员变量,则它们将被赋予默认值。可以在构造函数或其他方法中初始化成员变量,或者通过对象或类名访问它们并设置它们的值。

  • 实例

以下实例我们声明了两个成员变量 a 和 b,并对其进行了访问和设置。注意,我们可以通过对象访问成员变量,也可以通过类名访问静态成员变量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class RunoobTest {
private int a; // 私有成员变量a
public String b = "Hello"; // 公有成员变量b

public static void main(String[] args) {
RunoobTest obj = new RunoobTest(); // 创建对象

obj.a = 10; // 访问成员变量a,并设置其值为10
System.out.println("a = " + obj.a);

obj.b = "World"; // 访问成员变量b,并设置其值为"World"
System.out.println("b = " + obj.b);
}
}

以上实例编译运行结果如下:

1
2
a = 10
b = World

以下实例我们声明了两个成员变量 name 和 salary,并对其进行了访问和设置。

  • Employee.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
import java.io.*;
public class Employee{
// 这个成员变量对子类可见
public String name;
// 私有变量,仅在该类可见
private double salary;
//在构造器中对name赋值
public Employee (String empName){
name = empName;
}
//设定salary的值
public void setSalary(double empSal){
salary = empSal;
}
// 打印信息
public void printEmp(){
System.out.println("名字 : " + name );
System.out.println("薪水 : " + salary);
}

public static void main(String[] args){
Employee empOne = new Employee("RUNOOB");
empOne.setSalary(1000.0);
empOne.printEmp();
}
}

以上实例编译运行结果如下:

1
2
3
4
$ javac Employee.java 
$ java Employee
名字 : RUNOOB
薪水 : 1000.0

类变量(静态变量)

Java 中的静态变量是指在类中定义的一个变量,它与类相关而不是与实例相关,即无论创建多少个类实例,静态变量在内存中只有一份拷贝,被所有实例共享。

静态变量在类加载时被创建,在整个程序运行期间都存在。

定义方式

静态变量的定义方式是在类中使用 static 关键字修饰变量,通常也称为类变量。

以下实例中我们定义一个静态变量 count ,其初始值为 0:

  • 实例
1
2
3
4
public class MyClass {
public static int count = 0;
// 其他成员变量和方法
}

访问方式

由于静态变量是与类相关的,因此可以通过类名来访问静态变量,也可以通过实例名来访问静态变量。

  • 实例
    1
    2
    3
    MyClass.count = 10; // 通过类名访问  
    MyClass obj = new MyClass();
    obj.count = 20; // 通过实例名访问

生命周期

静态变量的生命周期与程序的生命周期一样长,即它们在类加载时被创建,在整个程序运行期间都存在,直到程序结束才会被销毁。因此,静态变量可以用来存储整个程序都需要使用的数据,如配置信息、全局变量等。

初始化时机

静态变量在类加载时被初始化,其初始化顺序与定义顺序有关。

如果一个静态变量依赖于另一个静态变量,那么它必须在后面定义。

  • 实例
    1
    2
    3
    4
    5
    public class MyClass {  
        public static int count1 = 0;
        public static int count2 = count1 + 1;
        // 其他成员变量和方法
    }
    上面的例子中,count1 要先于 count2 初始化,否则编译时会报错。

常量和静态变量的区别

常量也是与类相关的,但它是用 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
    13
    public 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
    11
    public 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
2
3
Application name: MyApp
Application version: 1.0.0
Database URL: jdbc:mysql://localhost:3306/mydb

可以看到,这些静态变量存储的全局配置信息可以在整个程序中使用,并且不会被修改。这个例子展示了静态变量的另一个常见应用,通过它我们可以很方便地存储全局配置信息,或者实现其他需要全局共享的数据。

以下实例定义了一个 Counter 类,其中包含了一个静态变量 count,用于记录创建了多少个 Counter 对象。

每当创建一个新的对象时,构造方法会将计数器加一。静态方法 getCount() 用于获取当前计数器的值。

在 main() 方法中,我们创建了三个 Counter 对象,并打印出了计数器的值。

  • Counter.java 文件代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Counter {
private static int count = 0;

public Counter() {
count++;
}

public static int getCount() {
return count;
}

public static void main(String[] args) {
Counter c1 = new Counter();
Counter c2 = new Counter();
Counter c3 = new Counter();
System.out.println("目前为止创建的对象数: " + Counter.getCount());
}
}

以上实例编译运行结果如下:

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
2
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
2
3
4
5
6
7
8
9
10
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

自增自减运算符

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
2
进行自增运算后的值等于4
进行自减运算后的值等于2

解析:

  • 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
2
自增运算符前缀运算后a=6,x=12
自增运算符后缀运算后b=6,y=10

关系运算符

下表为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
2
3
4
5
6
a == b = false
a != b = true
a > b = false
a < b = true
b >= a = true
b <= a = false

位运算符

Java定义了位运算符,应用于整数类型(int),长整型(long),短整型(short),字符型(char),和字节型(byte)等类型。

位运算符作用在所有的位上,并且按位运算。假设a = 60,b = 13;它们的二进制格式表示将如下:

1
2
3
4
5
6
7
A = 0011 1100
B = 0000 1101
-----------------
A&B = 0000 1100
A | B = 0011 1101
A ^ B = 0011 0001
~A= 1100 0011

下表列出了位运算符的基本运算,假设整数变量 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
2
3
4
5
6
7
a & b = 12
a | b = 61
a ^ b = 49
~a = -61
a << 2 = 240
a >> 2 = 15
a >>> 2 = 15

逻辑运算符

下表列出了逻辑运算符的基本运算,假设布尔变量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
2
3
a && b = false
a || b = true
!(a && b) = true

短路逻辑运算符

当使用与逻辑运算符时,在两个操作数都为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
2
使用短路逻辑运算符的结果为false
a的结果为5

解析: 该程序使用到了短路逻辑运算符(&&),首先判断 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
2
3
4
5
6
7
8
9
10
11
12
c = a + b = 30
c += a  = 40
c -= a = 30
c *= a = 300
c /= a = 1
c %= a  = 5
c <<= 2 = 20
c >>= 2 = 5
c >>= 2 = 1
c &= a  = 0
c ^= a   = 10
c |= a   = 10

条件运算符(?:)

条件运算符也被称为三元运算符。该运算符有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
2
Value of b is : 30
Value of b is : 20

instanceof 运算符

该运算符用于操作对象实例,检查该对象是否是一个特定类型(类类型或接口类型)。

instanceof运算符使用格式如下:

1
( Object reference variable ) instanceof  (class/interface type)

如果运算符左侧变量所指的对象,是操作符右侧类或接口(class/interface)的一个对象,那么结果为真。

下面是一个例子:

1
2
String name = "James";
boolean result = name instanceof String; // 由于 name 是 String 类型,所以返回真

如果被比较的对象兼容于右侧类型,该运算符仍然返回 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. 当左右两边有一方为字符串,则做拼接运算
    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
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
public class OperatorDemo1 {
public static void main(String[] args) {
// 目标:掌握基本的算术运算符的使用。
int a = 10;
int b = 2;
System.out.println(a + b);
System.out.println(a - b);
System.out.println(a * b); // 20
System.out.println(a / b); // 5
System.out.println(5 / 2); // 2.5 ==> 2
System.out.println(5.0 / 2); // 2.5
int i = 5;
int j = 2;
System.out.println(1.0 * i / j); // 2.5

System.out.println(a % b); // 0
System.out.println(3 % 2); // 1

System.out.println("---------------------------------------");

// 目标2:掌握使用+符号做连接符的情况。
int a2 = 5;
System.out.println("abc" + a2); // "abc5"
System.out.println(a2 + 5); // 10
System.out.println("itheima" + a2 + 'a'); // "itheima5a"
System.out.println(a2 + 'a' + "itheima"); // 102itheima
}
}

自增自减运算符

  1. 面试题1
1
2
3
int i=1;      //i->1
i=i++; //规则使用临时变量: (1) temp=i;(2) i=i+1;(3)i=temp;
System.out.println(i); //1

问:结果是多少?为什么?

  1. 面试题2
1
2
3
int i=1;
i=++i; //规则使用临时变量:;(1) i=i+1;(2) temp=i;(3)i=temp;
System.out.println(i); //2
  1. 练习2
1
2
3
4
5
6
7
8
int i1 = 10;
int i2 = 20;
int i = i1++;
System.out.print( "i="+i);//10
System.out.println( "i2="+i2);//20
i = --i2;
System.out.print( "i="+i);//19
System.out.println( "i2="+i2); //19
  1. 练习3
1
2
3
4
5
6
//(1)先定义一个double huaShi变量保存华氏温度
//(2)根据给出的公式,进行计算即可5/9*(华氏温度-100)
//(3)将得到的结果保存到double sheShi
double huaShi = 1234.6;
double sheShi =i/ 9*(huaShi - 100);
System.out.println("华氏温度" + huaShi + "对应的摄氏温度"= + sheShi);

赋值运算符

1
2
3
4
5
1.基本赋值运算符:
=符号含义: 把右边的值赋值给左边的变量

2.扩展赋值运算符:
+= -= *= /= %=符号含义:将右边的数据和左边的变量相加、相减、相乘、相除、取余数后,将结果重新赋值给左边的变量。

关系运算符

  1. 关系运算符的结果都是boolean型,也就是要么是true,要么是false
  2. 关系表达式经常用在if结构的条件电或循环结构的条件中

逻辑运算符

逻辑运算符一览

说明逻辑运算规则:

  1. a&b :&叫逻辑与:规则:当a和 b同时为true ,则结果为true,否则为false
  2. a&&b : &&叫短路与:规则:当a和 b同时为true ,则结果为true,否则为false
  3. a|b:|叫逻辑或,规则:当a和b,有一个为true ,则结果为true,否则为false
  4. a || b:||叫短路或,规则:当a和b,有一个为true ,则结果为true,否则为false
  5. !a :叫取反,或者非运算。当a为true,则结果为false,当a为false是,结果为true
  6. a^b :叫逻辑异或,当a和b 不同时,则结果为true,否则为false

开发中基本使用 && 和 ||

三元运算符

基本语法

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

条件表达式 ? 表达式1 : 表达式2;

运算规则:

  1. 如果条件表达式为true,运算后的结果是表达式1;
  2. 如果条件表达式为false,运算后的结果是表达式2;

API介绍、Scanner

  1. API是什么?API文档是什么?
    Application Programming Interface,应用程序编程接口:Java写好的程序,咱们可以直接调用。
    Java提供的程序使用说明书。

  2. 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class ScannerDemo1 {
public static void main(String[] args) {
// 1、导包:一般不需要我们自己做,idea工具会自动帮助我们 导包的。
// 2、抄写代码:得到一个键盘扫描器对象(东西)
Scanner sc = new Scanner(System.in);

// 3、开始 调用sc的功能,来接收用户键盘输入的数据。
System.out.println("请您输入您的年龄:");
int age = sc.nextInt(); // 执行到这儿,会开始等待用户输入一个整数,直到用户按了回车键,才会拿到数据。
System.out.println("您的年龄是:" + age);

System.out.println("请您输入您的名字:");
String name = sc.next(); // 执行到这儿,会开始等待用户输入一个字符串,直到用户按了回车键,才会拿到数据。
System.out.println(name + "欢迎您进入系统~~");
}
}

程序流程控制

顺序控制

程序的流程控制一般分为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
2
3
4
5
6
7
- 1.表达式类型只能是byteshortintchar
JDK5开始支持枚举,JDK7开始支持String
不支持doublefloatdouble

- 2.case给出的值不允许重复,且只能是字面量,不能是变量。

- 3.正常使用switch的时候,不要忘记写break,否则会出现穿透现象。

解读switch

  1. switch关键字,表示swtich分支
  2. 表达式对应一个值
  3. case常量1:当表达式的值等于常量1,就执行语句块1
  4. break :表示退出swtich
  5. 如果和case常量1匹配,就执行语句块1,如果没有匹配。就继续匹配case常量2
  6. 如果一个都没有匹配上,执行default

switch分支结构

  1. 表达式数据类型,应和case后的常量类型一致,或者是可以自动转成可以相互比较的类型,比如输入的是字符,而常量是int
  2. switch(表达式)中表达式的返回值必须是:(byte,short,int,char,enum,String)
1
2
3
4
5
6
double c = 1.1;
switch(c){//错误
case 1.1 ://错误
System.out.print1n( "ok3" );
break;
}
  1. case子句中的值必须是常量,而不能是变量
  2. default子句是可选的,当没有匹配的case时,执行default
  3. break语句用来在执行完一个case分支后使程序跳出switch语句块;如果没有写break,程序会顺序执行到switch结尾

switch和if选择

  1. 如果判断的具体数值不多,而且符合byte、short、int、char, enum, String这6种类型。虽然两个语句都可以使用,建议使用swtich语句。
  2. 其他情况:对区间判断,对结果为boolean类型判断,使用if,if的使用范围更广

for循环控制

基本语法

1
2
3
4
5
6
7
8
9
//for循环格式:
for (初始化语句; 循环条件; 迭代语句) {
循环体语句(重复执行的代码);
}

初始化语句:一般是定义一个变量,并给初始值
循环条件:一般是一个关系表达式,结果必须是true或者false
迭代语句:用于对条件进行控制,一般是自增或者自减
循环语句体:需要重复执行的代码

说明

  1. for关键字,表示循环控制
  2. for有四要素:(1)循环变量初始化(2)循环条件(3)循环操作(4)循环变量迭代
  3. 循环操作,这里可以有多条语句,也就是我们要循环执行的代码
  4. 如果循环操作(语句)只有一条语句,可以省略{},建议不要省略
  • 注意事项和细节说明
  1. 循环条件是返回一个布尔值的表达式
  2. for(;循环判断条件;)中的初始化和变量迭代可以写到其它地方,但是两边的分号不能省略。
  3. 循环初始值可以有多条初始化语句,但要求类型一样,并且中间用逗号隔开,
    循环变量迭代也可以有多条变量迭代语句,中间用逗号隔开。
  4. 使用内存分析法,老师分析输出下面代码输出什么?
1
2
3
4
int count = 3;
for (int i = o j= o; i < count; i++,j += 2) {
System.out.println("i=" + i + "j=" + j);
}

i = 0 j = 0
i = 1 j = 2
i = 2 j = 4

while基本语法

基本语法
循环变量初始化;
while(循环条件){
循环体(语句);
循环变量迭代;
}

do..while循环控制

基本语法
循环变量初始化;
do{
循环体(语句);
循环变量迭代;
}while(循环条件);

1
2
3
4
5
int i = 0;
do {
system.out. println( "Hello world! ");
i++;
}while( i < 3);

说明:

  1. do while是关键字
  2. 也有循环四要素,只是位置不一样
  3. 先执行,再判断,也就是说,一定会至少执行一次
  4. 最后有一个分号;
  5. while和do..while区别举例:要账

多重循环执行流程

介绍

  1. 将一个循环放在另一个循环体内,就形成了嵌套循环。其中,for while ,do…while均可以作为外层循环和内层循环。最多不要超过3层

  2. 实质上,嵌套循环就是把内层循环当成外层循环的循环体。当只有内层循环的循环条件为false时,才会完全跳出内层循环,才可结束外层的当次循环,开始下一次的循环。

  3. 设外层循环次数为m次,内层为n次,则内层循环体实际上需要执行m*n次。

1
2
3
4
5
for( int i= 1;i<= 7; i++){ //第一层循环 7
for( int j =1;j<=2; j++){ //第二层循环2
System.out.println("ok~~"); //7*2=14
}
}

三种循环的区别总结

1
2
3
4
5
6
7
8
9
1. for循环 和 while循环(先判断后执行); 
do...while (先执行后判断)

2.for循环和while循环的执行流程是一模一样的,
功能上无区别,for能做的while也能做,反之亦然。
如果已知循环次数建议使用for循环,如果不清楚要循环多少次建议使用while循环。

3 for循环中控制循环的变量只在循环中使用
while循环中,控制循环的变量在循环后还可以继续使用

死循环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//for死循环
for ( ; ; ){
System.out.println("Hello World1");
}

//while死循环
while (true) {
System.out.println("Hello World2");
}

//do-while死循环
do {
System.out.println("Hello World3");
}while (true);

跳转控制语句-break

  • break作用:跳出并结束当前所在循环的执行
  • continue作用:结束本次循环,进入下一次循环

基本介绍:

break语句用于终止某个语句块的执行,一般使用在switch或者循环[for , while ,do-while]中基本语法:
{ ….
break
….;
}

  • 跳转控制语句:break

注意事项和细节说明:

  1. break语句出现在多层嵌套的语句块中时,可以通过标签指明要终止的是哪一层语句块

  2. 标签的基本使用

标签的基本使用

1
2
3
4
5
6
7
8
label1: { ....
label2: { ....
label3: { ....
break label2;
....
}
}
}

(1)break语句可以指定退出哪层
(2)label1是标签,由程序员指定。
(3) break后指定到哪个label 就退出到哪里
(4)在实际的开发中,尽量不要使用标签,
(5)如果没有指定break,默认退出最近的循环体

1
2
3
4
5
6
7
8
9
10
lable1:
for(int j= 0; j<4; j++){
lable2:
for(int i = o; i< 10; i++){
if(i == 2){
break lable1;
}
System.out.println("i= "+i);
}
}

跳转控制语句-continue

基本介绍:

  1. continue语句用于结束本次循环,继续执行下一次循环。
  2. continue语句出现在多层嵌套的循环语句体中时,可以通过标签指明要跳过的是哪一层循环,这个和前面的标签的使用的规则一样.

基本语法:
{ ….
continue;
….
}

跳转控制语句-continue

1
2
3
4
5
6
7
8
9
10
11
12
13
label1:
for(int j = 0; j< 4; j++){
label2:
for(int i = 0; i<10; i++){i
if(i == 2){
//看看分别输出什么值,并分析
//continue ;
//continue label2;
continue label1;
}
System.out.println("i = " + i);
}
}

跳转控制语句-return

return使用在方法,表示跳出所在的方法,在讲解方法的时候,会详细的介绍,这里我们简单的提一下。
注意:如果return写在main方法,退出程序..

1
2
3
4
5
6
7
8
for(int i=1;i<=5;i++){
if(i==3) {
System.out.println("教育"+i);
return; //continue; break;
}
System.out.println("Hello World!");
}
System.out.println("go on..");

本章作业

  1. 判断一个整数是否是水仙花数,所谓水仙花数是指一个3位数,其各个位上数字立方和等于其本身。例如:153 = 111 +333+555
1
2
3
4
5
6
7
8
int n = 15;
int n1 = n / 100;
int n2 = n % 100/ 10;int n3 = n % 10;
if(n1 * n1 * n1 +n2* n2* n2 +n3 * n3 * n3 == n) {
System.out.println(n +"是水仙花数");
}else {
System.out.println(n +“"不是水仙花数");
}
  1. 输出1-100之间的不能被5整除的数,每5个一行

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    int 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();
    }
    }
    }
  2. 输出小写的a-z以及大写的Z-A

1
2
3
4
5
6
7
for(char c1 = 'a'; c1 <= 'z'; c1++) {
System.out.print(c1 +"");
}
//灵活的使用,编程。.
for(char c1 = 'Z'; c1 >'A'; c1--) {
System.out.print(c1 +"");
}
  1. 求出1-1/2+1/3-1/4…..1/100的和
1
2
3
4
5
6
7
8
9
10
double sum = 0;
for(int i = 1; i <= 100; i++){
//判断是奇数还是偶数,然后做不同的处理
if( i % 2 !=) {//分母为奇数
sum += 1.0/i;
}else {//分母我偶数
sum -= 1.0/i;
}
}
System.out.println( "sum=" + sum);
  1. 求1+(1+2)+(1+2+3)+(1+2+3+4) +….+(1+2+3+..+100)的结果
    1
    2
    3
    4
    5
    6
    7
    int 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
2
3
4
5
6
//(1)第一种动态分配方式
// double scores[] = new double[5];

//(2)第2种动态分配方式,先声明数组,再new分配空间
double scores[] ; //声明数组,这时scores是 null
scores = new doubLe[5]; // 分配内存空间,可以存放数据

数组动态初始化案例

1
2
3
4
5
6
7
8
9
10
案例需求:
某歌唱比赛,需要开发一个系统:可以录入6名评委的打分,录入完毕后立即输出平均分做
选手得分

需求分析:
1.需要录入6名评委的分数,可以用一个数组来保存。
因为在评委没有录入分数之前,还不确定数组中应该存哪些数据。
所以可以使用数组的动态初始化
2.遍历数组中的每一个位置,并录入分数,将分数存入数组中
3.遍历数组中的每一个元素,对元素求和

代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 1、定义一个动态初始化的数组,负责后期存储6个评委的打分。
double[] scores = new double[6];

Scanner sc = new Scanner(System.in);

// 2、遍历数组中的每个位置,录入评委的分数,存入到数组中去
for (int i = 0; i < scores.length; i++) {
// i = 0 1 2 3 4 5
System.out.println("请您输入当前第" + (i + 1) +"个评委的分数:");
double score = sc.nextDouble();
scores[i] = score;
}

// 3、遍历数组中的每个元素进行求和
double sum = 0;
for (int i = 0; i < scores.length; i++) {
sum += scores[i];
}
System.out.println("选手最终得分是:" + sum / scores.length);

使用方式2-静态初始化

所谓静态初始化指的是:在定义数组时直接给数组中的数据赋值。

静态初始化标准格式:

1
数据类型[] 变量名 = new 数据类型[]{元素1,元素2,元素3};

按照格式定义int类型、double类型数组

1
2
3
4
5
//定义数组,用来存储多个年龄
int[] ages = new int[]{12, 24, 36}

//定义数组,用来存储多个成绩
double[] scores = new double[]{89.9, 99.5, 59.5, 88.0};

静态初始化简化格式

1
数据类型[] 变量名 = {元素1,元素2,元素3};

使用简化格式定义int类型、double类型数组

1
2
3
4
//定义数组,用来存储多个年龄
int[] ages = {12, 24, 36}
//定义数组,用来存储多个成绩
double[] scores = {89.9, 99.5, 59.5, 88.0};

数组静态初始化案例

1
2
3
4
5
6
7
8
9
10
需求:某部门5名员工的销售额分别是:1626366100,请计算出他们部门的总销售额。

需求分析:
1.看到有16263661005个数据数据,而且数据值很明确;
1)想到,可以使用数组静态初始化把这5个数据存起来

2.请计算出他们部门的总销售额(这不就是求数组中数据的和吗?)
2)必须先将数组中所有的元素遍历出来
3)想要求和,得先有一个求和变量sum
4)再将每一个元素和求和变量sum进行累加(求和思想)

按照分析的思路来写代码

1
2
3
4
5
6
7
8
9
10
11
12
13
// 1、定义一个数组存储5名员工的销售额
//索引 0 1 2 3 4
int[] money = {16, 26, 36, 6, 100};

// 3、定义一个变量用于累加求和
int sum = 0;

// 2、遍历这个数组中的每个数据。
for (int i = 0; i < money.length; i++) {
// i = 0 1 2 3 4
sum += money[i];
}
System.out.println("员工的销售总额:" + sum);

数组使用注意事项和细节

  1. 数组是多个相同类型数据的组合,实现对这些数据的统一管理

  2. 数组中的元素可以是任何数据类型,包括基本类型和引用类型,但是不能混用。

  3. 数组创建后,如果没有赋值,有默认值
    int 0, short O, byte 0, long 0,
    float 0.0,double 0.0, char \u0000,
    boolean false,String null

  4. 使用数组的步骤1.声明数组并开辟空间2给数组各个元素赋值3使用数组

  5. 数组的下标是从O开始的。

  6. 数组下标必须在指定范围内使用,否则报:下标越界异常,比如
    int[]arr=new int[5];则有效下标为0-4

  7. 数组属引用类型,数组型数据是对象(object)

  8. 动态初始化数组的写法是什么样的?有什么特点?

数据类型 [数组名] = new 数据类型 [长度];
int[] ages = new int[4];

  1. 动态初始化数组后元素的默认值是什么样的?
  • byte、short、int , char、long类型数组的元素默认值都是0
  • float、double类型数组元素的默认值都是0.0
  • boolean类型数组的元素默认值是false、string类型数组的元素的默认值是null
  1. 两种数组定义的方法各自适合什么业务场景?
  • 动态初始化:适合开始不确定具体元素值,只知道元素个数的业务场景。
  • 静态初始化:适合一开始就知道要存入哪些元素值的业务场景。
  1. 多个数组变量,指向同一个数组对象的原因是什么?需要注意什么?
  • 多个数组变量中存储的是同一个数组对象的地址。
  • 多个变量修改的都是同一个数组对象中的数据。
  1. 如果某个数组变量中存储的null,代表什么意思?需要注意什么?
  • 代表这个数组变量没有指向数组对象。
  • 可以输出这个变量,但是不能用这个数组变量去访问数据或者访问数组长度,会报空指针异常:NullPointerException。

数组遍历

所谓遍历意思就是将数组中的元素一个一个的取出来。

1
2
3
4
5
int[] ages = {12, 24, 36};
for (int i = 0; i < ages.length; i++) {
// i的取值 = 0,1,2
System.out.println(ages[i]);
}

数组的执行原理,Java程序的执行原理

Java为了便于虚拟机执行Java程序,将虚拟机的内存划分为 方法区、栈、堆、本地方法栈、寄存器 这5块区域。同学们需要重点关注的是 方法区、栈、堆

  • 方法区:字节码文件先加载到这里
  • :方法运行时所进入的内存区域,由于变量在方法中,所以变量也在这一块区域中
  • :存储new出来的东西,并分配地址。由于数组是new 出来的,所以数组也在这块区域。

总结一下int a = 10int[] arr = new int[]{11,22,33}的区别

  • a是一个变量,在栈内存中,a变量中存储的数据就是10这个值。
  • arr也是一个变量,在栈中,存储的是数组对象在堆内存中的地址值
1
2
3
4
// 这里的int a是一个基本类型变量,存储的是一个数值
int a = 10 ;
//这里的int[] arr是一个引用类型的变量,存储的是一个地址值
int[] arr = new int[]{44,55,66};

数组练习1

1
2
3
4
5
6
7
8
9
10
11
12
char[] chars = new char[26];
for( int i = 0; i < chars.length; i++) {//循环26次
// chars是char[]
// chars[i]是char
chars[i] =(char)('A' + i); //'A'+i是int,需要强制转换
}

//循环输出
System.out.println( "===chars数组===");
for( int i = 0; i < chars.length; i++){//循环26次
System.out.print(chars[i] +" ");
}

数组练习2

1
2
3
4
5
6
7
8
9
10
11
12
int[] arr = {4,-1,9};

int max = arr[0];//假定第一个元素就是最大值
int maxIndex = 0;//
for(int i = 1; i < arr.length; i++){//从下标1开始逼历arr
if(max < arr[i]){//如果max<当前元素
max = arr[i];//把max设置成当前元素
maxIndex = i;
}
}
//当我们逼历这个数组arr后, max就是真正的最大值, maxIndex最大值下标
System.out.println( "max=" +max + " maxIndex=" + maxIndex);

数组赋值机制

  1. 基本数据类型赋值,这个值就是具体的数据,而且相互不影响。
    int n1 = 2;
    int n2 = n1;

  2. 数组在默认情况下是引用传递,赋的值是地址。
    int[]arr1 ={1,2,3};
    int[]arr2 = arr1;

数组求最值

1
需求:定义一个int类型数组,求数组中元素的最大值,并打印最大值
1
2
3
4
数组求最大值思路:
1)先找出数组中0索引的元素,假设为最大值,用max表示【擂主】
2)遍历后面的每一个元素和max比较,把较大的元素值重新赋值给max(擂主换人)
3)最后max就是所有元素的最大值(最后站在台上的擂主)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Test1 {
public static void main(String[] args) {
// 1、把颜值数据拿到程序中来,用数组装起来
int[] faceScores = {15, 9000, 10000, 20000, 9500, -5};

// 2、定义一个变量用于最终记住最大值。
int max = faceScores[0];

// 3、从数组的第二个位置开始遍历。
for (int i = 1; i < faceScores.length; i++) {
// i = 1 2 3 4 5
// 判断一下当前遍历的这个数据,是否大于最大值变量max存储的数据,
//如果大于,当前遍历的数据需要赋值给max
if(faceScores[i] > max ){
max = faceScores[i];
}
}
System.out.println("最高颜值是:" + max);
}
}

总结一下:

通过这个案例,我们主要掌握求最值的思路,以后不管遇到求最大值还是最小值,编程思路都是一样的,不同的可能是数据不同。

数组反转

1
2
需求:某个数组有5个数据:10,20,30,40,50,请将这个数组中的数据进行反转。
[10, 20, 30, 40, 50] 反转后 [50, 40, 30, 20, 10]
1
2
3
4
5
1.每次交换,需要有左右两边的两个索引,我们可以用i和j表示
刚开始i=0,j=数组长度-1;
2.每次让i和j索引位置的两个元素互换位置
arr[i]和arr[j]互换位置
3.每次还完位置之后,让i往右移动一位,让j往前移动一位

具体代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class Test2 {
public static void main(String[] args) {
// 目标:完成数组反转。
// 1、准备一个数组
int[] arr = {10, 20, 30, 40, 50};

// 2、定义一个循环,设计2个变量,一个在前,一个在后
for (int i = 0, j = arr.length - 1; i < j; i++, j--) {
// arr[i] arr[j]
// 交换
// 1、定义一个临时变量记住后一个位置处的值
int temp = arr[j];
// 2、把前一个位置处的值赋值给后一个位置了
arr[j] = arr[i];
// 3、把临时变量中记住的后一个位置处的值赋值给前一个位置处
arr[i] = temp;
}

// 3、遍历数组中的每个数据,看是否反转成功了
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
}

总结一下:

通过上面的案例,需要我们掌握元素互换位置的编程思路;以后遇到数据互换问题,都这样做。

数组扩容

要求:实现动态的给数组添加元素效果,实现对数组扩容。

  1. 原始数组使用静态分配int[] arr = {1,2,3}

  2. 增加的元素,直接放在数组的最后arr = {1,2,3.4}

  3. 用户可以通过如下方法来决定是否继续添加,添加成功,是否继续? y/n

有一个数组{1,2,3,4,5},可以将该数组进行缩减,提示用户是否继续缩减,每次缩减最后哪个元素。当只剩下最后一个元素,提示,不能再缩减。

1
2
3
4
5
6
7
8
9
10
11
12
13
int[] arr = {1,2,3};

int[] arrNew = new int[arr.length + 1];
//遍历arr数组,依次将arr的元素拷贝到arrNew数组
for(int i = e; i < arr.length; i++){
arrNew[i] = arr[i];
}
//把4赋给arrNew最后一个元素
arrNew[ arrNew.length - 1] =4; //让 arr指向arrNew,
arr = arrNew; //输出arr
for(int i = 0; i < arr.length; i++){
System.out.println(arr[i] +"\t");
}

排序介绍

排序的介绍
排序是将一群数据,依指定的顺序进行排列的过程。排序的分类:

  1. 内部排序:
    指将需要处理的所有数据都加载到内部存储器中进行排序。包括(交换式排序法、选择式排序法和插入式排序法);
  2. 外部排序法:
    数据量过大,无法全部加载到内存中,需要借助外部存储进行排序。包括(合并排序法和直接合并排序法)。
  • 冒泡排法
    冒泡排序(Bubble Sorting)的基本思想是:通过对待排序序列从后向前(从下标较大的元素开始),依次比较相邻元素的值,若发现逆序则交换,使值较
    大的元素逐渐从前移向后部,就象水底下的气泡一样逐渐向上冒。

冒泡排序法案例:

下面我们举一个具体的案例来说明冒泡法。我们将五个无序:
24,69,80,57,13使用冒泡排序法将其排成一个从小到大的有序数列。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int[]arr = {246980,5713};
int temp = 0;//用于辅助交换的变量
//将多轮排序使用外层循环包括起来即可
//先死后活=》4就是arr.length - 1
for( int i = 0; i < arr.length - 1; i++){//外层循环是4次
for( int j = 0; j < arr.length - 1 - i; j++){//4次比较-3次-2次-1次
//如果前面的数>后面的数,就交换
if(arr[j] > arr[j +1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
System.out.print1n( " [n==第"+(i+1)+"轮==");
for(int j = 0; j < arr.length; j++){
System.out.print(arr[j] + "\t");
}
}

查找

介绍:
在java中,我们常用的查找有两种:

  1. 顺序查找 SeqSearch.java
  2. 二分查找【二分法,我们放在算法讲解】

案例演示:

  1. 有一个数列:白眉鹰王、金毛狮王、紫衫龙王、青翼蝠王猜数游戏:
    从键盘中任意输入一个名称,判断数列中是否包含此名称【顺序查找】要求:如果找到了,就提示找到,并给出下标值。
  2. 请对一个有序数组进行二分查找{1,8,10,89,1000,1234},输入一个数看看该数组是否存在此数,并且求出下标,如果没有就提示”没有这个数”。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//定义一个字符串数组
string[ ] names = {"白眉鹰王","金毛狮王","紫衫龙王""青翼蝠王"};
Scanner myScanner = new Scanner(System.in);
System.out.println("请输入名字");
string findName = myScanner.next();

//遍历数组,逐一比较,如果有,则提示信息,并退出
//这里老师给大家一个编程思想/技巧,一个经典的方法
int index = -1;
for(int i = ; i < names.length; i++) {
//比较字符串比较equals,如果要找到名字就是当前元素
if(findName.equals(names[i])){
System.out.println("恭喜你找到" + findName);
System.out.println("下标为=" + i);
//把i保存到index
index = i;
break;//退出
}
}
if(index == -1) {//没有找到
System.out.println( "sorry ,没有找到"+ findName);
}

二维数组

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
//1.从定义形式上看int[][]
//2.可以这样理解,原来的一维数组的每个元素是一维数组,就构成二维数组
int[][]arr = { {000000},
{001,000},
{0,20,300},
{000000}};
//关于二维数组的关键概念
//(1)
System.out.println("二维数组的元素个数"= + arr.length);
//(2)二维数组的每个元素是一维数组,所以如果需要得到每个一维数组的值
// 还需要再次遍历
//(3)如果我们要访问第(i+1)个一维数组的第j+1个值arr[i][j];
//举例 访问3,=> 他是第3个一维数组的第4个值arr[2][3]
System.out.println("第3个一维数组的第4个值=" +arr[2][3]); //3

//输出二维图形
for(int i -0; i < arr.length; i++){//遍历二维数组的每个元秦
//遍历二维数组的每个元素(数组)

//1. arr[i]表示二维数组的第i+1个元素比如arr[0]∶二维数组的第一个元素
//2. arr[i].length得到对应的每个一维数组的长度
for(int j = 0; j < arr[i].length; j++){
System.out.print(arr[i][j] +" ");//输出了一维数组
}
System.out.println();//换行
}

二维数组的使用

使用方式1:动态初始化

  1. 语法:类型[][]数组名=new类型[大小][大小]
  2. 比如: int a[][]=new int[2][3]
  3. 二维数组在内存的存在形式

使用方式2:动态初始化

  1. 先声明:类型数组名[][];
  2. 再定义(开辟空间)数组名=new类型[大小][大小]
  3. 赋值(有默认值,比如int类型的就是0)

使用方式3:动态初始化-列数不确定

  1. 看一个需求:动态创建下面二维数组,并输出。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

/*一个有三个一维数组,每个一维数组的元素是不一样的*/
int[][ ] arr = new int[3][];//创建二维数组,但是只是确定―维数组的个数
for(int i = e; i < arr.length; i++){//逼历arr每个一维数组
//给每个一维数组开空间new
//如果没有给一维数组new,那么arr[ i]就是null
arr[i] = new int[i +1];
//遍历一维数组,并给一维数组的每个元素赋值
for(int j = 0;j < arr[i].length; j++){
arr[i][j]= i + 1;//赋值
}
}

System.out.print1n( "=====arr元素秦=====")
//遍历arr输出
for(int i = 0; i < arr.length; i++) {
//输出arr的每个一维数组
for(int j = 0; j < arr[i].length; j++){
system.out.print(arr[i][j]+" ");
}
system.out. println();/ /换行
}

使用方式4:静态初始化

  1. 定义类型数组名[][] ={ {值1,值2.},{值1,值2.},{值1,值2.} }

  2. 使用即可[固定方式访问]
    比如:
    int[][]arr = { {1,1,1},{8.8,9},{100} };

  3. 定义了一个二维数组arr

  4. arr有三个元素(每个元素都是一维数组)

  5. 第一个一维数组有3个元素,第二个一维数组有3个元素,第三个一维数组有1个元素

二维数组的应用案例

  1. 使用二维数组打印一个10行杨辉三角
    1
    1 1
    1 2 1
    1 3 3 1
    1 4 6 4 1
    1 5 10 10 5
    1……

【提示】

  1. 第一行有1个元素,第n行有n个元素
  2. 每一行的第一个元素和最后一个元素都是1
  3. 从第三行开始,对于非第一个元素和最后一个元素的元素的值.
    arr[i][j] = arr[i-1][j] + arr[i-1][j-1];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int[][]yangHui = new int[10][];
for(int i = o; i < yangHui.length; i++){//遍历yangHui的每个元素
//给每个一维数组(行)开空间
yangHui[i] = new int[i+1];
//给每个一维数组(行)赋值
for(int j = 0; j <yangHui[i].length; j++){
//每一行的第一个元素和最后一个元素都是1
if(j ==6 llj == yangHui[i].length - 1){
yangHui[i][j] = 1;
}else {//中间的元素
yangHui[i][j]yangHui[i-1][j] + yangHui[i-1][j-1];}
}
}
//输出杨辉三角
for(int i = 0; i < yangHui. length; i++){
for(int j = e; j < yangHui[i].length; j++){//遍历输出该行
system.out.print(yangHui[i][j] + "\lt");
}
system.out.println();//换行·
}

二维数组使用细节和注意事项

  1. 一维数组的声明方式有:
    int[]x或者int x[]

  2. 二维数组的声明方式有:
    int[][] y 或者int[] y[]或者int y[][]

  3. 二维数组实际上是由多个一维数组组成的,它的各个一维数组的长度可以相同,也可以不相同。比如: map[][]是一个二维数组
    int map [][]= { {1,2},{3,4,53} }
    由map[0]是一个含有两个元素的一维数组,map[1]是一个含有三个元素的一维数组构成,我们也称为列数不等的二维数组。

Debug调试工具

Debug调试工具的使用步骤如下:

1
2
3
4
第一步:打断点,如下图的红色小圆点
第二步:右键Debug方式启动程序,如下图右键菜单
启动后,代码会停留在打断点的这一行
第三步:点击箭头按钮,一行一行往下执行

Java 对象和类

Java 作为一种面向对象的编程语言,支持以下基本概念:

1、类(Class)

  • 定义对象的蓝图,包括属性和方法。
  • 示例:public class Car { ... }

2、对象(Object)

  • 类的实例,具有状态和行为。
  • 示例:Car myCar = new Car();

3、继承(Inheritance)

  • 一个类可以继承另一个类的属性和方法。
  • 示例:public class Dog extends Animal { ... }

4、封装(Encapsulation)

  • 将对象的状态(字段)私有化,通过公共方法访问。

  • 示例:

    1
    2
    private 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
    9
    public 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Dog {
String breed;
int size;
String colour;
int age;

void eat() {
// Implementation of the eat method
}

void run() {


void sleep() {

}

void name() {

}
}

一个类可以包含以下类型变量:

  • 局部变量:在方法、构造方法或者语句块中定义的变量被称为局部变量。变量声明和初始化都是在方法中,方法结束后,变量就会自动销毁。
  • 成员变量:成员变量是定义在类中,方法体之外的变量。这种变量在创建对象的时候实例化。成员变量可以被类中方法、构造方法和特定类的语句块访问。
  • 类变量:类变量也声明在类中,方法体之外,但必须声明为 static 类型。

一个类可以拥有多个方法,在上面的例子中:eat()、run()、sleep() 和 name() 都是 Dog 类的方法。


构造方法

每个类都有构造方法。如果没有显式地为类定义构造方法,Java 编译器将会为该类提供一个默认构造方法。

在创建一个对象的时候,至少要调用一个构造方法。构造方法的名称必须与类同名,一个类可以有多个构造方法。

下面是一个构造方法示例:

1
2
3
4
5
6
7
8
9
10
11
12
public class Puppy {
// 默认构造器,没有参数
public Puppy() {
// 在这里可以添加初始化代码
}

// 带一个参数的构造器,参数为名字(String类型)
public Puppy(String name) {
// 在这里可以添加初始化代码,例如设置名字属性
this.name = name; // 假设有一个名为name的成员变量
}
}

创建对象

对象是根据类创建的。在Java中,使用关键字 new 来创建一个新的对象。创建对象需要以下三步:

  • 声明:声明一个对象,包括对象名称和对象类型。
  • 实例化:使用关键字 new 来创建一个对象。
  • 初始化:使用 new 创建对象时,会调用构造方法初始化对象。

下面是一个创建对象的例子:

1
2
3
4
5
6
7
8
9
10
11
public class Puppy {
public Puppy(String name) {
// 这个构造器仅有一个参数:name
System.out.println("小狗的名字是 : " + name);
}

public static void main(String[] args) {
// 下面的语句将创建一个Puppy对象
Puppy myPuppy = new Puppy("tommy");
}
}

编译并运行上面的程序,会打印出下面的结果:

1
小狗的名字是 : tommy

访问实例变量和方法

通过已创建的对象来访问成员变量和成员方法,如下所示:

1
2
3
4
5
6
/\* 实例化对象 \*/ 
Object referenceVariable = new Constructor();
/\* 访问类中的变量 \*/
referenceVariable.variableName;
/\* 访问类中的方法 \*/
referenceVariable.methodName();

使用 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
    41
    public 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
2
3
小狗的名字是 : tommy
小狗的年龄为 : 2
变量值 : 2

源文件声明规则

在本节的最后部分,我们将学习源文件的声明规则。当在一个源文件中定义多个类,并且还有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.*;

例子

在该例子中,我们创建两个类:EmployeeEmployeeTest

首先打开代码编辑器,把下面的代码粘贴进去,将文件保存为 Employee.java

Employee 类有四个成员变量:name、age、designation 和 salary,该类显式声明了一个构造方法,该方法只有一个参数。

  • Employee.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
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    import 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 方法
    @Override
    public String toString() {
    return "名字: " + name + "\n" +
    "年龄: " + age + "\n" +
    "职位: " + designation + "\n" +
    "薪水: " + salary;
    }
    }
    Java 程序都是从 main 方法开始执行,为了能运行这个程序,必须包含 main 方法并且创建一个实例对象。

下面给出 EmployeeTest 类,该类实例化 2 个 Employee 类的实例,并调用方法设置变量的值。

将下面的代码保存在 EmployeeTest.java文件中。

  • EmployeeTest.java 文件代码:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    import 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();
    }
    }
    编译这两个文件并且运行 EmployeeTest 类,可以看到如下结果:
1
2
3
4
5
6
7
8
9
10
$ javac EmployeeTest.java Employee.java
$ java EmployeeTest
名字:RUNOOB1
年龄:26
职位:高级程序员
薪水:1000.0
名字:RUNOOB2
年龄:21
职位:菜鸟程序员
薪水:500.0