java学习笔记

1Java环境配置

1.1JRE 和 JDK

JRE (Java Runtime Environment) :是Java程序的运行时环境,包含 JVM 和运行时所需要的 核心类库 。

JDK (Java Development Kit):是Java程序开发工具包,包含 JRE 和开发人员使用的工具。 我们想要运行一个已有的Java程序,那么只需安装 JRE 即可。 我们想要开发一个全新的Java程序,那么必须安装 JDK 。

1. 2window系统安装jdk

1.2.1下载JDK

首先我们需要下载java开发工具包JDK,下载地址:http://www.oracle.com/technetwork/java/javase/downloads/index.html,点击如下下载按钮:

java学习笔记_第1张图片

在下载页面中你需要选择接受许可,并根据自己的系统选择对应的版本,本文以 Window 64位系统为例:

java学习笔记_第2张图片

下载后JDK的安装根据提示进行,还有安装JDK的时候也会安装JRE,一并安装就可以了。

安装JDK,安装过程中可以自定义安装目录等信息,例如我们选择安装目录为 C:\Program Files (x86)\Java\jdk1.8.0_91

1.2.2配置环境变量

1.安装完成后,右击"我的电脑",点击"属性",选择"高级系统设置";

java学习笔记_第3张图片

2.选择"高级"选项卡,点击"环境变量";

java学习笔记_第4张图片

然后就会出现如下图所示的画面:

java学习笔记_第5张图片

在 “系统变量” 中设置 3 项属性,JAVA_HOME、PATH、CLASSPATH(大小写无所谓),若已存在则点击"编辑",不存在则点击"新建"。

**注意:**如果使用 1.5 以上版本的 JDK,不用设置 CLASSPATH 环境变量,也可以正常编译和运行 Java 程序。

变量设置参数如下:

  • 变量名: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.2.3JAVA_HOME 设置

java学习笔记_第6张图片

java学习笔记_第7张图片

1.2.4PATH设置

java学习笔记_第8张图片

java学习笔记_第9张图片

**注意:**在 Windows10 中,Path 变量里是分条显示的,我们需要将 %JAVA_HOME%\bin;%JAVA_HOME%\jre\bin; 分开添加,否则无法识别:

%JAVA_HOME%\bin;
%JAVA_HOME%\jre\bin;

java学习笔记_第10张图片

更多内容可参考:Windows 10 配置Java 环境变量

1.2.5CLASSPATH 设置

java学习笔记_第11张图片

这是 Java 的环境配置,配置完成后,你可以启动 Eclipse 来编写代码,它会自动完成java环境的配置。

1.2.6测试JDK是否安装成功

1、“开始”->“运行”,键入"cmd";

2、键入命令: java -versionjavajavac 几个命令,出现以下信息,说明环境变量配置成功;

img

2.Java基础

2.1标识符

:是指在程序中,我们自己定义内容。比如类的名字、方法的名字和变量的名字等等,都是标识符。

类型 含义 数据举例
整数常量 所有的整数 0,1, 567, -9
小数常量 所有的小数 0.0, -0.1, 2.55
字符常量 单引号引起来,只能写一个字符,必须有内容 ‘a’ , ’ ', ‘好’
字符串常量 双引号引起来,可以写多个字符,也可以不写 “A” ,“Hello” ,“你好” ,""
布尔常量 只有两个值(流程控制中讲解) true , false
空常量 只有一个值(引用数据类型中讲解) null
命名规则: 硬性要求
标识符可以包含 英文字母26个(区分大小写) 、 0-9数字 、 $(美元符号) 和 _(下划线) 。
标识符不能以数字开头。
标识符不能是关键字。
命名规范: 软性建议
类名规范:首字母大写,后面每个单词首字母大写(大驼峰式)。
方法名规范: 首字母小写,后面每个单词首字母大写(小驼峰式)。
变量名规范** :全部小写。

2.2Java修饰符

像其他语言一样,Java可以使用修饰符来修饰类中方法和属性。主要有两类修饰符:

  • 访问控制修饰符 : default, public , protected, private

  • 非访问控制修饰符 : final, abstract, static, synchronized

  • default (即默认,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。

  • private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)

  • public : 对所有类可见。使用对象:类、接口、变量、方法

  • protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)


2.3Java 变量

常量是固定不变的数据,那么在程序中可以变化的量称为变量。

Java中要求一个变量每次只能保存一个数据,必须要明确保存的数据类型。

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

局部变量

类变量(静态变量)

成员变量(非静态变量)

变量名称:在同一个大括号范围内,变量的名字不可以相同。

变量赋值:定义的变量,不赋值不能使用。

2.3.1Java 局部变量

  • 局部变量声明在方法、构造方法或者语句块中;
  • 局部变量在方法、构造方法、或者语句块被执行的时候创建,当它们执行完成后,变量将会被销毁;
  • 访问修饰符不能用于局部变量;
  • 局部变量只在声明它的方法、构造方法或者语句块中可见;
  • 局部变量是在栈上分配的。
  • 局部变量没有默认值,所以局部变量被声明后,必须经过初始化,才可以使用。

2.3.2实例变量

  • 实例变量声明在一个类中,但在方法、构造方法和语句块之外;

  • 当一个对象被实例化之后,每个实例变量的值就跟着确定;

  • 实例变量在对象创建的时候创建,在对象被销毁的时候销毁;

  • 实例变量的值应该至少被一个方法、构造方法或者语句块引用,使得外部能够通过这些方式获取实例变量信息;

  • 实例变量可以声明在使用前或者使用后;

  • 访问修饰符可以修饰实例变量;

  • 实例变量对于类中的方法、构造方法或者语句块是可见的。一般情况下应该把实例变量设为私有。通过使用访问修饰符可以使实例变量对子类可见;

  • 实例变量具有默认值。数值型变量的默认值是0,布尔型变量的默认值是false,引用类型变量的默认值是null。变量的值可以在声明时指定,也可以在构造方法中指定;

  • 实例变量可以直接通过变量名访问。但在静态方法以及其他类中,就应该使用完全限定名:ObejectReference.VariableName

2.3.3类变量(静态变量)

  • 类变量也称为静态变量,在类中以 static 关键字声明,但必须在方法之外。
  • 无论一个类创建了多少个对象,类只拥有类变量的一份拷贝。
  • 静态变量除了被声明为常量外很少使用,静态变量是指声明为 public/private,final 和 static 类型的变量。静态变量初始化后不可改变。
  • 静态变量储存在静态存储区。经常被声明为常量,很少单独使用 static 声明变量。
  • 静态变量在第一次被访问时创建,在程序结束时销毁。
  • 与实例变量具有相似的可见性。但为了对类的使用者可见,大多数静态变量声明为 public 类型。
  • 默认值和实例变量相似。数值型变量默认值是 0,布尔型默认值是 false,引用类型默认值是 null。变量的值可以在声明的时候指定,也可以在构造方法中指定。此外,静态变量还可以在静态语句块中初始化。
  • 静态变量可以通过:ClassName.VariableName的方式访问。
  • 类变量被声明为 public static final 类型时,类变量名称一般建议使用大写字母。如果静态变量不是 public 和 final 类型,其命名方式与实例变量以及局部变量的命名方式一致。

2.4Java 关键字

下面列出了 Java 关键字。这些保留字不能用于常量、变量、和任何标识符的名称。

类别 关键字 说明
访问控制 private 私有的
protected 受保护的
public 公共的
default 默认
类、方法和变量修饰符 abstract 声明抽象
class
extends 扩充,继承
final 最终值,不可改变的
implements 实现(接口)
interface 接口
native 本地,原生方法(非 Java 实现)
new 新,创建
static 静态
strictfp 严格,精准
synchronized 线程,同步
transient 短暂
volatile 易失
程序控制语句 break 跳出循环
case 定义一个值以供 switch 选择
continue 继续
default 默认
do 运行
else 否则
for 循环
if 如果
instanceof 实例
return 返回
switch 根据值选择执行
while 循环
错误处理 assert 断言表达式是否为真
catch 捕捉异常
finally 有没有异常都执行
throw 抛出一个异常对象
throws 声明一个异常可能被抛出
try 捕获异常
包相关 import 引入
package
基本类型 boolean 布尔型
byte 字节型
char 字符型
double 双精度浮点
float 单精度浮点
int 整型
long 长整型
short 短整型
变量引用 super 父类,超类
this 本类
void 无返回值
保留关键字 goto 是关键字,但不能使用
const 是关键字,但不能使用

**注意:**Java 的 null 不是关键字,类似于 true 和 false,它是一个字面常量,不允许作为标识符使用。

2.5数据类型

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

  • 例子:

    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’;。

2.6Java 运算符

计算机的最基本用途之一就是执行数学运算,作为一门计算机语言,Java也提供了一套丰富的运算符来操纵变量。我们可以把运算符分成以下几组:

  • 算术运算符
  • 关系运算符
  • 位运算符
  • 逻辑运算符
  • 赋值运算符
  • 其他运算符

2.6.1算术运算符

算术运算符用在数学表达式中,它们的作用和在数学中的作用一样。下表列出了所有的算术运算符。

表格中的实例假设整数变量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(区别详见下文)

2.6.2关系运算符

下表为Java支持的关系运算符

表格中的实例整数变量A的值为10,变量B的值为20:

运算符 描述 例子
== 检查如果两个操作数的值是否相等,如果相等则条件为真。 (A == B)为假。
!= 检查如果两个操作数的值是否相等,如果值不相等则条件为真。 (A != B) 为真。
> 检查左操作数的值是否大于右操作数的值,如果是那么条件为真。 (A> B)为假。
< 检查左操作数的值是否小于右操作数的值,如果是那么条件为真。 (A
>= 检查左操作数的值是否大于或等于右操作数的值,如果是那么条件为真。 (A> = B)为假。
<= 检查左操作数的值是否小于或等于右操作数的值,如果是那么条件为真。 (A <= B)为真。

2.6.3位运算符

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

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

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 (A | B)得到61,即 0011 1101
^ 如果相对应位值相同,则结果为0,否则为1 (A ^ B)得到49,即 0011 0001
按位取反运算符翻转操作数的每一位,即0变成1,1变成0。 (〜A)得到-61,即1100 0011
<< 按位左移运算符。左操作数按位左移右操作数指定的位数。 A << 2得到240,即 1111 0000
>> 按位右移运算符。左操作数按位右移右操作数指定的位数。 A >> 2得到15即 1111
>>> 按位右移补零操作符。左操作数的值按右操作数指定的位数右移,移动得到的空位以零填充。 A>>>2得到15即0000 1111

2.6.4逻辑运算符

下表列出了逻辑运算符的基本运算,假设布尔变量A为真,变量B为假

操作符 描述 例子
&& 称为逻辑与运算符。当且仅当两个操作数都为真,条件才为真。 (A && B)为假。
| | 称为逻辑或操作符。如果任何两个操作数任何一个为真,条件为真。 (A | | B)为真。
称为逻辑非运算符。用来反转操作数的逻辑状态。如果条件为true,则逻辑非运算符将得到false。 !(A && B)为真。

2.6.5短路逻辑运算符

当使用与逻辑运算符时,在两个操作数都为true时,结果才为true,但是当得到第一个操作为false时,其结果就必定是false,这时候就不会再判断第二个操作了。


2.6.6赋值运算符

下面是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
| = 按位或赋值操作符 C | = 2等价于C = C | 2

2.6.7条件运算符(?:)

条件运算符也被称为三元运算符。该运算符有3个操作数,并且需要判断布尔表达式的值。该运算符的主要是决定哪个值应该赋值给变量。

variable x = (expression) ? value if true : value if false

2.7Java运算符优先级

当多个运算符出现在一个表达式中,谁先谁后呢?这就涉及到运算符的优先级别的问题。在一个多运算符的表达式中,运算符优先级不同会导致最后得出的结果差别甚大。

例如,(1+3)+(3+2)*2,这个表达式如果按加号最优先计算,答案就是 18,如果按照乘号最优先,答案则是 14。

再如,x = 7 + 3 * 2;这里x得到13,而不是20,因为乘法运算符比加法运算符有较高的优先级,所以先计算3 * 2得到6,然后再加7。

下表中具有最高优先级的运算符在的表的最上面,最低优先级的在表的底部。

类别 操作符 关联性
后缀 () [] . (点操作符) 左到右
一元 expr++ expr– 从左到右
一元 ++expr --expr + - ~ ! 从右到左
乘性 * /% 左到右
加性 + - 左到右
移位 >> >>> << 左到右
关系 > >= < <= 左到右
相等 == != 左到右
按位与 左到右
按位异或 ^ 左到右
按位或 | 左到右
逻辑与 && 左到右
逻辑或 | | 左到右
条件 ?: 从右到左
赋值 = + = - = * = / =%= >> = << =&= ^ = | = 从右到左
逗号 左到右

3.Java程序控制结构

3.1顺序结构

按照程序代码顺序逐个运行

public static void main(String[] args){ 
//顺序执行,根据编写的顺序,从上到下运行 
System.out.println(1);
System.out.println(2); 
System.out.println(3); }

3.2分支结构

一个 if 语句包含一个布尔表达式和一条或多条语句。

if 语句的语法如下:

if(布尔表达式) { //如果布尔表达式为true将执行的语句 }

如果布尔表达式的值为 true,则执行 if 语句中的代码块,否则执行 if 语句块后面的代码。

实例:

public class Test {    public static void main(String args[]){      int x = 10;       if( x < 20 ){         System.out.print("这是 if 语句");      }   } }

以上代码编译运行结果如下:

这是 if 语句

3.2.1if…else语句

if…else 的用法如下:

if(布尔表达式){ //如果布尔表达式的值为true }else{ //如果布尔表达式的值为false }

public class Test {    
public static void main(String args[]){
int x = 30;       if( x < 20 ){
System.out.print("这是 if 语句");      }else{
System.out.print("这是 else 语句");      }   } }

以上代码编译运行结果如下:

这是 else 语句

if…else if…else 语句

if 语句后面可以跟 else if…else 语句,这种语句可以检测到多种可能的情况。

使用 if,else if,else 语句的时候,需要注意下面几点:

  • if 语句至多有 1 个 else 语句,else 语句在所有的 else if 语句之后。
  • if 语句可以有若干个 else if 语句,它们必须在 else 语句之前。
  • 一旦其中一个 else if 语句检测为 true,其他的 else if 以及 else 语句都将跳过执行。

if…else 语法格式如下:

if(布尔表达式 1){  
//如果布尔表达式 1的值为true执行代码
}
else if(布尔表达式 2){   //如果布尔表达式 2的值为true执行代码 }
else if(布尔表达式 3){   //如果布尔表达式 3的值为true执行代码 }
else {   //如果以上布尔表达式都不为true执行代码 }
public class Test {   public static void main(String args[]){  
int x = 30;       if( x == 10 ){
System.out.print("Value of X is 10");      }
else if( x == 20 ){ 
System.out.print("Value of X is 20");      }
else if( x == 30 ){
System.out.print("Value of X is 30");      }
else{
System.out.print("这是 else 语句");      }   } }

以上代码编译运行结果如下:

Value of X is 30

嵌套的 if…else 语句

使用嵌套的 if…else 语句是合法的。也就是说你可以在另一个 if 或者 else if 语句中使用 if 或者 else if 语句。

语法

嵌套的 if…else 语法格式如下:

if(布尔表达式 1){ 如果布尔表达式 1的值为true执行代码 if(布尔表达式 2){ 如果布尔表达式 2的值为true执行代码 } }

你可以像 if 语句一样嵌套 else if…else。

实例

public class Test {   
public static void main(String args[]){ 
int x = 30;   
int y = 10;
if( x == 30 ){   
if( y == 10 ){         
System.out.print("X = 30 and Y = 10");   
}   
}   
} 
}

以上代码编译运行结果如下:

X = 30 and Y = 10

3.2.2Java switch case 语句

switch case 语句判断一个变量与一系列值中某个值是否相等,每个值称为一个分支。

switch case 语句语法格式如下:

switch(expression){ case value : //语句 break; //可选 case value : //语句 break; //可选 //你可以有任意数量的case语句 default : //可选 //语句 }

switch case 语句有如下规则:

  • switch 语句中的变量类型可以是: byte、short、int 或者 char。从 Java SE 7 开始,switch 支持字符串 String 类型了,同时 case 标签必须为字符串常量或字面量。
  • switch 语句可以拥有多个 case 语句。每个 case 后面跟一个要比较的值和冒号。
  • case 语句中的值的数据类型必须与变量的数据类型相同,而且只能是常量或者字面常量。
  • 当变量的值与 case 语句的值相等时,那么 case 语句之后的语句开始执行,直到 break 语句出现才会跳出 switch 语句。
  • 当遇到 break 语句时,switch 语句终止。程序跳转到 switch 语句后面的语句执行。case 语句不必须要包含 break 语句。如果没有 break 语句出现,程序会继续执行下一条 case 语句,直到出现 break 语句。
  • switch 语句可以包含一个 default 分支,该分支一般是 switch 语句的最后一个分支(可以在任何位置,但建议在最后一个)。default 在没有 case 语句的值和变量值相等的时候执行。default 分支不需要 break 语句。

switch case 执行时,一定会先进行匹配,匹配成功返回当前 case 的值,再根据是否有 break,判断是否继续输出,或是跳出判断。

public class Test {   
public static void main(String args[]){     
//char grade = args[0].charAt(0);    
char grade = 'C';     
switch(grade)     
{case 'A' :System.out.println("优秀");  break; 
case 'B' :      
case 'C' :  System.out.println("良好"); break;  
case 'D' :  System.out.println("及格");  break;    
case 'F' :  System.out.println("你需要再努力努力");  break;  
default :  System.out.println("未知等级");      }    
System.out.println("你的等级是 " + grade);   } }

以上代码编译运行结果如下:

良好
你的等级是 C

3.3循环结构

3.3.1for(;{}循环

for循环语句格式: 执行流程 执行顺序:①②③④>②③④>②③④…②不满足为止。

①负责完成循环变量初始化

②负责判断是否满足循环条件,不满足则跳出循环

③具体执行的语句

④循环后,循环条件所涉及变量的变化情况

for(初始化表达式①; 布尔表达式②; 步进表达式④){ 
循环体③
}
public class Test {
   public static void main(String args[]) {
 
      for(int x = 10; x < 20; x = x+1) {
         System.out.print("value of x : " + x );
         System.out.print("\n");
      }
   }
}

3.3.2while(){}循环

while是最基本的循环,它的结构为:

while( 布尔表达式 ) {  //循环内容 }

只要布尔表达式为 true,循环就会一直执行下去。

死循环

while(true){...}

3.3.3do{} while循环

对于 while 语句而言,如果不满足条件,则不能进入循环。但有时候我们需要即使不满足条件,也至少执行一次。

do…while 循环和 while 循环相似,不同的是,do…while 循环至少会执行一次。

do {
       //代码语句
}while(布尔表达式);

**注意:**布尔表达式在循环体的后面,所以语句块在检测布尔表达式之前已经执行了。 如果布尔表达式的值为 true,则语句块一直执行,直到布尔表达式的值为 false。

4.Java面向对象基础

类是对一类事物的描述,是抽象的。

对象是一类事物的实例,是具体的。

类是对象的模板,对象是类的实体。

4.1java类基础

4.1.1类的定义格式 :

public class 类名 { //成员变量 //成员方法 }

定义类:就是定义类的成员,包括成员变量和成员方法。

成员变量:和以前定义变量几乎是一样的。只不过位置发生了改变。

在类中,方法外。 成员方法:和以前定义方法几乎是一样的。只不过把static去掉,static的作用在面向对象后面课程中再详细 讲解。

4.1.2构造方法

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

在创建一个对象的时候,至少要调用一个构造方法。

构造方法的名称必须与类同名,一个类可以有多个构造方法。

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

public class 类名{  
String name;
public 类名(){    }     
public 类名(String name){        // 这个构造器仅有一个参数:name    }
}

4.1.3创建对象

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

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

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

public class Puppy{   public Puppy(String name){ 
    //这个构造器仅有一个参数:name     
    System.out.println("小狗的名字是 : " + name );    } 
public static void main(String[] args){ 
    // 下面的语句将创建一个Puppy对象    
    Puppy myPuppy = new Puppy( "tommy" );   } }

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

小狗的名字是 : tommy

4.2封装

  1. private是一个权限修饰符,代表最小权限。

    2.可以修饰成员变量和成员方法。

    1. 被private修饰后的成员变量和成员方法,只在本类中才能访问。

格式

private 数据类型 变量;

提供 getXxx 方法 /setXxx 方法,可以访问成员变量,代码如下:

public class Student {
private String name;
private int age;
public void setName(String n) {
name = n;
}
public String getName() {
return name;
}
public void setAge(int a) {
age = a;
}
public int getAge() {
return age;
}
}

4.3继承

继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。

继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为

关键字:extends

用法

class 父类{}
class 子类 extends 父类{}

4.3.1继承的特性

  • 子类拥有父类非 private 的属性、方法。
  • 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
  • 子类可以用自己的方式实现父类的方法。
  • Java 的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如 B 类继承 A 类,C 类继承 B 类,所以按照关系就是 B 类是 C 类的父类,A 类是 B 类的父类,这是 Java 继承区别于 C++ 继承的一个特性。
  • 提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)。

4.3.2super 与 this 关键字

super关键字:我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。

this关键字:指向自己的引用。

class Animal {  void eat() {   
System.out.println("animal : eat");  
} }
class Dog extends Animal { 
void eat() { 
System.out.println("dog : eat"); 
}  
void eatTest() {  
this.eat();  
// this 调用自己的方法  
super.eat();  
        // super 调用父  类方法  } }  
        public class Test { 
        public static void main(String[] args) {  
        Animal a = new Animal();   
        a.eat();  
        Dog d = new Dog(); 
        d.eatTest();  } }

输出结果为:

animal : eat
dog : eat
animal : eat

4.4多态

多态是同一个行为具有多个不同表现形式或形态的能力。

多态就是同一个接口,使用不同的实例而执行不同操作.

多态存在的三个必要条件

  • 继承
  • 重写
  • 父类引用指向子类对象

多态体现的格式: 父类类型:指子类对象继承的父类类型,或者实现的父接口类型。

代码如下: 当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,执行的是子类重写 后方法。

格式

父类类型 变量名 = new 子类对象;
变量名.方法名();

实例


class** Shape {
  **void** draw() {}
}

**class** Circle **extends** Shape {
  **void** draw() {
    System.out.println("Circle.draw()");
  }
}

**class** Square **extends** Shape {
  **void** draw() {
    System.out.println("Square.draw()");
  }
}

**class** Triangle **extends** Shape {
  **void** draw() {
    System.out.println("Triangle.draw()");
  }
}

当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。

多态的好处:可以使程序有良好的扩展,并可以对所有类的对象进行通用处理。

以下是一个多态实例的演示,详细说明请看注释:

public class Test {
    public static void main(String[] args) {
      show(new Cat());  // 以 Cat 对象调用 show 方法
      show(new Dog());  // 以 Dog 对象调用 show 方法
                
      Animal a = new Cat();  // 向上转型  
      a.eat();               // 调用的是 Cat 的 eat
      Cat c = (Cat)a;        // 向下转型  
      c.work();        // 调用的是 Cat 的 work
  }  
            
    public static void show(Animal a)  {
      a.eat();  
        // 类型判断
        if (a instanceof Cat)  {  // 猫做的事情 
            Cat c = (Cat)a;  
            c.work();  
        } else if (a instanceof Dog) { // 狗做的事情 
            Dog c = (Dog)a;  
            c.work();  
        }  
    }  
}
 
abstract class Animal {  
    abstract void eat();  
}  
  
class Cat extends Animal {  
    public void eat() {  
        System.out.println("吃鱼");  
    }  
    public void work() {  
        System.out.println("抓老鼠");  
    }  
}  
  
class Dog extends Animal {  
    public void eat() {  
        System.out.println("吃骨头");  
    }  
    public void work() {  
        System.out.println("看家");  
    }  
}

引用类型转换

多态的转型分为向上转型与向下转型两种:

向上转型:多态本身是子类类型向父类类型向上转换的过程,这个过程是默认的。 当父类引用指向一个子类对象时,便是向上转型。 使用格式:

父类类型 变量名 = new 子类类型();
如:Animal a = new Cat();

向下转型:父类类型向子类类型向下转换的过程,这个过程是强制的。

一个已经向上转型的子类对象,将父类引用转为子类引用,可以使用强制类型转换的格式,便是向下转型。 使用格式:

子类类型 变量名 = (子类类型) 父类变量名;:Cat c =(Cat) a;

5.Java抽象类和接口

关键字:abstract

在 Java 语言中使用 abstract class 来定义抽象类

使用 abstract 关键字修饰方法,该方法就成了抽象方法,抽象方法只包含一个方法名,而没有方法体。 定义格式:

修饰符 abstract 返回值类型 方法名 (参数列表);

5.1抽象类

**继承抽象类的子类必须重写父类所有的抽象方法。**否则,该子类也必须声明为抽象类。最终,必须有子类实现该父 类的抽象方法,否则,从最初的父类到最终的子类都不能创建对象,失去意义。 代码举例:

public abstract class Animal {
public abstract void run()}
public class Cat extends Animal {
public void run (){
System.out.println("小猫在墙头走~~~")}
}
public class CatTest {
public static void main(String[] args) {
// 创建子类对象
Cat c = new Cat();
// 调用run方法
c.run();
}
}
输出结果:
小猫在墙头走~~~

实例

定义抽象类

public abstract class Employee
{
   private String name;
   private String address;
   private int number;
   public Employee(String name, String address, int number)
   {
      System.out.println("Constructing an Employee");
      this.name = name;
      this.address = address;
      this.number = number;
   }
   public double computePay()
   {
     System.out.println("Inside Employee computePay");
     return 0.0;
   }
   public void mailCheck()
   {
      System.out.println("Mailing a check to " + this.name
       + " " + this.address);
   }
   public String toString()
   {
      return name + " " + address + " " + number;
   }
   public String getName()
   {
      return name;
   }
   public String getAddress()
   {
      return address;
   }
   public void setAddress(String newAddress)
   {
      address = newAddress;
   }
   public int getNumber()
   {
     return number;
   }
}

尽管我们不能实例化一个 Employee 类的对象,但是如果我们实例化一个 Salary 类对象,该对象将从 Employee 类继承 7 个成员方法,且通过该方法可以设置或获取三个成员变量。

继承抽象类

我们可以通过以下方式继承 Employee 类的属性:

public class Salary extends Employee
{
   private double salary; //Annual salary
   public Salary(String name, String address, int number, double
      salary)
   {
       super(name, address, number);
       setSalary(salary);
   }
   public void mailCheck()
   {
       System.out.println("Within mailCheck of Salary class ");
       System.out.println("Mailing check to " + getName()
       + " with salary " + salary);
   }
   public double getSalary()
   {
       return salary;
   }
   public void setSalary(double newSalary)
   {
       if(newSalary >= 0.0)
       {
          salary = newSalary;
       }
   }
   public double computePay()
   {
      System.out.println("Computing salary pay for " + getName());
      return salary/52;
   }
}

尽管我们不能实例化一个 Employee 类的对象,但是如果我们实例化一个 Salary 类对象,该对象将从 Employee 类继承 7 个成员方法,且通过该方法可以设置或获取三个成员变量。

public class AbstractDemo
{
   public static void main(String [] args)
   {
      Salary s = new Salary("Mohd Mohtashim", "Ambehta, UP", 3, 3600.00);
      Employee e = new Salary("John Adams", "Boston, MA", 2, 2400.00);
 
      System.out.println("Call mailCheck using Salary reference --");
      s.mailCheck();
 
      System.out.println("\n Call mailCheck using Employee reference--");
      e.mailCheck();
    }
}

以上程序编译运行结果如下:

Constructing an Employee
Constructing an Employee
Call mailCheck using  Salary reference --
Within mailCheck of Salary class
Mailing check to Mohd Mohtashim with salary 3600.0

Call mailCheck using Employee reference--
Within mailCheck of Salary class
Mailing check to John Adams with salary 2400.

5.2抽象方法

如果你想设计这样一个类,该类包含一个特别的成员方法,该方法的具体实现由它的子类确定,那么你可以在父类中声明该方法为抽象方法。

Abstract 关键字同样可以用来声明抽象方法,抽象方法只包含一个方法名,而没有方法体。

抽象方法没有定义,方法名后面直接跟一个分号,而不是花括号。

实例

public abstract class Employee//抽象类
{
   private String name;
   private String address;
   private int number;
   
   public abstract double computePay();、、抽象方法
   
   //其余代码
}

声明抽象方法会造成以下两个结果:

  • 如果一个类包含抽象方法,那么该类必须是抽象类。
  • 任何子类必须重写父类的抽象方法,或者声明自身为抽象类。

继承抽象方法的子类必须重写该方法。否则,该子类也必须声明为抽象类。最终,必须有子类实现该抽象方法,否则,从最初的父类到最终的子类都不能用来实例化对象。

如果Salary类继承了Employee类,那么它必须实现computePay()方法:

代码如下

public class Salary extends Employee {   
private double salary; // Annual salary     
public double computePay()   {     
System.out.println("Computing salary pay for " + getName());      
return salary/52;  
}    //其余代码 }

5.3抽象类总结规定

  • 抽象类不能被实例化(初学者很容易犯的错),如果被实例化,就会报错,编译无法通过。只有抽象类的非抽象子类可以创建对象。
  • 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
  • 抽象类中的抽象方法只是声明,不包含方法体,就是不给出方法的具体实现也就是方法的具体功能。
  • 构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法。
  • 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。

5.4接口

5.4.1用法

接口的定义,它与定义类方式相似,但是使用 interface 关键字。它也会被编译成.class文件,但一定要明确它并 不是类,而是另外一种引用数据类型。

public interface 接口名称 {
// 抽象方法
// 默认方法
// 静态方法
// 私有方法
}

含有抽象方法 抽象方法:使用 abstract 关键字修饰,可以省略,没有方法体。该方法供子类实现使用。 代码如下:

public interface 接口名 {
public abstract void 方法名();
}

用法

class 类名 implements 接口名 {
// 重写接口中抽象方法【必须】
// 重写接口中默认方法【可选】
}

一个接口能继承另一个或者多个接口,这和类之间的继承比较相似。接口的继承使用 extends 关键字,子接口继 承父接口的方法。如果父接口中的默认方法有重名的,那么子接口需要重写一次。

class 类名 extends 父类 implements 接口名1,接口名2 {
// 重写接口中抽象方法【必须】
// 重写接口中默认方法【可选】
}

5.4.2接口与类相似点:

  • 一个接口可以有多个方法。
  • 接口文件保存在 .java 结尾的文件中,文件名使用接口名。
  • 接口的字节码文件保存在 .class 结尾的文件中。
  • 接口相应的字节码文件必须在与包名称相匹配的目录结构中。

5.4.3接口与类的区别:

  • 接口不能用于实例化对象。
  • 接口没有构造方法。
  • 接口中所有的方法必须是抽象方法,Java 8 之后 接口中可以使用 default 关键字修饰的非抽象方法。
  • 接口不能包含成员变量,除了 static 和 final 变量。
  • 接口不是被类继承了,而是要被类实现。
  • 接口支持多继承。

6.Java数组和常用类

6.1数组

数组创建

数组存储的数据类型[] 数组名字 = new 数组存储的数据类型[长度];
数据类型[] 数组名 = new 数据类型[]{元素1,元素2,元素3...};
数据类型[] 数组名 = {元素1,元素2,元素3...};

格式: 数组定义格式详解:

数组存储的数据类型: 创建的数组容器可以存储什么数据类型。

[] : 表示数组。 数组名字:为定义的数组起个变量名,满足标识符规范,可以使用名字操作数组。

new:关键字,创建数组使用的关键字。

数组存储的数据类型: 创建的数组容器可以存储什么数据类型。

[长度]:数组的长度,表示数组容器中可以存储多少个元素。

注意:数组有定长特性,长度一旦指定,不可更改

6.2String 方法

下面是 String 类支持的方法

SN(序号) 方法描述
1 char charAt(int index) 返回指定索引处的 char 值。
2 int compareTo(Object o) 把这个字符串和另一个对象比较。
3 int compareTo(String anotherString) 按字典顺序比较两个字符串。
4 int compareToIgnoreCase(String str) 按字典顺序比较两个字符串,不考虑大小写。
5 String concat(String str) 将指定字符串连接到此字符串的结尾。
6 boolean contentEquals(StringBuffer sb) 当且仅当字符串与指定的StringBuffer有相同顺序的字符时候返回真。
7 [static String copyValueOf(char] data) 返回指定数组中表示该字符序列的 String。
8 [static String copyValueOf(char] data, int offset, int count) 返回指定数组中表示该字符序列的 String。
9 boolean endsWith(String suffix) 测试此字符串是否以指定的后缀结束。
10 boolean equals(Object anObject) 将此字符串与指定的对象比较。
11 boolean equalsIgnoreCase(String anotherString) 将此 String 与另一个 String 比较,不考虑大小写。
12 [byte] getBytes() 使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。
13 [byte] getBytes(String charsetName) 使用指定的字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。
14 [void getChars(int srcBegin, int srcEnd, char] dst, int dstBegin) 将字符从此字符串复制到目标字符数组。
15 int hashCode() 返回此字符串的哈希码。
16 int indexOf(int ch) 返回指定字符在此字符串中第一次出现处的索引。
17 int indexOf(int ch, int fromIndex) 返回在此字符串中第一次出现指定字符处的索引,从指定的索引开始搜索。
18 int indexOf(String str) 返回指定子字符串在此字符串中第一次出现处的索引。
19 int indexOf(String str, int fromIndex) 返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始。
20 String intern() 返回字符串对象的规范化表示形式。
21 int lastIndexOf(int ch) 返回指定字符在此字符串中最后一次出现处的索引。
22 int lastIndexOf(int ch, int fromIndex) 返回指定字符在此字符串中最后一次出现处的索引,从指定的索引处开始进行反向搜索。
23 int lastIndexOf(String str) 返回指定子字符串在此字符串中最右边出现处的索引。
24 int lastIndexOf(String str, int fromIndex) 返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索。
25 int length() 返回此字符串的长度。
26 boolean matches(String regex) 告知此字符串是否匹配给定的正则表达式。
27 boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len) 测试两个字符串区域是否相等。
28 boolean regionMatches(int toffset, String other, int ooffset, int len) 测试两个字符串区域是否相等。
29 String replace(char oldChar, char newChar) 返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的。
30 String replaceAll(String regex, String replacement) 使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。
31 String replaceFirst(String regex, String replacement) 使用给定的 replacement 替换此字符串匹配给定的正则表达式的第一个子字符串。
32 [String] split(String regex) 根据给定正则表达式的匹配拆分此字符串。
33 [String] split(String regex, int limit) 根据匹配给定的正则表达式来拆分此字符串。
34 boolean startsWith(String prefix) 测试此字符串是否以指定的前缀开始。
35 boolean startsWith(String prefix, int toffset) 测试此字符串从指定索引开始的子字符串是否以指定前缀开始。
36 CharSequence subSequence(int beginIndex, int endIndex) 返回一个新的字符序列,它是此序列的一个子序列。
37 String substring(int beginIndex) 返回一个新的字符串,它是此字符串的一个子字符串。
38 String substring(int beginIndex, int endIndex) 返回一个新字符串,它是此字符串的一个子字符串。
39 [char] toCharArray() 将此字符串转换为一个新的字符数组。
40 String toLowerCase() 使用默认语言环境的规则将此 String 中的所有字符都转换为小写。
41 String toLowerCase(Locale locale) 使用给定 Locale 的规则将此 String 中的所有字符都转换为小写。
42 String toString() 返回此对象本身(它已经是一个字符串!)。
43 String toUpperCase() 使用默认语言环境的规则将此 String 中的所有字符都转换为大写。
44 String toUpperCase(Locale locale) 使用给定 Locale 的规则将此 String 中的所有字符都转换为大写。
45 String trim() 返回字符串的副本,忽略前导空白和尾部空白。
46 static String valueOf(primitive data type x) 返回给定data type类型x参数的字符串表示形式。
47 contains(CharSequence chars) 判断是否包含指定的字符系列。
48 isEmpty() 判断字符串是否为空。

6.3Number & Math 类方法

下面的表中列出的是 Number & Math 类常用的一些方法:

序号 方法与描述
1 xxxValue() 将 Number 对象转换为xxx数据类型的值并返回。
2 compareTo() 将number对象与参数比较。
3 equals() 判断number对象是否与参数相等。
4 valueOf() 返回一个 Number 对象指定的内置数据类型
5 toString() 以字符串形式返回值。
6 parseInt() 将字符串解析为int类型。
7 abs() 返回参数的绝对值。
8 ceil() 返回大于等于( >= )给定参数的的最小整数,类型为双精度浮点型。
9 floor() 返回小于等于(<=)给定参数的最大整数 。
10 rint() 返回与参数最接近的整数。返回类型为double。
11 round() 它表示四舍五入,算法为 Math.floor(x+0.5),即将原来的数字加上 0.5 后再向下取整,所以,Math.round(11.5) 的结果为12,Math.round(-11.5) 的结果为-11。
12 min() 返回两个参数中的最小值。
13 max() 返回两个参数中的最大值。
14 exp() 返回自然数底数e的参数次方。
15 log() 返回参数的自然数底数的对数值。
16 pow() 返回第一个参数的第二个参数次方。
17 sqrt() 求参数的算术平方根。
18 sin() 求指定double类型参数的正弦值。
19 cos() 求指定double类型参数的余弦值。
20 tan() 求指定double类型参数的正切值。
21 asin() 求指定double类型参数的反正弦值。
22 acos() 求指定double类型参数的反余弦值。
23 atan() 求指定double类型参数的反正切值。
24 atan2() 将笛卡尔坐标转换为极坐标,并返回极坐标的角度值。
25 toDegrees() 将参数转化为角度。
26 toRadians() 将角度转换为弧度。
27 random() 返回一个随机数。

实例

public class Test {
    public static void main(String[] args) {
        System.out.println(Math.abs(-5));//绝对值
        System.out.println(Math.ceil(24.11));//向上取整
        System.out.println(Math.floor(24.99));//向下取整
        System.out.println(Math.max(1,4));//求最大值
        System.out.println(Math.min(1,4));//求最小值
        System.out.println(Math.pow(4,2));//求幂值
        System.out.println(Math.random());//0到1随机数
        System.out.println(Math.round(6.5));//四舍五入
        System.out.println(Math.round(6.4));//
        System.out.println(Math.sqrt(9));//完全平方根
    }
}

7.Java集合和泛型

7.1集合接口

集合框架定义了一些接口。本节提供了每个接口的概述:

序号 接口描述
1 Collection 接口 Collection 是最基本的集合接口,一个 Collection 代表一组 Object,即 Collection 的元素, Java不提供直接继承自Collection的类,只提供继承于的子接口(如List和set)。Collection 接口存储一组不唯一,无序的对象。
2 List 接口 List接口是一个有序的 Collection,使用此接口能够精确的控制每个元素插入的位置,能够通过索引(元素在List中位置,类似于数组的下标)来访问List中的元素,第一个元素的索引为 0,而且允许有相同的元素。List 接口存储一组不唯一,有序(插入顺序)的对象。
3 Set Set 具有与 Collection 完全一样的接口,只是行为上不同,Set 不保存重复的元素。Set 接口存储一组唯一,无序的对象。
4 SortedSet 继承于Set保存有序的集合。
5 Map Map 接口存储一组键值对象,提供key(键)到value(值)的映射。
6 Map.Entry 描述在一个Map中的一个元素(键/值对)。是一个 Map 的内部接口。
7 SortedMap 继承于 Map,使 Key 保持在升序排列。
8 Enumeration 这是一个传统的接口和定义的方法,通过它可以枚举(一次获得一个)对象集合中的元素。这个传统接口已被迭代器取代。

Set和List的区别

  • \1. Set 接口实例存储的是无序的,不重复的数据。List 接口实例存储的是有序的,可以重复的元素。
  • \2. Set检索效率低下,删除和插入效率高,插入和删除不会引起元素位置改变 <实现类有HashSet,TreeSet>
  • \3. List和数组类似,可以动态增长,根据实际存储的数据的长度自动增长List的长度。查找元素效率高,插入删除效率低,因为会引起其他元素位置改变 <实现类有ArrayList,LinkedList,Vector>

7.2Java Iterator(迭代器)

Java Iterator(迭代器)不是一个集合,它是一种用于访问集合的方法,可用于迭代 ArrayList 和 HashSet 等集合。

Iterator 是 Java 迭代器最简单的实现,ListIterator 是 Collection API 中的接口, 它扩展了 Iterator 接口。

使用方法:

// 引入 ArrayList 和 Iterator 类
import java.util.ArrayList;
import java.util.Iterator;

public class RunoobTest {
    public static void main(String[] args) {

        // 创建集合
        ArrayList<String> sites = new ArrayList<String>();
        sites.add("Google");
        sites.add("Runoob");
        sites.add("Taobao");
        sites.add("Zhihu");

        // 获取迭代器
        Iterator<String> it = sites.iterator();

        // 输出集合中的第一个元素
        System.out.println(it.next());
    }
}

7.3Java ArrayList 方法

Java ArrayList 常用方法列表如下:

方法 描述
add() 将元素插入到指定位置的 arraylist 中
addAll() 添加集合中的所有元素到 arraylist 中
clear() 删除 arraylist 中的所有元素
clone() 复制一份 arraylist
contains() 判断元素是否在 arraylist
get() 通过索引值获取 arraylist 中的元素
indexOf() 返回 arraylist 中元素的索引值
removeAll() 删除存在于指定集合中的 arraylist 里的所有元素
remove() 删除 arraylist 里的单个元素
size() 返回 arraylist 里元素数量
isEmpty() 判断 arraylist 是否为空
subList() 截取部分 arraylist 的元素
set() 替换 arraylist 中指定索引的元素
sort() 对 arraylist 元素进行排序
toArray() 将 arraylist 转换为数组
toString() 将 arraylist 转换为字符串
ensureCapacity() 设置指定容量大小的 arraylist
lastIndexOf() 返回指定元素在 arraylist 中最后一次出现的位置
retainAll() 保留 arraylist 中在指定集合中也存在的那些元素
containsAll() 查看 arraylist 是否包含指定集合中的所有元素
trimToSize() 将 arraylist 中的容量调整为数组中的元素个数
removeRange() 删除 arraylist 中指定索引之间存在的元素
replaceAll() 将给定的操作内容替换掉数组中每一个元素
removeIf() 删除所有满足特定条件的 arraylist 元素
forEach() 遍历 arraylist 中每一个元素并执行特定操作

实例

import java.util.ArrayList;
import java.util.Random;

public class ArrayListDemo {
    public static void main(String[] args) {
        ArrayList<Integer> A=new ArrayList<>();
        System.out.println(A);
        A.add(1);
        A.add(2);
        A.add(3);
        A.add(4);
        A.add(5);
        A.add(6);
        System.out.println(A);
                for (int i = 0; i <A.size(); i++) {
            System.out.println(A.get(i));
        }
        System.out.println("A集合长度:"+A.size());
        System.out.println("移除第五个元素:"+A.remove(4));

        System.out.println(A);

        A.removeAll(A);
        System.out.println(A);
   


    }
}

7.4java Linkedlist方法

方法 描述
public boolean add(E e) 链表末尾添加元素,返回是否成功,成功为 true,失败为 false。
public void add(int index, E element) 向指定位置插入元素。
public boolean addAll(Collection c) 将一个集合的所有元素添加到链表后面,返回是否成功,成功为 true,失败为 false。
public boolean addAll(int index, Collection c) 将一个集合的所有元素添加到链表的指定位置后面,返回是否成功,成功为 true,失败为 false。
public void addFirst(E e) 元素添加到头部。
public void addLast(E e) 元素添加到尾部。
public boolean offer(E e) 向链表末尾添加元素,返回是否成功,成功为 true,失败为 false。
public boolean offerFirst(E e) 头部插入元素,返回是否成功,成功为 true,失败为 false。
public boolean offerLast(E e) 尾部插入元素,返回是否成功,成功为 true,失败为 false。
public void clear() 清空链表。
public E removeFirst() 删除并返回第一个元素。
public E removeLast() 删除并返回最后一个元素。
public boolean remove(Object o) 删除某一元素,返回是否成功,成功为 true,失败为 false。
public E remove(int index) 删除指定位置的元素。
public E poll() 删除并返回第一个元素。
public E remove() 删除并返回第一个元素。
public boolean contains(Object o) 判断是否含有某一元素。
public E get(int index) 返回指定位置的元素。
public E getFirst() 返回第一个元素。
public E getLast() 返回最后一个元素。
public int indexOf(Object o) 查找指定元素从前往后第一次出现的索引。
public int lastIndexOf(Object o) 查找指定元素最后一次出现的索引。
public E peek() 返回第一个元素。
public E element() 返回第一个元素。
public E peekFirst() 返回头部元素。
public E peekLast() 返回尾部元素。
public E set(int index, E element) 设置指定位置的元素。
public Object clone() 克隆该列表。
public Iterator descendingIterator() 返回倒序迭代器。
public int size() 返回链表元素个数。
public ListIterator listIterator(int index) 返回从指定位置开始到末尾的迭代器。
public Object[] toArray() 返回一个由链表元素组成的数组。
public T[] toArray(T[] a) 返回一个由链表元素转换类型而成的数组。

例子

import java.util.LinkedList;

 public  class  RunoobTest {
 public  static void  main(String[] args) {
    LinkedList<String> sites =  new  LinkedList<String>();
    sites.add("Google");
    sites.add("Runoob");
    sites.add("Taobao");
    sites.add("Weibo");
    System.out.println(sites);
  }
}

7.5Java HashMa

HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。

HashMap 实现了 Map 接口,根据键的 HashCode 值存储数据,具有很快的访问速度,最多允许一条记录的键为 null,不支持线程同步。

HashMap 是无序的,即不会记录插入的顺序。

HashMap 继承于AbstractMap,实现了 Map、Cloneable、java.io.Serializable 接口。

HashMap 类提供了很多有用的方法,添加键值对(key-value)可以使用 put() 方法:

// 引入 HashMap 类      
import java.util.HashMap;

public class RunoobTest {
    public static void main(String[] args) {
        // 创建 HashMap 对象 Sites
        HashMap Sites = new HashMap();
        // 添加键值对
        Sites.put(1, "Google");
        Sites.put(2, "Runoob");
        Sites.put(3, "Taobao");
        Sites.put(4, "Zhihu");
        System.out.println(Sites);
    }
}

执行以上代码,输出结果如下:

{1=Google, 2=Runoob, 3=Taobao, 4=Zhihu}

7.5.1Java HashMap 方法

hashmap

Java HashMap 常用方法列表如下:

方法 描述
clear() 删除 hashMap 中的所有键/值对
clone() 复制一份 hashMap
isEmpty() 判断 hashMap 是否为空
size() 计算 hashMap 中键/值对的数量
put() 将键/值对添加到 hashMap 中
putAll() 将所有键/值对添加到 hashMap 中
putIfAbsent() 如果 hashMap 中不存在指定的键,则将指定的键/值对插入到 hashMap 中。
remove() 删除 hashMap 中指定键 key 的映射关系
containsKey() 检查 hashMap 中是否存在指定的 key 对应的映射关系。
containsValue() 检查 hashMap 中是否存在指定的 value 对应的映射关系。
replace() 替换 hashMap 中是指定的 key 对应的 value。
replaceAll() 将 hashMap 中的所有映射关系替换成给定的函数所执行的结果。
get() 获取指定 key 对应对 value
getOrDefault() 获取指定 key 对应对 value,如果找不到 key ,则返回设置的默认值
forEach() 对 hashMap 中的每个映射执行指定的操作。
entrySet() 返回 hashMap 中所有映射项的集合集合视图。
keySet() 返回 hashMap 中所有 key 组成的集合视图。
values() 返回 hashMap 中存在的所有 value 值。
merge() 添加键值对到 hashMap 中
compute() 对 hashMap 中指定 key 的值进行重新计算
computeIfAbsent() 对 hashMap 中指定 key 的值进行重新计算,如果不存在这个 key,则添加到 hasMap 中
computeIfPresent() 对 hashMap 中指定 key 的值进行重新计算,前提是该 key 存在于 hashMap 中。

7.6Java 泛型

Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。

泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。

格式

ArrayList list = new ArrayList();

String可替换其他数据类型

8.Java异常处理机制

8.1异常

异常(exception)是在运行程序时产生的一种异常情况。异常又称为例外,是一个在程序执行期间发生的事件,它中断正在执行程序的正常指令流。为了能够及时有效地处理程序中的运行错误,必须使用异常类,这可以让程序具有极好的容错性且更加健壮。

在 Java 中一个异常的产生,主要有如下三种原因:

  1. Java 内部错误发生异常,Java 虚拟机产生的异常。
  2. 编写的程序代码中的错误所产生的异常,例如空指针异常、数组越界异常等。
  3. 通过 throw 语句手动生成的异常,一般用来告知该方法的调用者一些必要信息。

Java 通过面向对象的方法来处理异常。在一个方法的运行过程中,如果发生了异常,则这个方法会产生代表该异常的一个对象,并把它交给运行时的系统,运行时系统寻找相应的代码来处理这一异常。

我们把生成异常对象,并把它提交给运行时系统的过程称为拋出(throw)异常。运行时系统在方法的调用栈中查找,直到找到能够处理该类型异常的对象,这一个过程称为捕获(catch)异常。

8.2Java 内置异常类

Java 语言定义了一些异常类在 java.lang 标准包中。

标准运行时异常类的子类是最常见的异常类。由于 java.lang 包是默认加载到所有的 Java 程序的,所以大部分从运行时异常类继承而来的异常都可以直接使用。

Java 根据各个类库也定义了一些其他的异常,下面的表中列出了 Java 的非检查性异常。

异常 描述
ArithmeticException 当出现异常的运算条件时,抛出此异常。例如,一个整数"除以零"时,抛出此类的一个实例。
ArrayIndexOutOfBoundsException 用非法索引访问数组时抛出的异常。如果索引为负或大于等于数组大小,则该索引为非法索引。
ArrayStoreException 试图将错误类型的对象存储到一个对象数组时抛出的异常。
ClassCastException 当试图将对象强制转换为不是实例的子类时,抛出该异常。
IllegalArgumentException 抛出的异常表明向方法传递了一个不合法或不正确的参数。
IllegalMonitorStateException 抛出的异常表明某一线程已经试图等待对象的监视器,或者试图通知其他正在等待对象的监视器而本身没有指定监视器的线程。
IllegalStateException 在非法或不适当的时间调用方法时产生的信号。换句话说,即 Java 环境或 Java 应用程序没有处于请求操作所要求的适当状态下。
IllegalThreadStateException 线程没有处于请求操作所要求的适当状态时抛出的异常。
IndexOutOfBoundsException 指示某排序索引(例如对数组、字符串或向量的排序)超出范围时抛出。
NegativeArraySizeException 如果应用程序试图创建大小为负的数组,则抛出该异常。
NullPointerException 当应用程序试图在需要对象的地方使用 null 时,抛出该异常
NumberFormatException 当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时,抛出该异常。
SecurityException 由安全管理器抛出的异常,指示存在安全侵犯。
StringIndexOutOfBoundsException 此异常由 String 方法抛出,指示索引或者为负,或者超出字符串的大小。
UnsupportedOperationException 当不支持请求的操作时,抛出该异常。

Error和Exception的异同

Error(错误)和 Exception(异常)都是 java.lang.Throwable 类的子类,在 Java 代码中只有继承了 Throwable 类的实例才能被 throw 或者 catch。

Exception 和 Error 体现了 Java 平台设计者对不同异常情况的分类,Exception 是程序正常运行过程中可以预料到的意外情况,并且应该被开发者捕获,进行相应的处理。Error 是指正常情况下不大可能出现的情况,绝大部分的 Error 都会导致程序处于非正常、不可恢复状态。所以不需要被开发者捕获。

Error 错误是任何处理技术都无法恢复的情况,肯定会导致程序非正常终止。并且 Error 错误属于未检查类型,大多数发生在运行时。Exception 又分为可检查(checked)异常和不检查(unchecked)异常,可检查异常在源码里必须显示的进行捕获处理,这里是编译期检查的一部分。不检查异常就是所谓的运行时异常,通常是可以编码避免的逻辑错误,具体根据需要来判断是否需要捕获,并不会在编译器强制要求。

如下是常见的 Error 和 Exception:

1)运行时异常(RuntimeException):

  • NullPropagation:空指针异常;
  • ClassCastException:类型强制转换异常
  • IllegalArgumentException:传递非法参数异常
  • IndexOutOfBoundsException:下标越界异常
  • NumberFormatException:数字格式异常

2)非运行时异常:

  • ClassNotFoundException:找不到指定 class 的异常
  • IOException:IO 操作异常

3)错误(Error):

  • NoClassDefFoundError:找不到 class 定义异常
  • StackOverflowError:深递归导致栈被耗尽而抛出的异常
  • OutOfMemoryError:内存溢出异常

8.3异常方法

下面的列表是 Throwable 类的主要方法:

序号 方法及说明
1 public String getMessage() 返回关于发生的异常的详细信息。这个消息在Throwable 类的构造函数中初始化了。
2 public Throwable getCause() 返回一个Throwable 对象代表异常原因。
3 public String toString() 使用getMessage()的结果返回类的串级名字。
4 public void printStackTrace() 打印toString()结果和栈层次到System.err,即错误输出流。
5 public StackTraceElement [] getStackTrace() 返回一个包含堆栈层次的数组。下标为0的元素代表栈顶,最后一个元素代表方法调用堆栈的栈底。
6 public Throwable fillInStackTrace() 用当前的调用栈层次填充Throwable 对象栈层次,添加到栈层次任何先前信息中。

8.4捕获异常

使用 try 和 catch 关键字可以捕获异常。try/catch 代码块放在异常可能发生的地方。

try/catch代码块中的代码称为保护代码,使用 try/catch 的语法如下:

try
{
   // 程序代码
}catch(ExceptionName e1)
{
   //Catch 块
}

Catch 语句包含要捕获异常类型的声明。当保护代码块中发生一个异常时,try 后面的 catch 块就会被检查。

如果发生的异常包含在 catch 块中,异常会被传递到该 catch 块,这和传递一个参数到方法是一样。

8.4.1多重捕获块

一个 try 代码块后面跟随多个 catch 代码块的情况就叫多重捕获。

多重捕获块的语法如下所示:

try{   // 程序代码 }
    catch(异常类型1 异常的变量名1){  // 程序代码 }
        catch(异常类型2 异常的变量名2){  // 程序代码 }
            catch(异常类型3 异常的变量名3){  // 程序代码 }

8.5throws 声明异常

当一个方法产生一个它不处理的异常时,那么就需要在该方法的头部声明这个异常,以便将该异常传递到方法的外部进行处理。使用 throws 声明的方法表示此方法不处理异常。throws 具体格式如下:

returnType method_name(paramList) throws Exception 1,Exception2,{}

其中,returnType 表示返回值类型;method_name 表示方法名;paramList 表示参数列表;Exception 1,Exception2,… 表示异常类。

throws/throw 关键字:

如果一个方法没有捕获到一个检查性异常,那么该方法必须使用 throws 关键字来声明。throws 关键字放在方法签名的尾部。

也可以使用 throw 关键字抛出一个异常,无论它是新实例化的还是刚捕获到的。

下面方法的声明抛出一个 RemoteException 异常:

import java.io.*; public class className { public void deposit(double amount) throws RemoteException { // Method implementation throw new RemoteException(); } //Remainder of class definition }

一个方法可以声明抛出多个异常,多个异常之间用逗号隔开。

例如,下面的方法声明抛出 RemoteException 和 InsufficientFundsException:

import java.io.*; public class className { public void withdraw(double amount) throws RemoteException, InsufficientFundsException { // Method implementation } //Remainder of class definition }


8.6finally关键字

finally 关键字用来创建在 try 代码块后面执行的代码块。

无论是否发生异常,finally 代码块中的代码总会被执行。

在 finally 代码块中,可以运行清理类型等收尾善后性质的语句。

finally 代码块出现在 catch 代码块最后,语法如下:

try{ // 程序代码 }catch(异常类型1 异常的变量名1){ // 程序代码 }catch(异常类型2 异常的变量名2){ // 程序代码 }finally{ // 程序代码 }

案例

public class ExcepTest{  public static void main(String args[]){    
    int a[] = new int[2];  
    try{      
        System.out.println("Access element three :" + a[3]);  
    }
    catch(ArrayIndexOutOfBoundsException e)
    {       
        System.out.println("Exception thrown  :" + e);  
    } 
    finally{
        a[0] = 6; 
        System.out.println("First element value: " +a[0]);     
        System.out.println("The finally statement is executed");   
           }  } }

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

Exception thrown  :java.lang.ArrayIndexOutOfBoundsException: 3
First element value: 6
The finally statement is executed

注意下面事项:

  • catch 不能独立于 try 存在。
  • 在 try/catch 后面添加 finally 块并非强制性要求的。
  • try 代码后不能既没 catch 块也没 finally 块。
  • try, catch, finally 块之间不能添加任何代码。

8.7声明自定义异常

在 Java 中你可以自定义异常。编写自己的异常类时需要记住下面的几点。

  • 所有异常都必须是 Throwable 的子类。
  • 如果希望写一个检查性异常类,则需要继承 Exception 类。
  • 如果你想写一个运行时异常类,那么需要继承 RuntimeException 类。

可以像下面这样定义自己的异常类:

class MyException extends Exception{ }

只继承Exception 类来创建的异常类是检查性异常类。

下面的 InsufficientFundsException 类是用户定义的异常类,它继承自 Exception。

一个异常类和其它任何类一样,包含有变量和方法。

案例1

package yichang;

import java.util.Scanner;


class LoginException extends Exception{
    LoginException() {
        super();
    }

    public LoginException(String msg) {
        super(msg);
    }




}
public class Test {
    public boolean validatelogin(String username,String pwd) {
        boolean con=false;
        boolean conUname=false;
        try {
            if(username.length()>=6&&username.length()<=10) {

                for(int i=0;i<username.length();i++)
                {
                    char ch=username.charAt(i);


                    if(ch>='0'&&ch<='9') {
                        conUname=true;
                    }
                    else {
                        conUname=false;
                        throw new LoginException("用户名含有非数字字符");
                    }
                }
            }
            else {
                throw new LoginException("用户名长度必须在6到10之间");
            }
            if(conUname) {
                if(pwd.length()==6) {
                    con=true;
                }
                else {
                    con=false;
                    throw new LoginException("密码长度必须是六位");

                }
            }
        }catch(LoginException e) {
            System.out.println(e.getMessage());
        }
        return con;
    }
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        System.out.println("请输入用户名");
        String username=sc.next();
        System.out.println("密码");
        String password=sc.next();
        Test it=new Test();
        boolean con=it.validatelogin(username, password);
        if(con)
        {
            System.out.println("登陆成功");
        }
    }
}


案例2

package yichang;

import java.util.Scanner;
public class yichang {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        System.out.println("请输入年龄");
        int age=sc.nextInt();
        System.out.println("请输入性别");
         String sex=sc.next();
        System.out.println("请输入姓名");
        String name=sc.next();
        Preson p=new Preson();
        p.setAge(age);//大于100岁或小于0显示异常
        p.setSex(sex);//不是男性或男性显示异常
        p.Intro(name,age,sex);
    }
}
class SexException extends Exception{
    public SexException() {
        super();
    }
    public SexException(String sex) {
        super(sex);
    }
}
class AgeException extends Exception{
    public AgeException() {
        super();
    }
    public AgeException(String age) {
        super(age);
    }
}
class Preson{
    public void setAge(int age){ boolean con=false;
        if(age>0&&age<100)
        {
            System.out.println(age);}
        else{
            try {
                throw new AgeException("年龄不符合要求");
            }
            catch (AgeException e){
                System.out.println(e.getMessage());
                e.printStackTrace();
            }
        }
    }
    public void setSex(String sex){boolean con=false;
        if(sex.equals("男性")||sex.equals("女性"))
        {System.out.println();
        }
        else{
            try {
                throw new SexException("性别不符合要求");
            }
            catch (SexException e){
                System.out.println(e.getMessage());
                e.printStackTrace();
            }
        }
    }
    public void Intro(String name, int age, String sex){
        System.out.println("姓名:"+name+",年龄:"+age+",性别:"+sex);
    }
}


9.java多线程

Java 给多线程编程提供了内置的支持。 一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。

多线程是多任务的一种特别的形式,但多线程使用了更小的资源开销。

9.1创建一个线程

Java 提供了三种创建线程的方法:

  • 通过实现 Runnable 接口;
  • 通过继承 Thread 类本身;
  • 通过 Callable 和 Future 创建线程。

9.2继承Thread类创建多线程

–JDK中提供了一个线程类Thread,通过继承Thread类,并重写Thread类中的run()方法便可实现多线程。

–在Thread类中,提供了一个start()方法用于启动新线程,线程启动后,系统会自动调用run()方法,如果子类重写了该方法便会执行子类中的方法。Java文件读写

public class Example01 {
	public static void main(String[] args) {
		MyThread myThread=new MyThread(); // 创建MyThread实例对象
		myThread.run();  // 调用MyThread类的run()方法
		while (true) {  // 该循环是一个死循环,打印输出语句
			System.out.println("Main方法在运行");
		}
	}
}
class MyThread {
	public void run() {
		while (true) { // 该循环是一个死循环,打印输出语句
			System.out.println("MyThread类的run()方法在运行");
		}
	}
}

9.3通Thread 方法

下表列出了Thread类的一些重要方法:

序号 方法描述
1 public void start() 使该线程开始执行;Java 虚拟机调用该线程的 run 方法。
2 public void run() 如果该线程是使用独立的 Runnable 运行对象构造的,则调用该 Runnable 对象的 run 方法;否则,该方法不执行任何操作并返回。
3 public final void setName(String name) 改变线程名称,使之与参数 name 相同。
4 public final void setPriority(int priority) 更改线程的优先级。
5 public final void setDaemon(boolean on) 将该线程标记为守护线程或用户线程。
6 public final void join(long millisec) 等待该线程终止的时间最长为 millis 毫秒。
7 public void interrupt() 中断线程。
8 public final boolean isAlive() 测试线程是否处于活动状态。

9.4过实现 Runnable 接口来创建线程

创建一个线程,最简单的方法是创建一个实现 Runnable 接口的类。

为了实现 Runnable,一个类只需要执行一个方法调用 run(),声明如下:

public void run()

你可以重写该方法,重要的是理解的 run() 可以调用其他方法,使用其他类,并声明变量,就像主线程一样。

在创建一个实现 Runnable 接口的类之后,你可以在类中实例化一个线程对象。

Thread 定义了几个构造方法,下面的这个是我们经常使用的:

Thread(Runnable threadOb,String threadName);

这里,threadOb 是一个实现 Runnable 接口的类的实例,并且 threadName 指定新线程的名字。

新线程创建之后,你调用它的 start() 方法它才会运行。

void start();

下面是一个创建线程并开始让它执行的实例:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C5y1vsAS-1640146273301)(C:\Users\常乐无忧\Desktop\02011badbf45a9eeea7cdfe34f65b5fe.png)]

10.Java文件读写

10.1文件操作

ava文件类以抽象的方式代表文件名和目录路径名。该类主要用于文件和目录的创建、文件的查找和文件的删除等。

File对象代表磁盘中实际存在的文件和目录。通过以下构造方法创建一个File对象。

通过给定的父抽象路径名和子路径名字符串创建一个新的File实例。

File(File parent, String child);

通过将给定路径名字符串转换成抽象路径名来创建一个新 File 实例。

File(String pathname)

根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例。

File(String parent, String child)

通过将给定的 file: URI 转换成一个抽象路径名来创建一个新的 File 实例。

File(URI uri)

创建File对象成功后,可以使用以下列表中的方法操作文件。

序号 方法描述
1 **public String getName()**返回由此抽象路径名表示的文件或目录的名称。
2 public String getParent()、 返回此抽象路径名的父路径名的路径名字符串,如果此路名没有指定父目录,则返回 null。
3 public File getParentFile()****返回此抽象路径名的父路径名的抽象路径名,如果此路径名没指定父目录,则返回 null。
4 **public String getPath()**将此抽象路径名转换为一个路径名字符串。
5 **public boolean isAbsolute()**测试此抽象路径名是否为绝对路径名。
6 **public String getAbsolutePath()**返回抽象路径名的绝对路径名字符串。
7 **public boolean canRead()**测试应用程序是否可以读取此抽象路径名表示的文件。
8 **public boolean canWrite()**测试应用程序是否可以修改此抽象路径名表示的文件。
9 **public boolean exists()**测试此抽象路径名表示的文件或目录是否存在。
10 **public boolean isDirectory()**测试此抽象路径名表示的文件是否是一个目录。
11 **public boolean isFile()**测试此抽象路径名表示的文件是否是一个标准文件。
12 **public long lastModified()**返回此抽象路径名表示的文件最后一次被修改的时间。
13 **public long length()**返回由此抽象路径名表示的文件的长度。
14 public boolean createNewFile() throws IOException****当且仅当不存在具有此抽象路径名指定的名称的文件时,原子地创建由此抽象路径名指定的一个新的空文件。
15 public boolean delete() 删除此抽象路径名表示的文件或目录。
16 **public void deleteOnExit()**在虚拟机终止时,请求删除此抽象路径名表示的文件或目录
17 public String[] list()****返回由此抽象路径名所表示的目录中的文件和目录名称所组成字符串数组。
18 public String[] list(FilenameFilter filter)****返回由包含在目录中的文件和目录的名称所组成的字符串数组,这一目录是通过满足指定过滤器的象路径名来表示的。
19 public File[] listFiles() 返回一个抽象路径名数组,这些路径名表示此抽象路名所表示目录中的文件。
20 public File[] listFiles(FileFilter filter)****返回表示此抽象路径名所表示目录中的文件和目录的抽象路径名数组,这些路径名满足特定过滤器**。**
21 **public boolean mkdir()**创建此抽象路径名指定的目录。
22 public boolean mkdirs()****创建此抽象路径名指定的目录,包括创建必需但不存的父目录。
23 public boolean renameTo(File dest) 重新命名此抽象路径名表示的文件。
24 **public boolean setLastModified(long time)**设置由此抽象路径名所指定的文件或目录的最后一次修改时间。
25 **public boolean setReadOnly()**标记此抽象路径名指定的文件或目录,以便只可对其进行读操作
26 public static File createTempFile(String prefix, String suffix, File directory) throws IOException****在指定目录中创建一个新的空文件,使用给定的前缀和后缀字符串生成其名称。
27 public static File createTempFile(String prefix, String suffix) throws IOException****在默认临时文件目录中创建一个空文件,使用给定前缀和后缀生成其名称。
28 **public int compareTo(File pathname)**按字母顺序比较两个抽象路径名。
29 **public int compareTo(Object o)**按字母顺序比较抽象路径名与给定对象。
30 **public boolean equals(Object obj)**测试此抽象路径名与给定对象是否相等。
31 public String toString() 返回此抽象路径名的路径名字符串。

案例1:文件读取

public class DirList {
    public static void main(String args[]) {
        String dirname = "/java";
        File f1 = new File(dirname);
        if (f1.isDirectory()) {
            System.out.println("Directory of " + dirname);
            String s[] = f1.list();
            for (int i = 0; i < s.length; i++) {
                File f = new File(dirname + "/" + s[i]);
                if (f.isDirectory()) {
                    System.out.println(s[i] + " is a directory");
                } else {
                    System.out.println(s[i] + " is a file");
                }
            }
        } else {
            System.out.println(dirname + " is not a directory");
        }
    }
}
public class Test02 {
    public static void main(String[] args) {
        String path = "C:/windows/"; // 指定文件所在的目录
        File f = new File(path, "notepad.exe"); // 建立File变量,并设定由f变量引用
        System.out.println("C:\\windows\\notepad.exe文件信息如下:");
        System.out.println("============================================");
        System.out.println("文件长度:" + f.length() + "字节");
        System.out.println("文件或者目录:" + (f.isFile() ? "是文件" : "不是文件"));
        System.out.println("文件或者目录:" + (f.isDirectory() ? "是目录" : "不是目录"));
        System.out.println("是否可读:" + (f.canRead() ? "可读取" : "不可读取"));
        System.out.println("是否可写:" + (f.canWrite() ? "可写入" : "不可写入"));
        System.out.println("是否隐藏:" + (f.isHidden() ? "是隐藏文件" : "不是隐藏文件"));
        System.out.println("最后修改日期:" + new Date(f.lastModified()));
        System.out.println("文件名称:" + f.getName());
        System.out.println("文件路径:" + f.getPath());
        System.out.println("绝对路径:" + f.getAbsolutePath());
    }
}

10.2输入/输出流

Java 程序通过流来完成输入/输出,所有的输入/输出以流的形式处理。因此要了解 I/O 系统,首先要理解输入/输出流的概念。

输入就是将数据从各种输入设备(包括文件、键盘等)中读取到内存中,输出则正好相反,是将数据写入到各种输出设备(比如文件、显示器、磁盘等)。例如键盘就是一个标准的输入设备,而显示器就是一个标准的输出设备,但是文件既可以作为输入设备,又可以作为输出设备。

数据流是 Java 进行 I/O 操作的对象,它按照不同的标准可以分为不同的类别。

  • 按照流的方向主要分为输入流和输出流两大类。

  • 数据流按照数据单位的不同分为字节流和字符流。

  • 按照功能可以划分为节点流和处理流。

10.3字节流


下面首先介绍上述两个父类提供的常用方法,然后介绍如何使用它们的子类输入和输出字节流,包括 ByteArrayInputStream 类、ByteArrayOutputStream 类、FileInputStream 类和 FileOutputStream 类。

字节输入流

InputStream 类及其子类的对象表示字节输入流,InputStream 类的常用子类如下。

  • ByteArrayInputStream 类:将字节数组转换为字节输入流,从中读取字节。
  • FileInputStream 类:从文件中读取数据。
  • PipedInputStream 类:连接到一个 PipedOutputStream(管道输出流)。
  • SequenceInputStream 类:将多个字节输入流串联成一个字节输入流。
  • ObjectInputStream 类:将对象反序列化。

使用 InputStream 类的方法可以从流中读取一个或一批字节。表 1 列出了 InputStream 类的常用方法。

方法名及返回值类型 说明
int read() 从输入流中读取一个 8 位的字节,并把它转换为 0~255 的整数,最后返回整数。如果返回 -1,则表示已经到了输入流的末尾。为了提高 I/O 操作的效率,建议尽量使用 read() 方法的另外两种形式
int read(byte[] b) 从输入流中读取若干字节,并把它们保存到参数 b 指定的字节数组中。 该方法返回读取的字节数。如果返回 -1,则表示已经到了输入流的末尾
int read(byte[] b, int off, int len) 从输入流中读取若干字节,并把它们保存到参数 b 指定的字节数组中。其中,off 指定在字节数组中开始保存数据的起始下标;len 指定读取的字节数。该方法返回实际读取的字节数。如果返回 -1,则表示已经到了输入流的末尾
void close() 关闭输入流。在读操作完成后,应该关闭输入流,系统将会释放与这个输入流相关的资源。注意,InputStream 类本身的 close() 方法不执行任何操作,但是它的许多子类重写了 close() 方法
int available() 返回可以从输入流中读取的字节数
long skip(long n) 从输入流中跳过参数 n 指定数目的字节。该方法返回跳过的字节数
void mark(int readLimit) 在输入流的当前位置开始设置标记,参数 readLimit 则指定了最多被设置标记的字节数
boolean markSupported() 判断当前输入流是否允许设置标记,是则返回 true,否则返回 false
void reset() 将输入流的指针返回到设置标记的起始处

注意:在使用 mark() 方法和 reset() 方法之前,需要判断该文件系统是否支持这两个方法,以避免对程序造成影响。

字节输出流

OutputStream 类及其子类的对象表示一个字节输出流。OutputStream 类的常用子类如下。

  • ByteArrayOutputStream 类:向内存缓冲区的字节数组中写数据。
  • FileOutputStream 类:向文件中写数据。
  • PipedOutputStream 类:连接到一个 PipedlntputStream(管道输入流)。
  • ObjectOutputStream 类:将对象序列化。

利用 OutputStream 类的方法可以从流中写入一个或一批字节。表 2 列出了 OutputStream 类的常用方法。

方法名及返回值类型 说明
void write(int b) 向输出流写入一个字节。这里的参数是 int 类型,但是它允许使用表达式,而不用强制转换成 byte 类型。为了提高 I/O 操作的效率,建议尽量使用write() 方法的另外两种形式
void write(byte[] b) 把参数 b 指定的字节数组中的所有字节写到输出流中
void write(byte[] b,int off,int len) 把参数 b 指定的字节数组中的若干字节写到输出流中。其中,off 指定字节数组中的起始下标,len 表示元素个数
void close() 关闭输出流。写操作完成后,应该关闭输出流。系统将会释放与这个输出流相关的资源。注意,OutputStream 类本身的 close() 方法不执行任何操作,但是它的许多子类重写了 close() 方法
void flush() 为了提高效率,在向输出流中写入数据时,数据一般会先保存到内存缓冲区中,只有当缓冲区中的数据达到一定程度时,缓冲区中的数据才会被写入输出流中。使用 flush() 方法则可以强制将缓冲区中的数据写入输出流,并清空缓冲区

字节数组输入流

ByteArrayInputStream 类可以从内存的字节数组中读取数据,该类有如下两种构造方法重载形式。

  1. ByteArrayInputStream(byte[] buf):创建一个字节数组输入流,字节数组类型的数据源由参数 buf 指定。
  2. ByteArrayInputStream(byte[] buf,int offse,int length):创建一个字节数组输入流,其中,参数 buf 指定字节数组类型的数据源,offset 指定在数组中开始读取数据的起始下标位置,length 指定读取的元素个数。

例 1

使用 ByteArrayInputStream 类编写一个案例,实现从一个字节数组中读取数据,再转换为 int 型进行输出。代码如下:

  1. public class test08 {
  2. public static void main(String[] args) {
  3. ​ byte[] b = new byte[] { 1, -1, 25, -22, -5, 23 }; // 创建数组
  4. ​ ByteArrayInputStream bais = new ByteArrayInputStream(b, 0, 6); // 创建字节数组输入流
  5. ​ int i = bais.read(); // 从输入流中读取下一个字节,并转换成int型数据
  6. while (i != -1) { // 如果不返回-1,则表示没有到输入流的末尾
  7. ​ System.out.println(“原值=” + (byte) i + “\t\t\t转换为int类型=” + i);
  8. ​ i = bais.read(); // 读取下一个
  9. ​ }
  10. ​ }
  11. }

在该示例中,字节输入流 bais 从字节数组 b 的第一个元素开始读取 4 字节元素,并将这 4 字节转换为 int 类型数据,最后返回。

提示:上述示例中除了打印 i 的值外,还打印出了 (byte)i 的值,由于 i 的值是从 byte 类型的数据转换过来的,所以使用 (byte)i 可以获取原来的 byte 数据。

该程序的运行结果如下:

原值=1 转换为int类型=1 原值=-1 转换为int类型=255 原值=25 转换为int类型=25 原值=-22 转换为int类型=234 原值=-5 转换为int类型=251 原值=23 转换为int类型=23

从上述的运行结果可以看出,字节类型的数据 -1 和 -22 转换成 int 类型的数据后变成了 255 和 234,对这种结果的解释如下:

  • 字节类型的 1,二进制形式为 00000001,转换为 int 类型后的二进制形式为 00000000 00000000 0000000000000001,对应的十进制数为 1。
  • 字节类型的 -1,二进制形式为 11111111,转换为 int 类型后的二进制形式为 00000000 00000000 0000000011111111,对应的十进制数为 255。

可见,从字节类型的数转换成 int 类型的数时,如果是正数,则数值不变;如果是负数,则由于转换后,二进制形式前面直接补了 24 个 0,这样就改变了原来表示负数的二进制补码形式,所以数值发生了变化,即变成了正数。

提示:负数的二进制形式以补码形式存在,例如 -1,其二进制形式是这样得来的:首先获取 1 的原码 00000001,然后进行反码操作,1 变成 0,0 变成 1,这样就得到 11111110,最后进行补码操作,就是在反码的末尾位加 1,这样就变成了 11111111。

字节数组输出流

ByteArrayOutputStream 类可以向内存的字节数组中写入数据,该类的构造方法有如下两种重载形式。

  1. ByteArrayOutputStream():创建一个字节数组输出流,输出流缓冲区的初始容量大小为 32 字节。
  2. ByteArrayOutputStream(int size):创建一个字节数组输出流,输出流缓冲区的初始容量大小由参数 size 指定。

ByteArrayOutputStream 类中除了有前面介绍的字节输出流中的常用方法以外,还有如下两个方法。

  1. intsize():返回缓冲区中的当前字节数。
  2. byte[] toByteArray():以字节数组的形式返回输出流中的当前内容。

10.4文件输入流

FileInputStream 是 Java 流中比较常用的一种,它表示从文件系统的某个文件中获取输入字节。通过使用 FileInputStream 可以访问文件中的一个字节、一批字节或整个文件。

在创建 FileInputStream 类的对象时,如果找不到指定的文件将拋出 FileNotFoundException 异常,该异常必须捕获或声明拋出。

FileInputStream 常用的构造方法主要有如下两种重载形式。

  1. FileInputStream(File file):通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的 File 对象 file 指定。
  2. FileInputStream(String name):通过打开一个到实际文件的链接来创建一个 FileInputStream,该文件通过文件系统中的路径名 name 指定。

下面的示例演示了 FileInputStream() 两个构造方法的使用。

  1. try {
  2. ​ // 以File对象作为参数创建FileInputStream对象
  3. ​ FileInputStream fis1 = new FileInputStream(new File(“F:/mxl.txt”));
  4. ​ // 以字符串值作为参数创建FilelnputStream对象
  5. ​ FileInputStream fis2 = new FileInputStream(“F:/mxl.txt”);
  6. } catch(FileNotFoundException e) {
  7. ​ System.out.println(“指定的文件找不到!”);
  8. }

例 3

假设有一个 D:\myJava\HelloJava.java 文件,下面使用 FileInputStream 类读取并输出该文件的内容。具体代码如下:

**

public class Test10 {

   public static void main(String[] args) {

        File f = new File("D:/myJava/HelloJava.java");

        FileInputStream fis = null;

        try {

            // 因为File没有读写的能力,所以需要有个InputStream

            fis = new FileInputStream(f);

            // 定义一个字节数组

            byte[] bytes = new byte[1024];

            int n = 0; // 得到实际读取到的字节数

            System.out.println("D:\\myJava\\HelloJava.java文件内容如下:");

            // 循环读取

            while ((n = fis.read(bytes)) != -1) {

               String s = new String(bytes, 0, n); // 将数组中从下标0到n的内容给s

               System.out.println(s);

            }
        } catch (Exception e) {

            e.printStackTrace();

        } finally {

            try {

                fis.close();

            } catch (IOException e) {

                e.printStackTrace();

            }

        }

    }

}

10.5文件输出流

FileOutputStream 类继承自 OutputStream 类,重写和实现了父类中的所有方法。FileOutputStream 类的对象表示一个文件字节输出流,可以向流中写入一个字节或一批字节。在创建 FileOutputStream 类的对象时,如果指定的文件不存在,则创建一个新文件;如果文件已存在,则清除原文件的内容重新写入。

FileOutputStream 类的构造方法主要有如下 4 种重载形式。

  1. FileOutputStream(File file):创建一个文件输出流,参数 file 指定目标文件。
  2. FileOutputStream(File file,boolean append):创建一个文件输出流,参数 file 指定目标文件,append 指定是否将数据添加到目标文件的内容末尾,如果为 true,则在末尾添加;如果为 false,则覆盖原有内容;其默认值为 false。
  3. FileOutputStream(String name):创建一个文件输出流,参数 name 指定目标文件的文件路径信息。
  4. FileOutputStream(String name,boolean append):创建一个文件输出流,参数 name 和 append 的含义同上。

注意:使用构造方法 FileOutputStream(String name,boolean append) 创建一个文件输出流对象,它将数据附加在现有文件的末尾。该字符串 name 指明了原文件,如果只是为了附加数据而不是重写任何已有的数据,布尔类型参数 append 的值应为 true。

对文件输出流有如下四点说明:

  1. 在 FileOutputStream 类的构造方法中指定目标文件时,目标文件可以不存在。
  2. 目标文件的名称可以是任意的,例如 D:\abc、D:\abc.de 和 D:\abc.de.fg 等都可以,可以使用记事本等工具打开并浏览这些文件中的内容。
  3. 目标文件所在目录必须存在,否则会拋出 java.io.FileNotFoundException 异常。
  4. 目标文件的名称不能是已存在的目录。例如 D 盘下已存在 Java 文件夹,那么就不能使用 Java 作为文件名,即不能使用 D:\Java,否则抛出 java.io.FileNotFoundException 异常。

同样是读取 D:\myJava\HelloJava.java 文件的内容,在这里使用 FileInputStream 类实现,然后再将内容写入新的文件 D:\myJava\HelloJava.txt 中。具体的代码如下:

  1. 
    public class Test11 {
        public static void main(String[] args) {
            FileInputStream fis = null; // 声明FileInputStream对象fis
            FileOutputStream fos = null; // 声明FileOutputStream对象fos
            try {
                File srcFile = new File("D:/myJava/HelloJava.java");
                fis = new FileInputStream(srcFile); // 实例化FileInputStream对象
                File targetFile = new File("D:/myJava/HelloJava.txt"); // 创建目标文件对象,该文件不存在
                fos = new FileOutputStream(targetFile); // 实例化FileOutputStream对象
                byte[] bytes = new byte[1024]; // 每次读取1024字节
                int i = fis.read(bytes);
                while (i != -1) {
                    fos.write(bytes, 0, i); // 向D:\HelloJava.txt文件中写入内容
                    i = fis.read(bytes);
                }
                System.out.println("写入结束!");
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    fis.close(); // 关闭FileInputStream对象
                    fos.close(); // 关闭FileOutputStream对象
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    

字符流


尽管 Java 中字节流的功能十分强大,几乎可以直接或间接地处理任何类型的输入/输出操作,但利用它却不能直接操作 16 位的 Unicode 字符。这就要用到字符流。本节将重点介绍字符流的操作。

字符输入流

Reader 类是所有字符流输入类的父类,该类定义了许多方法,这些方法对所有子类都是有效的。

Reader 类的常用子类如下。

  • CharArrayReader 类:将字符数组转换为字符输入流,从中读取字符。
  • StringReader 类:将字符串转换为字符输入流,从中读取字符。
  • BufferedReader 类:为其他字符输入流提供读缓冲区。
  • PipedReader 类:连接到一个 PipedWriter。
  • InputStreamReader 类:将字节输入流转换为字符输入流,可以指定字符编码。

与 InputStream 类相同,在 Reader 类中也包含 close()、mark()、skip() 和 reset() 等方法,这些方法可以参考 InputStream 类的方法。下面主要介绍 Reader 类中的 read() 方法,如表 1 所示。

方法名及返回值类型 说明
int read() 从输入流中读取一个字符,并把它转换为 0~65535 的整数。如果返回 -1, 则表示已经到了输入流的末尾。为了提高 I/O 操作的效率,建议尽量使用下面两种 read()方法
int read(char[] cbuf) 从输入流中读取若干个字符,并把它们保存到参数 cbuf 指定的字符数组中。 该方法返回读取的字符数,如果返回 -1,则表示已经到了输入流的末尾
int read(char[] cbuf,int off,int len) 从输入流中读取若干个字符,并把它们保存到参数 cbuf 指定的字符数组中。其中,off 指定在字符数组中开始保存数据的起始下标,len 指定读取的字符数。该方法返回实际读取的字符数,如果返回 -1,则表示已经到了输入流的末尾

字符输出流

与 Reader 类相反,Writer 类是所有字符输出流的父类,该类中有许多方法,这些方法对继承该类的所有子类都是有效的。

Writer 类的常用子类如下。

  • CharArrayWriter 类:向内存缓冲区的字符数组写数据。
  • StringWriter 类:向内存缓冲区的字符串(StringBuffer)写数据。
  • BufferedWriter 类:为其他字符输出流提供写缓冲区。
  • PipedWriter 类:连接到一个 PipedReader。
  • OutputStreamReader 类:将字节输出流转换为字符输出流,可以指定字符编码。

与 OutputStream 类相同,Writer 类也包含 close()、flush() 等方法,这些方法可以参考 OutputStream 类的方法。下面主要介绍 Writer 类中的 write() 方法和 append() 方法,如表 2 所示。

方法名及返回值类型 说明
void write(int c) 向输出流中写入一个字符
void write(char[] cbuf) 把参数 cbuf 指定的字符数组中的所有字符写到输出流中
void write(char[] cbuf,int off,int len) 把参数 cbuf 指定的字符数组中的若干字符写到输出流中。其中,off 指定字符数组中的起始下标,len 表示元素个数
void write(String str) 向输出流中写入一个字符串
void write(String str, int off,int len) 向输出流中写入一个字符串中的部分字符。其中,off 指定字符串中的起始偏移量,len 表示字符个数
append(char c) 将参数 c 指定的字符添加到输出流中
append(charSequence esq) 将参数 esq 指定的字符序列添加到输出流中
append(charSequence esq,int start,int end) 将参数 esq 指定的字符序列的子序列添加到输出流中。其中,start 指定子序列的第一个字符的索引,end 指定子序列中最后一个字符后面的字符的索引,也就是说子序列的内容包含 start 索引处的字符,但不包括 end索引处的字符

注意:Writer 类所有的方法在出错的情况下都会引发 IOException 异常。关闭一个流后,再对其进行任何操作都会产生错误。

字符文件输入流

为了读取方便,Java 提供了用来读取字符文件的便捷类——FileReader。该类的构造方法有如下两种重载形式。

  1. FileReader(File file):在给定要读取数据的文件的情况下创建一个新的 FileReader 对象。其中,file 表示要从中读取数据的文件。
  2. FileReader(String fileName):在给定从中读取数据的文件名的情况下创建一个新 FileReader 对象。其中,fileName 表示要从中读取数据的文件的名称,表示的是一个文件的完整路径。

在用该类的构造方法创建 FileReader 读取对象时,默认的字符编码及字节缓冲区大小都是由系统设定的。要自己指定这些值,可以在 FilelnputStream 上构造一个 InputStreamReader。

注意:在创建 FileReader 对象时可能会引发一个 FileNotFoundException 异常,因此需要使用 try catch 语句捕获该异常。

字符流和字节流的操作步骤相同,都是首先创建输入流或输出流对象,即建立连接管道,建立完成后进行读或写操作,最后关闭输入/输出流通道。

例 1

要将 D:\myJava\HelloJava.java 文件中的内容读取并输出到控制台,使用 FileReader 类的实现代码如下:

  1. public class Test12 {
  2. public static void main(String[] args) {
  3. ​ FileReader fr = null;
  4. try {
  5. ​ fr = new FileReader(“D:/myJava/HelloJava.java”); // 创建FileReader对象
  6. ​ int i = 0;
  7. ​ System.out.println(“D:\myJava\HelloJava.java文件内容如下:”);
  8. while ((i = fr.read()) != -1) { // 循环读取
  9. ​ System.out.print((char) i); // 将读取的内容强制转换为char类型
  10. ​ }
  11. ​ } catch (Exception e) {
  12. ​ System.out.print(e);
  13. ​ } finally {
  14. try {
  15. ​ fr.close(); // 关闭对象
  16. ​ } catch (IOException e) {
  17. ​ e.printStackTrace();
  18. ​ }
  19. ​ }
  20. ​ }
  21. }

如上述代码,首先创建了 FileReader 字符输入流对象 fr,该对象指向 D:\myJava\HelloJava.java 文件,然后定义变量 i 来接收调用 read() 方法的返回值,即读取的字符。在 while 循环中,每次读取一个字符赋给整型变量 i,直到读取到文件末尾时退出循环(当输入流读取到文件末尾时,会返回值 -1)。

字符文件输出流

Java 提供了写入字符文件的便捷类——FileWriter,该类的构造方法有如下 4 种重载形式。

  1. FileWriter(File file):在指定 File 对象的情况下构造一个 FileWriter 对象。其中,file 表示要写入数据的 File 对象。
  2. FileWriter(File file,boolean append):在指定 File 对象的情况下构造一个 FileWriter 对象,如果 append 的值为 true,则将字节写入文件末尾,而不是写入文件开始处。
  3. FileWriter(String fileName):在指定文件名的情况下构造一个 FileWriter 对象。其中,fileName 表示要写入字符的文件名,表示的是完整路径。
  4. FileWriter(String fileName,boolean append):在指定文件名以及要写入文件的位置的情况下构造 FileWriter 对象。其中,append 是一个 boolean 值,如果为 true,则将数据写入文件末尾,而不是文件开始处。

在创建 FileWriter 对象时,默认字符编码和默认字节缓冲区大小都是由系统设定的。要自己指定这些值,可以在 FileOutputStream 上构造一个 OutputStreamWriter 对象。

FileWriter 类的创建不依赖于文件存在与否,如果关联文件不存在,则会自动生成一个新的文件。在创建文件之前,FileWriter 将在创建对象时打开它作为输出。如果试图打开一个只读文件,将引发一个 IOException 异常。

注意:在创建 FileWriter 对象时可能会引发 IOException 或 SecurityException 异常,因此需要使用 try catch 语句捕获该异常。

例 2

编写一个程序,将用户输入的 4 个字符串保存到 D:\myJava\book.txt 文件中。在这里使用 FileWriter 类中的 write() 方法循环向指定文件中写入数据,实现代码如下:

**public** **class** Test13 {

​    **public** **static** void main(String[] args) {

​        Scanner input = **new** Scanner(System.in);

​        FileWriter fw = **null**;

​        **try** {

​            fw = **new** FileWriter("D:\\myJava\\book.txt"); // 创建FileWriter对象

​            **for** (int i = 0; i < 4; i++) {

​                System.out.println("请输入第" + (i + 1) + "个字符串:");

​                String name = input.next(); // 读取输入的名称

​                fw.write(name + "\r\n"); // 循环写入文件

​            }

​            System.out.println("录入完成!");

​        } **catch** (Exception e) {

​            System.out.println(e.getMessage());

​        } **finally** {

​            **try** {

​                fw.close(); // 关闭对象

​            } **catch** (IOException e) {

​                e.printStackTrace();

​            }

​        }

​    }

}

如上述代码,首先创建了一个指向 D:\myJava\book.txt 文件的字符文件输出流对象 fw,然后使用 for 循环录入 4 个字符串,并调用 write() 方法将字符串写入到指定的文件中。最后在 finally 语句中关闭字符文件输出流。

运行该程序,根据提示输入 4 个字符串,如下所示。接着打开 D:\myJava\book.txt 文件,将看到写入的内容,如图 1 所示。

请输入第1个字符串: 热点要闻 请输入第2个字符串: 个性推荐 请输入第3个字符串: 热搜新闻词 请输入第4个字符串: 本地看点 录入完成!

​ [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C065JhGf-1640146273302)(data:,)]

图 1 book.txt 文件内容

字符缓冲区输入流

BufferedReader 类主要用于辅助其他字符输入流,它带有缓冲区,可以先将一批数据读到内存缓冲区。接下来的读操作就可以直接从缓冲区中获取数据,而不需要每次都从数据源读取数据并进行字符编码转换,这样就可以提高数据的读取效率。

BufferedReader 类的构造方法有如下两种重载形式。

  1. BufferedReader(Reader in):创建一个 BufferedReader 来修饰参数 in 指定的字符输入流。
  2. BufferedReader(Reader in,int size):创建一个 BufferedReader 来修饰参数 in 指定的字符输入流,参数 size 则用于指定缓冲区的大小,单位为字符。

除了可以为字符输入流提供缓冲区以外,BufferedReader 还提供了 readLine() 方法,该方法返回包含该行内容的字符串,但该字符串中不包含任何终止符,如果已到达流末尾,则返回 null。readLine() 方法表示每次读取一行文本内容,当遇到换行(\n)、回车(\r)或回车后直接跟着换行标记符即可认为某行已终止。

例 3

使用 BufferedReader 类中的 readLine() 方法逐行读取 D:\myJava\Book.txt 文件中的内容,并将读取的内容在控制台中打印输出,代码如下:

**public** **class** Test13 {

​    **public** **static** void main(String[] args) {

       FileReader fr = **null**;

       BufferedReader br = **null**;

​        **try** {

​            fr = **new** FileReader("D:\\myJava\\book.txt"); // 创建 FileReader 对象

​            br = **new** BufferedReader(fr); // 创建 BufferedReader 对象

​            System.out.println("D:\\myJava\\book.txt 文件中的内容如下:");

​            String strLine = "";

​            **while** ((strLine = br.readLine()) != **null**) { // 循环读取每行数据

​                System.out.println(strLine);

​            }

​        } **catch** (FileNotFoundException e1) {

​            e1.printStackTrace();

​        } **catch** (IOException e) {

​            e.printStackTrace();

​        } **finally** {

​            **try** {

​                fr.close(); // 关闭 FileReader 对象

​                br.close();

​            } **catch** (IOException e) {

​                e.printStackTrace();

​            }

​        }

​    }

}

如上述代码,首先分别创建了名称为 fr 的 FileReader 对象和名称为 br 的 BufferedReader 对象,然后调用 BufferedReader 对象的 readLine() 方法逐行读取文件中的内容。如果读取的文件内容为 Null,即表明已经读取到文件尾部,此时退出循环不再进行读取操作。最后将字符文件输入流和带缓冲的字符输入流关闭。

运行该程序,输出结果如下所示:

D:\myJava\book.txt 文件中的内容如下: 热点要闻 个性推荐 热搜新闻词 本地看点

字符缓冲区输出流

BufferedWriter 类主要用于辅助其他字符输出流,它同样带有缓冲区,可以先将一批数据写入缓冲区,当缓冲区满了以后,再将缓冲区的数据一次性写到字符输出流,其目的是为了提高数据的写效率。

BufferedWriter 类的构造方法有如下两种重载形式。

  1. BufferedWriter(Writer out):创建一个 BufferedWriter 来修饰参数 out 指定的字符输出流。
  2. BufferedWriter(Writer out,int size):创建一个 BufferedWriter 来修饰参数 out 指定的字符输出流,参数 size 则用于指定缓冲区的大小,单位为字符。

该类除了可以给字符输出流提供缓冲区之外,还提供了一个新的方法 newLine(),该方法用于写入一个行分隔符。行分隔符字符串由系统属性 line.separator 定义,并且不一定是单个新行(\n)符。

提示:BufferedWriter 类的使用与 FileWriter 类相同,这里不再重述。

实验


每到学校开学季都会新进一批图书教材,需要将这些图书信息保存到文件,再将它们打印出来方便老师查看。下面编写程序,使用文件输入/输出流完成图书信息的存储和读取功能,具体的实现步骤如下。

1)创建 Book 类,在该类中包含 no、name 和 price 3 个属性,分别表示图书编号、图书名称和图书单价。同时还包含两个方法 write() 和 read(),分别用于将图书信息写入到磁盘文件中和从磁盘文件中读取图书信息并打印到控制台。

此外,在 Product 类中包含有该类的 toString() 方法和带有 3 个参数的构造方法,具体的内容如下:

public class Book {
    private int no; // 编号
    private String name; // 名称
    private double price; // 单价

    public Book(int no, String name, double price) {
        this.no = no;
        this.name = name;
        this.price = price;
    }

    public String toString() {
        return "图书编号:" + this.no + ",图书名称:" + this.name + ",图书单价:" + this.price + "\n";
    }

    public static void write(List books) {
        FileWriter fw = null;
        try {
            fw = new FileWriter("E:\\myJava\\books.txt"); // 创建FileWriter对象
            for (int i = 0; i < books.size(); i++) {
                fw.write(books.get(i).toString()); // 循环写入
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        } finally {
            try {
                fw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void read() {
        FileReader fr = null;
        BufferedReader br = null;
        try {
            fr = new FileReader("E:\\myJava\\books.txt");
            br = new BufferedReader(fr); // 创建BufferedReader对象
            String str = "";
            while ((str = br.readLine()) != null) { // 循环读取每行数据
                System.out.println(str); // 输出读取的内容
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        } finally {
            try {
                br.close();
                fr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

编写测试类 Test14,创建两个 Book 对象,并将这两个对象保存到 List 集合中,再将 List 集合对象传递给 Book 类中的 write() 方法,向 F:\product.txt 文件中写入图书信息。最后调用 Product 类中的 read() 方法读取该文件内容,代码如下:

public class Test14 {     public static void main(String[] args) {  
    Book book1 = new Book(1001, "C语言中文网Java教程", 159);     
    Book book2 = new Book(1002, "C语言中文网C++教程", 259);      
    List books = new ArrayList();    
    books.add(book1);  
    books.add(book2);    
    Book.write(books);     
    System.out.println("********************图书信息******************");  
    Book.read();  
}
                    }

12.Java GUI设计

12.1.简介

Gui的核心技术: Swing AWT

不流行原因:

因为界面不美观
需要jre环境
为什么我们要学习?

可以写出自己心中想要的小工具
工作时候,也可能需要维护到swing界面,概率极小!
了解MVC架构,了解监听!
2、 AWT介绍
包含了很多类和接口! GUI:图形用户界面编程
元素:窗口,按钮,文本框
包都在java.awt
组件和容器

12.2.Frame框架

//Gui 的第一个界面
public static void main(String[] args){
    //Frame,JDK,看源码!(JDK帮助文档)
    Frame frame = new Frame("我的第一个Java图像界面窗口");
    //需要设置可见性
    frame.setVisible(true);
    //设置窗口大小
    frame.setSize(400,400);
    //设置背景颜色,可以直接查源代码设置已有的颜色frame.setBackground(Color.black);
   
    //弹出的初始位置
    frame.setLocation(200,200);
    //已经大概有雏形,但是没有设置关闭窗口功能,最小化、最大化、窗口尺寸已经默认存在。
    //设置大小固定
    frame.setResizable(false);
}

12.3.面板Panel

import java.awt.*;
//panel 可以看成是一个空间,但是不能单独存在
public class TestPanel {
public static void main(String[] args){
Frame frame = new Frame(); //new 窗口
//布局的概念
Panel panel = new Panel(); //new 面板
Panel panel1 = new Panel();
//设置布局,不设置面板会置顶
frame.setLayout(null);
//窗口坐标和颜色
frame.setBounds(300,300,500,500);
frame.setBackground(new Color(140, 208, 212));
//panel 设置坐标,相对于frame
panel.setBounds(50,50,400,100);
panel.setBackground(new Color(181, 186, 54));
panel1.setBounds(50,200,400,250);
panel1.setBackground(new Color(165, 34, 101));
//将panel添加进frame
frame.add(panel1);
frame.add(panel);
frame.setVisible(true);

}

}
// 解决窗口关闭的问题
//监听事件,监听窗口关闭事件 System.exit(0)强制结束
/*frame.addWindowListener(new WindowListener() {
@Override
public void windowOpened(WindowEvent e) {

}
@Override
public void windowClosing(WindowEvent e) {

}

});…
直接new WindowListener()子类太多,
可以使用适配器模式,new 其中一项需要的子类*/
frame.addWindowListener(new WindowAdapter() {
//窗口点击关闭的时候需要的事情
@Override
public void windowClosing(WindowEvent e) {
//结束程序
System.exit(0);
}

12.4.布局管理器

12.4.1流式布局

frame.setLayout(new FlowLayout(0));



import java.awt.*;
public class TestFlowLayout  {
    public static void main(String[] args) {
        Frame frame = new Frame();
        //组件-按钮
        Button button1 = new Button("button1");
        Button button2 = new Button("button2");
        Button button3 = new Button("button3");
        //设置流式布局的位置
        //frame.setLayout(new FlowLayout(0));	0为左,1为中...
        frame.setLayout(new FlowLayout(FlowLayout.LEFT));//两种方式
        frame.setSize(200,200);
        //把按钮添加上去
        frame.add(button1);
        frame.add(button2);
        frame.add(button3);
        frame.setVisible(true);
    }
}

12.4.2东西南北中

BorderLayout.EAST方位

frame.add(按键名字,BorderLayout.EAST方位);

import java.awt.*;
public class TestBorderLayout {
    public static void main(String[] args) {
        Frame frame = new Frame("TestBorderLayout");
        Button east = new Button("East");
        Button west = new Button("West");
        Button south = new Button("South");
        Button north = new Button("North");
        Button center = new Button("Center");
        frame.setSize(400,400);
        //不同布局的方位
        frame.add(east,BorderLayout.EAST);
        frame.add(west,BorderLayout.WEST);
        frame.add(south,BorderLayout.SOUTH);
        frame.add(north,BorderLayout.NORTH);
        frame.add(center,BorderLayout.CENTER);
        frame.setVisible(true);
    }
}

12.4.3表格布局

TestGridLayout

import java.awt.*;
public class TestGridLayout {
    public static void main(String[] args) {
        Frame frame = new Frame("TestGridLayout");
        Button btn1 = new Button("btn1");
        Button btn2 = new Button("btn2");
        Button btn3 = new Button("btn3");
        Button btn4 = new Button("btn4");
        Button btn5 = new Button("btn5");
        Button btn6 = new Button("btn6");
        frame.setLayout(new GridLayout(3,2));
        frame.add(btn1);
        frame.add(btn2);
        frame.add(btn3);
        frame.add(btn4);
        frame.add(btn5);
        frame.add(btn6);
        frame.pack();//Java函数,用于优化大小;
        // frame.setSize(400,400);
        frame.setVisible(true);
    }
}

12.5.事件监听

事件监听:当某个事情发生的时候,干什么?

public class testActionEvent {
    public static void main(String[] args) {
        // 按下按钮,触发一些事件
        Frame frame = new Frame();
        Button button = new Button();

    // 因为,addActionListener()需要一个ActionListener,所以我们需要构建一个ActionListener
    MyActionListener myActionListener = new MyActionListener();
    button.addActionListener(myActionListener);

    frame.add(button,BorderLayout.CENTER);
    frame.pack();
    windowClose(frame);//关闭窗口
    frame.setVisible(true);

}

// 关闭窗体的事件
public static void windowClose(Frame frame){
    frame.addWindowListener(new WindowAdapter() {
        @Override
        public void windowClosing(WindowEvent e) {
            System.exit(0);
        }
    });
}

}

// 事件监听

class MyActionListener implements ActionListener{

@Override
public void actionPerformed(ActionEvent e) {
    System.out.println("aaa");
}

}

多个按钮,共享一个事件

public class testActionEvent02 {
    public static void main(String[] args) {
        Frame frame = new Frame("开始-停止");
        Button button1 = new Button("start");
        Button button2 = new Button("stop");

   // 可以显示的定义触发会返回的命令,如果不显示定义,则会走默认的值!
    // 可以多个按钮只写一个监听类
    button2.setActionCommand("button2-stop");

    MyMonitor myMonitor = new MyMonitor();

   button1.addActionListener(myMonitor);    
   button2.addActionListener(myMonitor);

   frame.add(button1,BorderLayout.NORTH);
   frame.add(button2,BorderLayout.SOUTH);
  frame.pack();
   frame.setVisible(true);
}

}



class MyMonitor implements ActionListener {

@Override
public void actionPerformed(ActionEvent e) {
    // 获得按钮的信息
    System.out.println("按钮被点击了:msg"+e.getActionCommand());

}

}

输入框 TextField 监听

public class testTextFieldEvent {
   public static void main(String[] args) {
       // 启动
       new MyFrame();
   }
}

class MyFrame extends Frame{
   public MyFrame(){
       TextField textField = new TextField();
       add(textField);

BorderLayout.EAST方位   // 监听这个文本框输入的文字
   MyActionListener2 myActionListener2 = new MyActionListener2();
   // 按下enter 就会触发这个输入框的事件
   textField.addActionListener(myActionListener2);

   // 设置替换编码
   textField.setEchoChar('*');

   setVisible(true);
   pack();

   }
}

class MyActionListener2 implements ActionListener{

   @Override
   public void actionPerformed(ActionEvent e) {
       TextField field = (TextField) e.getSource();  // 获得一些资源,返回一个对象
       System.out.println(field.getText()); // 获得输入框的文本
       field.setText(""); 
   }
}

12.6.Swing

窗口、面板

public class JFrameDemo {
    // init();初始化
    public void init(){
        JFrame jframe = new JFrame("this is a JFrame window!");
        jframe.setVisible(true);
        jframe.setBounds(100,100,300,400);

    //设置文字JLabel
    JLabel jLabel = new JLabel("你打开了这个窗口哦!");
    jframe.add(jLabel);
    //关闭事件
    jframe.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

}
public static void main(String[] args) {
    //新建一个窗口
    new JFrameDemo().init();
}

}

标签居中

package GUI.lesson04;

import javax.swing.*;
import java.awt.*;

public class JFrameDemo {
    // init();初始化
    public void init(){
        JFrame jframe = new JFrame("this is a JFrame window!");
        jframe.setVisible(true);
        jframe.setBounds(100,100,300,400);

    //设置文字JLabel
    JLabel jLabel = new JLabel("你打开了这个窗口哦!");
    jframe.add(jLabel);
    //关闭事件
    jframe.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    //容器实例化
    Container container = jframe.getContentPane();
    container.setBackground(Color.blue);
    //设置label水平居中
    jLabel.setHorizontalAlignment(SwingConstants.CENTER);

}
public static void main(String[] args) {
    //新建一个窗口
    new JFrameDemo().init();
}

}

弹窗

//主窗口
public class DiologDemo extends JFrame {

public DiologDemo(){
    this.setVisible(true);
    this.setBounds(300,300,700,500);
   // this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

    //JFrame 放东西,容器
    Container container = this.getContentPane();
    // 绝对定位
    container.setLayout(null);
    //按钮
    JButton jbutton = new JButton("点我");
    jbutton.setBounds(30,30,200,50);

    //点击这个按钮的时候,弹出一个弹窗
    jbutton.addActionListener(new ActionListener() { //监听器
        @Override
        public void actionPerformed(ActionEvent e) {
            //弹窗
            new MyDialog();
        }
    });
    container.add(jbutton);
}

public static void main(String[] args) {
        new DiologDemo();
}

}
//弹窗的窗口
class MyDialog extends JDialog{
    public MyDialog() {
        this.setBounds(100,100,500,500);
        this.setVisible(true);
        //this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

    Container container = this.getContentPane();
    container.add(new Label("啦啦啦"));
    container.setLayout(null);

}

}

标签
label

面板

JPanel

public class JPanelDemo extends JFrame {
    public JPanelDemo(){
        Container container = this.getContentPane();

    container.setLayout(new GridLayout(2,1,10,10));//后面的两个参数代表间距

    JPanel jPanel1 = new JPanel(new GridLayout(1, 3));
    JPanel jPanel2 = new JPanel(new GridLayout(3, 1));
    JPanel jPanel3 = new JPanel(new GridLayout(1, 2));
    JPanel jPanel4 = new JPanel(new GridLayout(2, 1));
    jPanel1.add(new JButton("1"));
    jPanel1.add(new JButton("1"));
    jPanel1.add(new JButton("1"));
    jPanel2.add(new JButton("2"));
    jPanel2.add(new JButton("2"));
    jPanel2.add(new JButton("2"));
    jPanel3.add(new JButton("3"));
    jPanel3.add(new JButton("3"));
    jPanel4.add(new JButton("4"));
    jPanel4.add(new JButton("4"));

    container.add(jPanel1);
    container.add(jPanel2);
    container.add(jPanel3);
    container.add(jPanel4);
    this.setVisible(true);
    this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    this.setBounds(200,200,500,500);
}
public static void main(String[] args) {
    new JPanelDemo();
}

}



public class JScrollDemo extends JFrame {
    public JScrollDemo(){
        Container container = getContentPane();

    //文本域
    JTextArea textArea = new JTextArea(20, 50);
    textArea.setText("啦啦啦啦啦啦啦啦啦");
    //Scroll面板
    JScrollPane scrollPane = new JScrollPane(textArea);
    container.add(scrollPane);
    this.setVisible(true);
    this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    this.setBounds(200,200,500,500);
}

public static void main(String[] args) {
    new JScrollDemo();
}

}

12.6.1按钮

单选按钮

public class JButtonDemo01 extends JFrame {

public JButtonDemo01(){
    //将一个图片变成一个图标
    Container container = this.getContentPane();
    URL resource = JButtonDemo01.class.getResource("pic.jpg");
    Icon icon = new ImageIcon(resource);

    //单选框
    JRadioButton radioButton01 = new JRadioButton("JRadioButton01");
    JRadioButton radioButton02 = new JRadioButton("JRadioButton02");
    JRadioButton radioButton03 = new JRadioButton("JRadioButton03");

    //由于单选框只能选择一个,分组,一个组中只能选择一个
    ButtonGroup group = new ButtonGroup();
    group.add(radioButton01);
    group.add(radioButton02);
    group.add(radioButton03);

    container.add(radioButton01,BorderLayout.NORTH);
    container.add(radioButton02,BorderLayout.CENTER);
    container.add(radioButton03,BorderLayout.SOUTH);

    this.setVisible(true);
    this.setBounds(100,100,100,100);
    this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}

public static void main(String[] args) {
    new JButtonDemo01();
}

}

多选按钮

public class JButtonDemo03 extends JFrame {

public JButtonDemo03(){
    //将一个图片变成一个图标
    Container container = this.getContentPane();
    URL resource = JButtonDemo03.class.getResource("pic.jpg");
    Icon icon = new ImageIcon(resource);

    //多选框
    JCheckBox checkBox01 = new JCheckBox("JCheckBox01");
    JCheckBox checkBox02 = new JCheckBox("JCheckBox02");
    JCheckBox checkBox03 = new JCheckBox("JCheckBox03");

    container.add(checkBox01,BorderLayout.NORTH);
   container.add(checkBox02,BorderLayout.CENTER);
    container.add(checkBox03,BorderLayout.SOUTH);
   this.setVisible(true);
  this.setBounds(100,100,500,500);
   this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}

public static void main(String[] args) {
    new JButtonDemo03();
}

}

12.6.2列表

下拉框

public class testComboboxDemo01 extends JFrame {
    public testComboboxDemo01() {
        Container container = this.getContentPane();
        JComboBox comboBox = new JComboBox();

    comboBox.addItem("正在热映");
    comboBox.addItem("已下架");
    comboBox.addItem("即将上映");
    container.add(comboBox);
    
    this.setVisible(true);
    this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    this.setBounds(200,200,500,500);
}

public static void main(String[] args) {
    new testComboboxDemo01();
}

}

列表框

public class testComboboxDemo02 extends JFrame {
    public testComboboxDemo02() {
        Container container = this.getContentPane();

//        String[] contents = {"1","2","3"};
        Vector vector = new Vector();
        //列表中需要放入的内容
        JList jList = new JList(vector);

    vector.add("zhangsan");
    vector.add("lisi");
    vector.add("wangwu");
    container.add(jList);
    this.setVisible(true);
    this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    this.setBounds(200,200,500,500);
}

public static void main(String[] args) {
    new testComboboxDemo02();
}

12.6.3文本框

public class testTextDemo01 extends JFrame {
    public testTextDemo01() {
        Container container = this.getContentPane();JTextField textField = new JTextField("Hello");JTextField textField2 = new JTextField("World",20);

​    container.add(textField,BorderLayout.NORTH);
​    container.add(textField2,BorderLayout.SOUTH);this.setVisible(true);this.setBounds(100,100,500,500);this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}

public static void main(String[] args) {
    new testTextDemo01();
}

tPane();
URL resource = JButtonDemo01.class.getResource(“pic.jpg”);
Icon icon = new ImageIcon(resource);

//单选框
JRadioButton radioButton01 = new JRadioButton("JRadioButton01");
JRadioButton radioButton02 = new JRadioButton("JRadioButton02");
JRadioButton radioButton03 = new JRadioButton("JRadioButton03");

//由于单选框只能选择一个,分组,一个组中只能选择一个
ButtonGroup group = new ButtonGroup();
group.add(radioButton01);
group.add(radioButton02);
group.add(radioButton03);

container.add(radioButton01,BorderLayout.NORTH);
container.add(radioButton02,BorderLayout.CENTER);
container.add(radioButton03,BorderLayout.SOUTH);

this.setVisible(true);
this.setBounds(100,100,100,100);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

}

public static void main(String[] args) {
new JButtonDemo01();
}

}




#### 多选按钮

```java
public class JButtonDemo03 extends JFrame {

public JButtonDemo03(){
    //将一个图片变成一个图标
    Container container = this.getContentPane();
    URL resource = JButtonDemo03.class.getResource("pic.jpg");
    Icon icon = new ImageIcon(resource);

    //多选框
    JCheckBox checkBox01 = new JCheckBox("JCheckBox01");
    JCheckBox checkBox02 = new JCheckBox("JCheckBox02");
    JCheckBox checkBox03 = new JCheckBox("JCheckBox03");

    container.add(checkBox01,BorderLayout.NORTH);
   container.add(checkBox02,BorderLayout.CENTER);
    container.add(checkBox03,BorderLayout.SOUTH);
   this.setVisible(true);
  this.setBounds(100,100,500,500);
   this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}

public static void main(String[] args) {
    new JButtonDemo03();
}

}

12.6.2列表

下拉框

public class testComboboxDemo01 extends JFrame {
    public testComboboxDemo01() {
        Container container = this.getContentPane();
        JComboBox comboBox = new JComboBox();

    comboBox.addItem("正在热映");
    comboBox.addItem("已下架");
    comboBox.addItem("即将上映");
    container.add(comboBox);
    
    this.setVisible(true);
    this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    this.setBounds(200,200,500,500);
}

public static void main(String[] args) {
    new testComboboxDemo01();
}

}

列表框

public class testComboboxDemo02 extends JFrame {
    public testComboboxDemo02() {
        Container container = this.getContentPane();

//        String[] contents = {"1","2","3"};
        Vector vector = new Vector();
        //列表中需要放入的内容
        JList jList = new JList(vector);

    vector.add("zhangsan");
    vector.add("lisi");
    vector.add("wangwu");
    container.add(jList);
    this.setVisible(true);
    this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    this.setBounds(200,200,500,500);
}

public static void main(String[] args) {
    new testComboboxDemo02();
}

12.6.3文本框

public class testTextDemo01 extends JFrame {
    public testTextDemo01() {
        Container container = this.getContentPane();JTextField textField = new JTextField("Hello");JTextField textField2 = new JTextField("World",20);

​    container.add(textField,BorderLayout.NORTH);
​    container.add(textField2,BorderLayout.SOUTH);this.setVisible(true);this.setBounds(100,100,500,500);this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}

public static void main(String[] args) {
    new testTextDemo01();
}

你可能感兴趣的:(java,开发语言,后端)