整体目录结构
java是计算机编程语言,java语言的前身是Oak语言,是由美国Sun公司在1991年推出;在1995年Sun公司将其更名为Java;2009Sun公司被Oracle公司收购。
语法简单、功能强大、安全性高。
java是一个面向对象的语法,与C不同,去掉了C语言中的指针等复杂概念;(语法简单)
JVM自动回收垃圾,保证程序的可靠性。(功能强大)
java语言要先编译再解释运行,保证了代码的安全性。
跨平台性运行。
因为JVM的存在,保证了Java的跨平台运行性。
解释编译运行。
多线程。
丰富的API。
JDK名为Java软件开发工具包,包含了Java的编译、解释、运行的过程所需的所有工具。
bin
目录下包含了Java的开发工具,如javac编译器,java解释器等。
jre
目录下包含了java所需的运行环境——java虚拟机。
lib
目录下包含了java开发类库。
javac编译器,java解释器。⭐️
安装jdk的时候需要设置系统的环境变量,而设置环境变量的意义是什么?
在没有设置环境变量的时候,我们要想使用doc命令启动应用,就必须前往应用的安装目录下,找到应用的启动程序才能启动;而配置了环境变量后,我们可以在任何地方直接使用doc命令来启动应用。
java程序分为两种,一种是Java应用程序,另一种是Java小应用程序,又称为java小程序。
java的入口函数为main方法,而main方法执行完毕也代表着整个java程序的结束。
java的源程序的扩展名为.java
,编译后的字节码文件扩展名是.class
,有JVM载入执行。
public class Hello{ public static void main(String[] args) { System.out.print("Hello World"); } }
javac
编译器,将源文件(.java
)文件编译为.class
字节码文件。java
解释器,将.class
字节码文件载入JVM并运行。IDE是继承开发环境,这是提供给开发人员使用的程序开发环境,包含了编译器、解释器、调试器等工具,常见的开发IDE由Eclipse、IDEA等。
面向对象是一种软件开发的方法,通常包括3个方面:
面向对象就是将相关的数据和方法(描述和行为),抽象成一个整体,从更高的层次来进行数据的建模,更贴切现实,便于理解,简单易用。
对象是类的一个具体实现,而类是对象的一个抽象模板。
对象具有两个特性——状态和行为;状态描述的是对象的属性,而行为描述的是对象的方法。
封装
隐藏对象的属性和实现细节,只提供使用的方法,提高了安全性。
继承
提高了代码的复用性,继承是多态的前提。
多态
父类或接口引用指子类或实现类对象。提高程序的拓展性、灵活性。
使用相同的操作名,能跟根据具体的对象自动选择对应的操作。(可以向上转型或向下转型,以便使用不同的方法)。
注释的三种形式
单行注释:/* */
作用:对变量、一行程序进行简短的说明。
多行注释:/* */
作用:对方法、设计逻辑、基本思想等进行说明。
文章注释:/** */
作用:在类或方法的头部进行声明,表示对方法和类描述说明;如返回值,方法形参进行说明。
语句、分号和块
语句
语句是java程序的最小执行单位,程序之间以";"分号进行分隔。
语句块
以"{ …语句;… }"大括号开始并结尾的整块代码成为语句块。
关键字是java中内部保留的字符,他们都有着特殊的意义,在使用的时候不能把这些关键字声明为标识符使用。
标识符的说明
标识符是由字母、数字、下划线、"$"美元符号组成的字符串,其中不能以数字开头;标识符区分大小写,没有长度限制。
标识符的作用:可用作变量名、方法名、接口名和类名等。
Jva源码使用的是Unicode编码。
java数据类型分为两种,一种是基本数据类型,第二种是引用数据类型。
注意:数组也是引用数据类型。
基本数据类型
基本数据类型 | 标识符 |
---|---|
整数类型 | byte、short、int、long |
浮点数类型 | float、double |
字符型 | char |
布尔类型 | boolean |
引用数据类型(复合数据类型)
引用数据类型 | 标识符 |
---|---|
类类型 | class |
数组 | |
接口类型 | interface |
整数类型和字节大小
一个字节由8个二进制位(bit)组成
整数类型 | 整数长度 | 字节数 | 范围 |
---|---|---|---|
byte | 8(位) | 1 | -128~127 |
short | 16 | 2 | -32768~32767 |
int | 32 | 4 | 网上有 |
long | 64 | 8 | 网上有 |
整数类型可以用二进制、八进制、十进制、十六进制来表示,由0和1组成的是二进制;以0开头为八进制;以0x开头的是十六进制。
java提供的特殊整型常量值
类型 | 最大值 | 最小值 |
---|---|---|
int | Integer.MAX_VALUE | Integer.MIN_VALUE |
long | Long.MAX_VALUE | Long.MIN_VALUE |
在Java中,有些字符由特定的含义,不能当作普通的标识符类使用,应当使用转移字符——’\'斜杠类转义使用。
表达式是由运算符和操作数组成,对操作数进行运算符指定的操作。
常量的含义:常量指的是在程序运行过程中,其值不变的量;并且只有基本类型与String类型才有相应的常量。
变量的定义
变量指的是在程序运行过程中,其值可以改变的量;并且变量要先声明才能使用。
变量的所属类型既可以是简单数据类型,也可以是引用数据类型。
变量按照声明地方的不同可以分为两类,在类中方法外定义的变量称为成员变量;而在方法內部声明的变量称为局部变量。
变量的作用域指的是声明的变量能够使用的范围。
成员变量的使用范围为整个类,而方法变量的使用范围为其声明方法的内部。
注意:变量的使用讲究就近原则。
分算符主要分为以下几类:
算术运算符就是最基本的加、减、乘、除、取余。
而且取模操作还可以用于负数,结果的符号与第一个操作数的符号相同。
关系型运算符包括大于、小于、等比较操作。关系型运算符都是二元运算符,也就是每个运算符需要带两个操作数。
“==” 与 "!="两种运算符用于任何数据类型。
逻辑运算符包括逻辑与(" && “)与逻辑或(”||")和逻辑非("!")。
java对逻辑与和逻辑或提供短路操作功能,在运算时,先计算左侧表达式的值,如果使用该值能够确定整个表达式的值,那么将不再计算右边表达式的值。
什么是位运算符?
位运算符就是对两个二进制数,进行逻辑运算。
取反(~)
如果一个二进制数的位数为0,那么取反结果是1,如果位为1,结果是0。
按位与(&)
两个二进制数对应的位数都为1,结果才为1,否则结果为0。
按位或(|)
两个二进制数,只要对应的位数有一个为1,那么结果就是1,否则就为0
异或(^)
两个二进制数,对应的位数相同则结果为0,不同则结果为1
左移(<<)
将二进制数像左边进行移动,最左边的舍弃,最右边的补零。
右移(>>)
将二进制想右移动,最右边舍弃,最左边补位。
注意:在右移运算符中,如果操作的二进制数的十进制是为负整数,那么再对其二进制进行右移的时候,左边的补位应该为1,如果是正整数,那么补位为0.
无符号右移(>>>)
与右移相同,但是不关注正负整数的问题,左边统一补位为0.
int a << 1:表示将a的二进制左移一位,得到的结果时a的两倍。
int a >> 1:表示将a的二进制右移一位,得到的结果时a的2/1。
如果左移或右移的位数大于等于32,那么再进行位移之前会先对位移数取余(加入向左或向右位移32位,则取余公式位 32 % 32),所以实际的位移结果位 << 0,表示不位移。
如+=
、-=
、*=
等扩展赋值运算符,以及? :
三元运算符。
十进制为正整数的情况
十进制为负整数的情况
步骤:
二进制0开头表示其原十进制为正整数时
用8421法进行权位*系数 = 结果 的方法。
二进制1开头表示其原十进制为负整数时
步骤:
java是一种强类型语言,不支持变量类型之间的自动任意转换,有时必须显示的进行变量类型的转换;这种转换叫做强转。
能够自动类型转换的类型顺序为:
byte->short->char->int->long->float->double
java的自动转换分为自动类型转换和强制类型转换.
自动类型转换
从字节数小类型的转换为字节数大类型的可以自动类型转换。
整型数据与小数之间可以互相转换,但是有可能会出现精度损失的问题。
强制类型转换
从字节数大的转换为字节数小的类型,不能自动转换,需要强制类型转换。
一个Java源文件可以有多个类定义,但是只能有一个类为public
公有类。
包是类的容器,在定义包时应该避免包冲突;并且一个包中不能有相同类名的类或接口。
包的引入格式为:package 包路径1.包路径2
注意:如果一个类中有package语句,那么此语句一定是在此Java文件中的第一条非注释语句。
在Java源文件中,如果想要使用某个包下的某个类,那么需要使用import
语句;将要使用的类进行导入。
import
引入语句的使用格式:import 包名1.包名2.类名;
如果要导入包中的所有类,可以使用通配符" * ",格式:import 包名1.包名2.*
java中以下三种语句分别对应不同的流:
赋值语句 -> 顺序流
分支语句 -> 分支流
循环语句 -> 循环流
表达式可以当作一个值赋给某一个变量,这样的语句叫做赋值语句。
实例:int x = 10 + 11;
分支语句可以根据一定的条件,来控制程序的执行流向。
java中的分支语句有两种,一是if
语句,二是switch
语句。
if关键字后的必须要跟一个逻辑值表达式,这个表达式一定是能够得到一个boolean值。
if…else…的匹配原则:⭐️
在java中,else语句优先与离它最近的if语句匹配,但是前提是在同一个语句块中。
switch关键字后的表达式与if不同,它必须要求表达式的计算结果是int类型或者字符类型,这样才能与后面的case语句进行匹配。
并且Java规定switch语句表达式不能使用浮点数类型或Long类型的表达式。
在Java中一共分为三种:
for (初始语句; 条件表达式; 迭代语句){ // 循环体 }
初始语句与迭代语句可以有多个,使用,
逗号进行分隔。
初始化语句 ——> 条件表达式 ——> 循环体 ——> 迭代语句
while(条件表达式) { // 循环体 }
while循环与for循环的条件表达式都不能以数值类进行判断,要求表达式最总结果必须是一个布尔类型。
do{ // 循环体 } while (条件表达式)
do…while语句与while与for循环语句不同,do语句至少会执行一次。
先执行循环体 ——> 然后判断条件表达式是否成立,成立则继续执行,不成立的退出循环,所以do语句的循环体至少会执行一次。
一般来说常用的是for循环与while循环,而do语句则很少使用。如果知道具体的循环次数,那么选用for循环语句,反之使用while循环。
java中存在两个关键字,能够配合流程控制语句与循环语句使用——break与continue。
switch语句
当使用在switch语句中时,表示跳出此次case语句,也就是跳出本次分支流程,继续往后执行。
循环语句
当使用在循环语句中时,表示跳出循环,结束循环语句。
与标号配置使用在语句块中(不常用)
continue语句作用在循环语句中,表示跳出本次循环,直接进入下次循环。
Scanner
类位于java.util
包下,是一个用于读取不同类型输入值的类。
Scanner scanner = new Scanner(System.in);
System.in
:代表标准输入流,默认指键盘输入。
Scanner类提供了nextLine()、nextDouble、nextInt
等方法,用于读取不同类型的数据。
指的是在程序运行过程中,可能出现非正常情况,可能导致JVM非正常停止所出现的情况。
java把异常分成两类,程序出现非正常情况但是可以修复,这种我们称为异常;反之不可简单修复的称为错误。
在java中,都定义了一些常见的异常类和错误类;异常类的顶级父类是Exception
,而错误类的顶级父类是Error
;同时他俩的父类又是Throwable
。
在java中,总共把异常分为受检异常和运行异常。
受检异常是指程序执行期间发生严重事情的后果,常见的受检异常有ClassNotFoundException
,IOException
等。
运行时异常是指程序执行时发生的逻辑错误而引起的异常。常见的运行时异常有索引越界异常,除0异常等。
Java中处理异常的方式有两种:
try...catch...finally
语句捕获异常。注意的是,使用try...catch...finally
捕获异常时,finally中的代码都会执行,位移不执行的方法就是在finally语句块执行之前使用了System.exit(0);
程序来终止了JVM虚拟机的运行。
首先类的定义也成为类的声明,而一个类中的组成元素主要为两个——成员变量与成员方法。
权限修饰符代表了所声明的变量或方法的访问范围;而在Java中,权限修饰符有以下几种(访问范围从大到小排列):
public 、protected、default、private
public:表示公有的意思,访问范围——可以被任何对象访问。
protected:受保护的意思,访问范围——不同包且非父子类关系不能访问。
default:默认的意思,访问范围——只能同包访问,包不同则不能互相访问。
private:私有的,访问范围——只能同类互相访问。
Object
。构造方式时一个类中的特殊方法,它用于定义此类的对象;每个类中都有一个默认的无参构造。
new
关键字调用。native
、final
等关键字修饰。Java中,如果方法名相同,而形参列表不同,这样的多个方法就称为方法的重载。
方法签名:方法名+形参列表。
构造方法的唯一作用就是为了创建类的实例,也就是创建对象。
简单来说,对象就是类的实例。
类时对象的模板,而对象时类的实例。
举一个简单的例子,手机设计图假如是一个类,那么一台真实的手机则是一个对象。
只有对象真正实例化之后,内存中才有内存地址。
调用成员方法——对象名.成员方法名。
调用成员变量——对象名.成员变量名。
在Java中调用方法传递参数的过程,我们称为按值传送。
按值传送的意思也就是按照型参的类型传递;如果参数为基本数据类型,那么传值就会以复制的方式传送;如果参数为引用类型,那么传值就会以传递内存地址值的方法传送。
采用static
修饰的成员变量或成员方法都成为静态成员。
首选要说明,静态成员的加载优先级是要高于普通成员的。静态成员在类被JVM进行加载的时候就会加载;而普通成员则是要实例化对象的时候,依靠构造方法才会加载。
总结由如下几点:
当多个对象需要共享一个变量的时候,就可以定义静态变量来实现。
前面提到了,静态变量是跟随类的加载而加载的,所以调用的时候由类名进行调用。
包装类是一种特殊得基本类型。
自动装箱
由基本类型转为包装类型的过程称为自动装箱。
自动拆箱
由包装类型转为基本类型的过程称为自动拆箱。
注意:自动装箱和拆箱仅能用于基本数据类型与包装类型之间。
类型 数组名[] 或者 类型[] 数组名
数组的声明仅仅是声明了一个引用,而内存中还未创建其真实地址。所以要想使用数组,不光要声明,还要进行数据的初始化。
首先,数组的初始化分为静态初始化、动态初始化两种方法。
静态初始化:
所谓的静态初始化就是在声明数组的时候对数组进行赋值,完成数组初始化的过程。
例如:int[] a = {1, 2, 3};
动态初始化:
而所谓的动态初始化则是使用new
关键字,进行数组的声明并创建对象,为其分配内存空间;但是要注意,在使用动态初始化的时候,要指定初始化数组的长度。
然后使用下标的方式为数组的每个索引赋值。
例如:
int[] a = new int[3]; int[0] = 1; int[1] = 2; int[2] = 3;
当定义好一个数组之后,要想访问数组中某个索引处的元素就需要以下标的方式从数组中取出对应索引下标上的元素。
如:
int[] a = {1,2,3}; int b = a[1]; // b=2
但是需要注意的是,如果在使用下标获取数组中的元素时,索引下标超出了数组的原本长度,那么则会引发索引越界异常。而一个数组的最大索引为 = 数组的长度 -1
。(索引从0开始)
且数组的下标可以是整数类型与表达式类型。
简单来说,就是一个数组中由多个元素,而没有给元素又是一个单独的数组。这样的情况我们就称之为多为数组。
int[][] a;
int a[][];
int[] a[];
和一维数组一样,多维数组的初始化也分为静态初始化与动态初始化两种方式。
静态初始化也就是在声明数组的时候进行赋值。
例如:int[][] a = {{1,2}, {2,3}, {3,4}}
当对多维数组进行动态初始化时有两种内存分配方法。
直接分配
直接分配指的就是在声明多维数组的时候,直接指定维度的大小。
如:int[][] a = new int[2][5];
按维分配
按维分配指的就是分别为每一个维度分配内存空间大小。
如:
int[][] a = new int[2][]; a[0] = new int[2]; a[1] = new int[2]; a[2] = new int[2];
以上分配方式就是动态初始化中的多维分配。
多维数组的引用方式为:数组名[第一位下标][第二位下标]
。
二维数组的第一维称为行,第二位称为列。
二维数组也有.length属性
,其长度有第一维长度所定义。
列:int[][] a = new int[2][5];
,因二维数组的长度由第一维定义,所以a数组的长度为2。
Arrays类是关于数组的一个工具类,在这个类中提供了许多关于数组的方法。
equals(type[], type[])
用于比较两个数组的值是否相同。
sort(type[])
对数组进行排序。
字符串是由单个字符组合而成,在java中字符串是一个对象。
在java中,字符串分为常量与变量两种。
常量格式:Stirng a = "123";
变量格式:String a = new String("123")
在java中,系统会自动为程序中出现的常量字符串创建一个String对象。
区别:
String对象一旦创建后不可改变,凡是对String对象改变操作,系统会直接生成一个新的String对象。
而StringBuffer对象则是可以通过append()
方法,在原先的字符串上进行拼接,且系统不会生成一个新的对象。
使用:
不变字符串采用String类型,而常变字符串采用StirngBuffer类型。
equals()
方法比较的是两个字符串的内容是否相等,而==
比较的是两个对象的地址值是否相同。
还是就是两个内容相等的常量字符串使用==
结果是true,因为在堆内存中存在字符串常量池概念,在声明字符串常量的时候,发现常量池中有相同的字符串,则会进行复用,而不会新生成一个字符串常量。
例如:
String a = "aaaa"; String b = "aaaa"; a == b; // 结果为true
数组的缺点
在java中数组的缺点在我看来有两个,一是数组中的元素类型全部要统一,二是数组的长度是定长的。
而Vector
类就是为了解决数组的缺点而生,Vector类可以看作是变长数组。
int capacityIncrement
:增量的大小(每次增加Vector对象的大小)。int elementCount
:Vector类中元素的数量。Object elementData[]
:保存元素的数组。Java中子类的概念是体现在继承关系中;被继承的类称为父类,继承的类称为子类。
将共性内容放入父类,特殊内容由其子类自己实现。
extends
是实现继承的关键字。
使用格式:public class Son extends Parent{}
Object
类是所有java类的间接或直接父类,是最顶级的类。
equals方法与==都是比较引用对象的地址值是否相等,只要两个对象的地址值不同,所得的结果一定是false。
注意:要判断两个对象的成员属性值是否相等,必须要重写Object类的equals()
方法,不能使用从Object原始的equals()
方法。
多重继承说明
多重继承指从多个类派生出一个子类,及一个子类有多个父类。
在java中鄙弃了多重继承,只有单重继承,及一个类只能有一个直接父类;而多重继承的特点由接口实现,也就是一个类能实现多个接口。
这就是java的单继承,多实现。
父类引用或接口引用指向子类对象,这称为对象的转型。
类的变量既可以指向本类对象,也可以指向其子类对象,这为对象的多态性。
前提:父子类中拥有相同的属性成员的情况下。
使用多态的口诀:属性(成员变量)看左边,行为(成员方法)看右边。
super
关键字进行调用。super.method()
调用的方法是一定是直接父类的方法,也有可能是祖先类中的。
super()
方法必须放在子类构造方法体的第一行。多态的情况下,执行的是对象真正类型(运行时)的相关方法。
final`是Java中的一个关键字,它表示终极的意思,可以修饰类、成员方法、成员变量。
final
修饰的类不能被继承。final
修饰的方法不能被重写。final
修饰的变量,其值不能改变。被final
关键字修饰的类称为终极类。
被final
关键字修饰的方法称为终极方法。
格式:
public final int test() { }
被final
修饰的变量称为终极变量,实际上他会成为一个常量,所以其值不能改变。
如果把一个引用类型的变量标记为final
终极的,那么这个变量将不能指向其他类型的对象,但是它原本所指的对象的属性值可以改变。
被abstract
关键字修饰的类称为抽象类。
在程序过程中,有时候需要创建某个类,代表一些基本行为,并且为其规范定义一些方法,但这些方法又不适合在这个类中加以实现,所以就将本类定义为抽象类。具体的时候由其子类根据实际情况去实现这些方法。
被abstract
修饰的方法称为抽象方法。
如果一个类继承抽象类,那么必须重写抽象类中的抽象方法。如果不重写抽象方法,那么子类也应该为一个抽象类。
在定义类的时候,使用interface
代替class
关键字所定义出来的类,称为接口。
接口中只能包含抽象方法和final
修饰的常量。
public interface Demo() { }
接口与一般类一样,本身也具有数据成员变量和方法;但是不同于类的是,接口中的成员变量必须初值,且不能改变;而方法也只能是抽象方法。
在接口中定义的成员变量都默认为终极静态变量,系统会自动为其加上final
与static
俩关键字。
在Java中,一个类可以实现多个接口。
磁盘与其他设备关联的数据源抽象为流。
数据流是指一组有顺序、有起点和终点的字节集合。
数据流分为输入流和输出流两类。
输入流只能读不能写,而输出流只能写不能读;且输入流必须指定数据源与输入流相连。
java.io
包下提供了表示数据流的4个基本抽象类。
字节流相关
InputStream
与OutputStream
字符流相关
Reader
与Writer
以上四个类都是属于抽象类。
输入数据流指的是只能读不能写的数据流,用于向计算机内输入信息使用。
InputSteam
是所有字节输入流的顶级抽象类,所有的字节输入流都直接或间接继承了InputStream
抽象类。
int read()
:从输入流中读取一个字节的二进制数据。int read(byte[] b)
:从输入流中读取一个b数组大小的数据。int read(byte[] b, int off, int len)
:从输入流中读取长度为len的数据,从byte数组的off下标位置开始放置。int available()
:返回目前可以从数据流中读取的字节数(但实际读操作得到的字节数可能大于该返回值)。注意:当输入流读取结束时,使用read()
方法返回值的为-1,表示没有数据可以读取了。
输出数据流指的是只能写不能读的数据流,用于从计算机中写出数据。
OutputSteam
是所有字节输出流的顶级抽象类,所有的字节输出流全都直接或简介继承了OutputStream
这个抽象类。
void write(int i)
:将字节i写到数据流中。void write(byte[] b)
:将byte数组中的所有字节写入数据流。void write(byte[] b, int off, int len)
:将数组中从下标off开始的len个长度的字节,写入数据流。void flush()
:刷新此输出流,并强制写出所有缓冲区的字节。输出缓冲区的存在就是为了减少IO次数,提交传输效率。
举例说明:
假设我们往一个文件中写入数据,如果每写一次都立刻去进行IO操作,将数据写入文件,那么在写入数据较少的情况下,势必会影响我们的传输效率;而缓冲区的作用正是在这里。
我们预先设定好缓冲区的大小,当我们写入的数据大小没有缓冲区大小大的时候,那么数据会先进入缓冲区,等待下一次数据到来;等两次的数据大小和大于了缓冲区大小时,那么就会执行IO操作,将数据写入文件。
在这种方式下,传输末尾阶段总会有一段数据因为数据量不够而呆在缓冲区中,所有flush()
方法的作用就是将这部分数据强制刷出缓冲区,写入文件中。
文件数据流包括FileInputStream(文件输入流)
与FileOutputStream(文件输出流)
,这两个类用来进行文件的IO处理,其数据源或数据终点都是文件。
FileInputStream
文件输入流时,所指定的文件数据源对象不存在则会产生FileNotFoundException
异常。FileOutputStream
文件输出流时,如果指定的输出文件不存在,则会新建;如果输出文件已存在,那么新写入的内容将覆盖原本内容。IOException
异常。过滤器数据流类:FilterInputStream
,该类时继承的InputStream
抽象类。
过滤器数据流的创建:一个过滤器数据流在创建时与一个已经存在的数据流相连接。
过滤器数据流的作用:在从原数据流读取数据时,过滤器数据流就能够对原始输入数据流内容进行特定处理。
缓冲区数据流简介
缓冲区数据流分为缓冲区输入流BufferedInputStream
与缓冲区输出流BufferedOutputStream
;它们是在数据流上增加了以恶缓冲区,都属于过滤器数据流。
这两个缓冲区数据流又继承了过滤器数据流类。
缓冲区输入流:BufferedOInputStream extends FilterInputStream
缓冲区输出流:BufferedOutputStream extends FilterOutputStream
缓冲区的作用
当读写数据时,数据以块为单位先进入缓冲区(块的大小可以自己设置),其后的读写操作则作用域缓冲区。采用这种方法可以提高IO效率。
缓冲区输出流使用注意事项
在关闭缓冲区数据流之前,应该先使用flush()
方法,强制刷出剩余数据;以确保缓冲区内的所有数据全部写入输出流。
数据数据流简介
数据数据流主要分为数据输入流DataInputStream
与数据输出流DataOutputStream
,它俩也是继承了过滤器数据流。
数据数据流的作用
数据数据流允许通过数据流来读写Java的基本类型。
常用方法介绍
数据输入流
byte readByte()
Stirng readUTF()
int readInt()
数据输出流
void writeByte(int v)
void write(int b)
void writeUTF(String str)
对象流简介
Java提供了把对象写入数据流,或从数据流中读出的功能;通过java.io
包下的ObjectInputStream 对象输入流
与ObjectOutputStream 对象输出流
两个类实现。
对象输入流的关键方法
从一个流中读取对象的方法:readObject()
,把数据流以Object类型返回,然后需转换为合理的对象操作类型。
通过对象流对对象的持久化操作也和对象的序列化分不开。
对象的持久性?
能够记录自己的当前状态,以便将来能够复原;这样的能力称为对象的持久性。
什么叫序列化?
把对象转换为字节序列的过程称为对象的序列化;把字节序列恢复为对象的过程称为反序列化。
对象序列化的注意事项
transitent
关键字标明的成员变量都不会被保存。transient
修饰,那么则整个对象可以进行持久化。从JDK1.1开始,java.io
包下加入了专门处理字符流的类,他们是Reader
和Writer
派生出来的一系列类。
Reader
和Writer
是两个抽象类,也是所有字符流的祖类。
字符转换流是用来在字节流和字符流之间做转换使用的。
核心类就是在java.io
包下的InputStreamReader 字符输入转换流
和OutputStreamWriter字符输出转换流
。
把以字节方式表示的流转换为特定平台上的字符表示。简而言之就是在字节流与字符流之间相互转换。
InputStreamReader(InputStream in)
:将字节流转化为字符流。OutputStreamWriter(OutputStream out)
:将字符流转化为字节流。java.io
包下的BufferedReader字符缓冲区输入流
与BufferedWriter 字符缓冲区输出流
。
作用与字节缓冲区流相同,都是为了提高IO效率,故而加入了缓冲区这一功能。
并且也有flush()
刷新方法,在数据传输尾声,需要使用该方法将缓冲区剩余数据强制刷新出去。
字符缓冲流提供了整行字符的处理方法。
String readLine()
:BufferedReader
方法,从输入流中读取一行字符。void newLine()
:BufferedWriter
方法,向输入流中写入行结束标志,下次写入的数据就会在下一行。Java提供了File
类,用于处理文件相关操作;File对象既可以用来生成文件,也可以用来生成文件目录。
java.io.File
类提供了获取文件基本信息及操作文件的方法。
File(String pathname)
:pathname
为文件名+文件路径名。File(String parent, String child)
:parent
父路径名,child
文件子路径名。File(File parent, String child)
:parent
是一个文件对象,child
文件子路径名。String getName();
:获取文件名。String getPath();
:获取文件路径。String getAbsolutePath();
:获取文件的绝对路径。String getParent();
:获取文件父目录名称。boolean renameTo(File dest);
:更改文件名。boolean exists;
:判断文件对象是否存在。boolean canWrite();
:判断文件对象是否可写。boolean canRead();
:判断文件对象是否可读。boolean isFile();
:判断文件对象是否是文件。boolean isDirectory();
:判断文件对象是否是文件目录。boolean isAbsolute();
:判断文件对象是否是绝对路径。long lastModified();
:获取文件最后修改时间。long length();
:获取文件长度。boolean delete()
:删除文件对象指向的文件。boolean mkdir();
:创建新目录。boolean mkdirs()
:创建新目录,与mkdir()
不同的是,mkdirs
可以一次性创建多层次的目录。String[] list(FilenameFilter filter)
:列出符合模式的文件名。在文件不同位置进行读取操作,由RandomAccessFile
类实现。
GUI(Graphical User Interface),又名图形用户界面;在java.awt
包与javax.swing
包下定义了多种用于创建图形用户界面的组件类。
一般设计图形用户界面有3个步骤:
java.awt
包下,而Swing组件定义在javax.swing
包下。组件可以分为容器组件和非容器组件。
作为容器组件就是指可以包含其他组件的组件;而非容器组件则必须要包含在容器组件中。
容器组件又可以分为顶层容器组件和一般用途容器组件。
显示在屏幕上的组件都必须包含在某个容器中,有些容器可以嵌套,在这个嵌套的最外层,必须有一个顶层容器。
java为所有容器定义了父类Container
,容器的共有操作都定义在Container
类中。
在Swing中提供了4中顶层容器,分别为JFrame
、JApplet
、JDialog
和JWindow
;他们各自的特点如下:
JFrame
是一个带有标题行和控制按钮的独立窗口,有时候被称为框架。Applet
是一个被包含在游览器中的窗口中。JDialog
用于创建一个对话框。JWindow
创建一个不带标题行和控制按钮的窗口。在创建容器对象后,他的大小为0,并且不可见;所以需要使用frame.pack()
语句来调整窗口的大小,使用frame.setVisiable(true)
,来让容器可见。
4个顶层容器,每个容器都有一个默认的内容窗格;处菜单外,顶层容器中的组件都放在这个内容窗格中。
.getContentPane
add()
顶层容器默认的内容窗格的布局管理器是BorderLayout
;而JPanel
的默认布局管理器是FlowLayout
。
注意:内容窗格可以嵌套,如一个面板中可以嵌套入另一个面板。
在javax.swing
包中,面板被分为普通面板和滚动面板,他俩都是广泛运用的容器。
Jpanel()
:创建一个普通面板,面板的默认布局时FlowLayout
。JPanel(LayoutManager layout)
:创建一个带有指定布局管理器的普通面板。Compoent add(Compoent comp)
:将指定组件添加到面板或容器中。JScrollPane
是带有滚动条的面板,他是Container
类的子类,且滚动面板中只能加入一个组件,所以一般都是先将各个组件添加进JPanel
面板,然后将JPanel
添加到JScrollPane
滚动版面中。
创建滚动面板的方法(创建的滚动面板中包含滚动条)
JScrollPane()
:创建一个新的滚动面板。JSCrollPane(Compoent comp)
:创建一个显示指定组件的滚动面板,只要组件内容超过视图大小,就会显示垂直滚动条和水平滚动条。AWT中滚动条组件的创建
ScrollBar()
:构造一个新的垂直滚动条。
Scrollbar(int orientation)
:构造一个具有指定方法的滚动条。
…
标签JLabel
和按钮JButton
都是swing中的组件。
JLabel()
:构造一个空标签。JLabel(Icon image)
:构造一个显示图标的标签。JLabel(String text)
:构造一个显示文字的标签。JLabel(Icon image, int horizontalAlignment)
:构造一个显示图标的标签,水平对齐方法由参数horizontalAlignment
指定。JLabel(String text, int horizontalAlignment)
:构造一个显示文字的标签,水平对齐方法由参数horizontalAlignment
指定。JLabel(String text, Icon icon, int horizontalAlignment)
:构造一个同时显示文字和图标的标签,水平对齐方法由参数horizontalAlignment
指定。注:horizontalAlignment
的取值常类为:
JLabel.CENTER
:居中对齐。JLabel.LEFT
:左对齐。JLabel.RIGHT
:右对齐。void setHorizontalAlignment(int alignment)
:设置标签内容水平对齐的方法。void setVerticalAlignment(int alignment)
:设置标签内容垂直对齐的方法。void setIcon(Icon icon)
:设置标签图标的方法。void setText(String text)
:设置标签文本的方法。经常用到的按钮分为JButton
普通按钮、JToggleButton
切换按钮、JCheckBox
复选框按钮、JRadioButton
单选框按钮,它们均是AbstractButton
的子类。
它们都有着一些共有方法:
void addActionListener(ActionListener l)
:为当前按钮注册监听事件。void setEnabled(boolean b)
:禁用或启用button。void setText(String text)
:设置按钮的文本。setIcon(Icon defaultIcon)
:设置按钮的图标。切换按钮JToggleButton
是具有两种状态的按钮,及选中状态和未选中状态。
JCheckBox
复选按钮和JRedioButton
都是JToggleButton
的子类。
获取按钮的选中状态
在JToggleButton
中定义获取按钮选中状态的方法:
boolean isSelected()
:如果当前按钮处于选中状态返回true,反之返回false。
可以注册的监听事件
JToggleButton
、JCheckBox
、JRedioButton
这三种按钮因为有状态的切换,所以不仅可以注册ActionEvent
事件侦听程序,还可以注册ItemEvent
选项事件侦听程序。
按钮不仅可以单独存在,还可以多个按钮组成按钮组;当多个按钮被添加到按钮组之后,如果用户选中一个按钮,则其它按钮变为未选中状态。
JCheckBoxGroup
与GRedioButtonGroup
两个类分别注册了不同的事件侦听程序,实现了组中选一个按钮时,其他按钮变为未选中状态。
定义:
布局管理器顾名思义就是用于容器的管理布局。
作用:
因为容器中有各个组件,那么组件的排列顺序就需要有人来管理;所以布局管理器的作用就是来管理各个组件的位置和大小。
根据各个布局管理器的管理方式不同,所以将各个布局管理器进行了分类。
容器的默认布局管理器
顶级容器的默认布局管理器是BorderLayout
;面板的默认布局管理器是FlowLayout
。
FlowLayout
定在java.awt
包中,此布局管理器的方式是将组件逐个的放置在容器中的一行上,一行放慢之后就另起一行。
FlowLayout()
:创建一个默认的FlowLayout
布局管理器,居中对齐,默认水平和垂直间距为5个像素。FlowLayout(int align)
:创建一个FlowLayout
布局管理器,对齐方式由align
指定。FlowLayout(int align, int hgap, int vgap)
:创建一个FlowLayout
布局管理器,对齐方式由align
指定,垂直间距由hgap
指定,水平间距由vgap
指定。align的取值
align
的取值范围有FlowLayout.LEFT
左对齐,FlowLayout.RIGHT
右对齐,FlowLayout.CONTER
居中对齐三种。
BorderLayout
是顶层容器的默认布局管理器,每个由BorderLayout
管理的容器被分成5块区域;分别代表容器的上下左右中共5部分,分别用常量表示:
BorderLayout.NORTH
:上部。BorderLayout.SOUTH
:下部。BorderLayout.WEST
:左部。BorderLayout.EAST
:右部。BorderLayout.CENTER
:中部。BorderLayout()
:构造一个组件之间没有间距的BorderLayout
布局管理器。BorderLayout(int hgap, int vgap)
:构造一个BorderLayout
布局管理器,并通过参数指定组件之间的间距大小。4.3 获取
顶层容器的默认布局管理器就是BorderLayout
Center
区域;也可以在使用add()
方法的时候添加到指定的区域。GridLayout
是一种网格布局管理器,它将容器空间划分成若干行乘若干列的网格,组件依次放入其中,每个组件占据一格。
GridLayout()
:创建一个只有一行的网格,网格的列数根据实际需要而定。GridLayout(int rows, int cols)
:创建具有指定行数和列数的网格布局管理器。GridLayout(int rows, int cols, int hgap, int vgap)
:创建具有指定行数和列数的网格布局管理器,并且指定垂直间距和水平间距。GridLayout
所管理的相对位置不会变化,但是组件大小会改变。CardLayout
也是定义在java.awt
包下的布局管理器,这是一种卡片式的布局管理器,它将容器的组件处理为一系列卡片,每一时刻只显示出其中的一张,而容器充当卡片的容器。
构造方法
CardLayout()
:创建一个默认无间距的CardLayout
布局管理器。CardLayout(int hgap, int vgap)
:创建一个带有指定间距的卡片布局管理器。成员方法
void first(Container parent)
:翻转到容器的第一张卡片。void last(Container parent)
:翻转到容器的最后一张卡片。void next(Container parent)
:翻转到容器的下一张卡片,如果当前时最后一张,则翻转到第一张。void previous(Container parent)
:翻转到容器的上一张卡片,如果当前是第一张,则翻转到最后一张。void show(Container parent, String name)
:翻转到已添加到此布局的具有指定name的卡片,如果不存在则不发生任何操作。BoxLayout
是定义在java.awt
包中的一种布局管理器,它将容器中的组件按水平方向拍成一行或按垂直方向排成一列。
当组件排成一行时,每个组件可以有不同的宽带;当组件排成一列时,每个组件可以又不同的高度。
BoxLayout(Container target, int axis)
:创建一个将沿给定轴放置组件的布局管理器。target
指定为哪个容器设置此BoxLayout
布局;axis
用于指定组件的排列方向,常用常量为BoxLayout.X_AXIS
与BoxLayout.Y_AXIS
表示水平方向排列或垂直方向排列。
在java.swing
包中提供了Box
类,使用这个类能够更加方便的创建具有BoxLayout
的容器。
方法
static Box createHorizontalBox()
:使用水平方向的BoxLayout
。static Box createVerticalBox()
:使用垂直方向的BoxLayout
。空布局指的是不使用布局管理器的情况,通过数值指定组件的位置和大小。
在使用空布局的时候首先要将容器的布局设置为null(setLayout(null)
),然后调用组件的set Bounds()
方法设置组件的大小和位置。
void setBounds(int x, int y, int width, int height)
:x
与y
设置组件的位置,width
与height
设置组件的宽和高。
定义:用户在程序界面所进行的操作称为用户事件,对用户事件的响应称为事件处理。
用户对程序组件进行的操作响应称为事件。
每种事件源可以发出多种不同类型的事件,在程序中为每个事件源指定一个或多个侦听者对事件进行侦听,每当数据源的某个事件发生,就会触发相应的侦听事件。
数据源:鼠标
事件:鼠标移动、鼠标双击、鼠标单击…
侦听器是为了侦听用户与组件之间的交互情况,从而做出不同的相应。
为了接受并处理某个类用户事件,组件必须注册相应的事件处理程序,这种事件处理程序称为事件侦听程序,也成为侦听器。它是实现了对应侦听程序接口的一个类。
添加侦听器与移除侦听器都是在组件之上所进行的,所以以下两个方法需要组件对象来进行调用。
添加侦听器
void addActionListener(ActionListener l)
:方法参数就是要添加的侦听器。
移除侦听器
void removeActionListener(ActionListener l)
:方法参数就是要移除的侦听器,移除后用户对应的操作将不再被侦听到。
ActionEvent
是事件,也就是一个组件有用的哪些事件。
ActionListener
:则是事件对应的侦听器,能够侦听到组件的事件是否执行;侦听到事件执行后,做出某些动作。
组件、事件、侦听器之间的关系
组件和事件之间是多对多的关系;一个组件对应多个事件,一个事件可以由多个组件触发。
事件和侦听器之间的关系是一对一;即一个事件对应有一个侦听器,此侦听器就负责侦听对应的事件是否被触发。
关于事件相关的接口都在java.awt.event
包与java.swing.event
包下。
**使用注意:**凡是需要接收并处理事件类对象的类(事件发生后需要执行的类),都需要实现事件对应的侦听接口。
事件侦听模式允许为一个组件注册多个事件侦听。
为了实现对组件事件的处理,需要实现Listener
接口的类;然而在某些Listener
接口中声明了很多抽象方法,为了实现这个接口,需要一一实现这些方法。然而在某些情况下我们只关心接口中的某个方法,但也不得不把Listener
接口中的方法全部重写。
这样就比较麻烦,所以Java就提供了Adapter
适配器,先有Adapter
去实现各个Listener
接口,然后重写接口中的方法(方法体为空)。因为Adapter
是一个抽象类,所以我们在定义事件监听类的时候,直接继承Adapter
适配器类,重写我们需要的方法就行了。
Listener接口
public interface MouseListener extends EventListener { public void mouseClicked(MouseEvent e); public void mousePressed(MouseEvent e); public void mouseReleased(MouseEvent e); public void mouseEntered(MouseEvent e); public void mouseExited(MouseEvent e); }
Adapter适配器类
public abstract class MouseAdapter implements MouseListener, MouseWheelListener, MouseMotionListener { public void mouseClicked(MouseEvent e) {} public void mousePressed(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} public void mouseWheelMoved(MouseWheelEvent e){} public void mouseDragged(MouseEvent e){} public void mouseMoved(MouseEvent e){} }
JDK中并没有为所有的监听器接口都提供相应的适配器类。
绘图过程说明
Java中使用java.awt
包下的Color
类来定义和管理颜色。
使用Java中预定义的颜色
自定义RGB组合确定颜色
通过三原色红、绿、蓝三种颜色的组合,来产生新颜色。
Color color = new Color(float r, float g, float b)
画图对象调用
drawChars(char data[], int offset, int length, int x, int y)
使用此图形上下文的当前字体和颜色,从数组data
的下标索引offset
处,取length
个字符,从图形的x
和y
处开始绘画。
void drawString(String str, int x, int y)
在指定位置显示字符串str
。
drawBytes(byte data[], int offset, int length, int x, int y)
使用与第一个方法相同。
Font类预定义文本字体
Font(String name, int style, int size)
根据指定的字体名称(如宋体)、样式(斜体、粗体)和字号创建一个新的Font对象。
setFont(Font f)
:通过组件的setFont()
方法,将预定于的文本字体设置到组件中。
GrapHics
是java.awt
包下的类,用于显示和管理图形信息,是所有图形上下文的抽象父类。
建立字体、设置显示颜色、显示图像和文本、回值和填充几何图形等。
组件上的绘图模型主要分为两类——正常模式和异或模式。
正常模式
正常模式下,后绘制的图形会覆盖掉先绘制的图形。
异或模式
异或模式下,当前绘制的颜色、先前回值的颜色以及所选定的颜色之间会进行某种处理,得到新的颜色进行绘制。
Graphics
设置绘图模式的方法:
void setPaintMode()
:将此图形的绘图模式设置为正常模式。默认正常模式。void setXORMode(Color c1)
:将图形的绘图模式设置为异或模式,c1
指定颜色。paintComponent(Graphics g)
方法,在该方法中进行绘图。画圆方法
drawPolygon()
fillPolygon
其他方法自行查阅。
为了解决图形对象的局限性,Java引入了一个Graphics2D
类,增加了许多状态属性,扩展了Graphics
的绘图功能。
Graphics2D
类中定义了几种方法,用于添加或改变图形的状态属性。
stroke属性
作用
stroke
属性控制线的宽度、笔形样式、线段连接方式和短划线图案。
使用
创建BasicStroke
对象,然后再调用setStroke()
方法即可设置stroke
属性。
构造方法
BasicStroke(float width)
:指定线的宽度。
paint属性
作用
paint
属性控制填充效果。
使用
先调用GradientPaint()
方法确定填充效果,再使用setPaint()
方法继续设置。
transform属性
作用
该属性用来实现常用的图形平移、缩放和斜切等变换操作。
使用
首先创建AffineTransform
对象,然后调用setTransform
方法,设置transform
的属性;
最后使用具有指定属性的Graphics2D
对象绘制图形。
构造方法
AffineTransform()
clip属性
作用
clip
属性用于实现建材效果。
composit属性
composit
属性设置图形重叠区域的效果。
Graphics2D
类的绘图方法Graphics与Graphics2D的不同
Graphics2D
仍然保留着Graphics
的绘图方法,同时增加了许多新的方法。新方法将几何图形作为一个对象来绘制。
几何图形对象
Line2D
:线段类RoundRectangle2D
:圆角矩形类。Ellipse2D
:椭圆类。Arc2D
:圆弧类。QuadCurve2D
:二次曲线类。CubicCurve2D
:三次曲线类。Graphics2D类的使用方法
使用Graphics2D
类的新方法画一个图形的步骤通常是:
paintComponent
或paint()
中,把参数对象g
强制转换为Graphics2D
类型对象。Double()
创建该图形的对象。Graphics2D
对象的draw()
方法绘制这个图形。组合框(JComboBox
),是一个下拉菜单,它拥有两种形式——不可编辑和可编辑的。
对于不可编辑的JComboBox
,用户只能在现有的选项列表中进行选择;对于可编辑的JComnoBox
,用户既可以在现有的选项中选择,又可以输入新的内容。
JComboBox()
:创建一个没有任何可选项的默认组合框。JComboBox(E[] items)
:创建一个带有初始选项的组合框,初始选项就是items
数组中的元素。在组合框对象创建后,默认是不可编辑得;可以通过setEnabled(boolean b)
方法将其设置为可编辑的。
addItem(E item)
:添加选项末尾添加新选项。Object getSelectedItem()
:返回当前所选项。removeItemAt(int anIndex)
:删除指定索引处的选项。组合框上的用户事件既可以通过ActionListener
处理,也可以通过ItemListener
处理。
用户输入项目后按<Enter>
键,对应的接口是ActionListener
,而用户选中选项,对应的接口是ItemListener
。
列表JList
是一个可供用户进行选择的一系列可选项。
JList()
:构造一个空列表。JList(final E[] listData)
:构造一个列表,列表的可选项又对象数组listData
指定。当用户在列表上进行选择时,将引发ListSelectedEvent
事件。
在JList
中,提供了addListSelectionListener(ListSelectionListener listener)
方法,用于注册对应的事件侦听程序。
ListSelectionListener
接口中只包含一个方法void valueChanged(ListSelectionEvent e);
,当列表的当前选项发生变化时,将会调用该方法。
int getSelectedIndex()
:返回所选项第一次出现的索引;如果没有所选项,则返回-1。E getSelectedValue()
:返回所选的第一个值,如果选择为空,则返回null。void setVisibleRowCount(int visibleRowCount)
:设置不使用滚动条可以在列表中显示的首选行数。可以使用JList
中定义的setModel(ListModel<E> model)
方法,设置新的列表选项。
当列表可选项较多时,可以将列表对象放入JScrollPane
滚动窗口中,以提供滚动功能。
列表既支持单项选择,又支持多项选择;可以使用JList
中定义的setSelectionMode(int selectionMode)
方法,对列表的选择模式进行设置。
selectionMode常量:
ListSelectionModel.SINGLE_SELECTION
只能进行单项选择。
ListSelectionModel.SINGLE_INTERVAL_SELECTION
可多项选择,但多个选项时必须连续的。
ListSelectionModel.MULTIPLE_INTERVAL_SELECTION
可以多项选择,且多个选项之间可以间断的,设置默认选择模式。
文本组件的定义
文本组件可用于显示信息和提供用户输入功能。
文本组件的分类和共有
分类
在Swing中提供了文本域JTextField
、口令输入区JPasswordField
、文本区JTextArea
等多个文本组件,这些文本组件都有一个共同父类——JTextComponent
。
共有方法
String getSelectedText()
:从文本组件中提取被选中的内容。String getText()
:从文本组件中提取所有文本内容。String getText(int offs, int len)
:从文本组件中获取指定范围内的文本内容。void select(int selectionStart, int selectionEnd)
:在文本组件中选中指定的起始位置和结束位置之间的文本内容。void setText(String t)
:这只文本组件中的文本内容boolean requestFocusInWindow()
:获取当前组件的输入焦点。文本域是一个单行的文本输入框,用于输入少量文本。
JTextField()
:构造一个空的文本域。JTextField(int columns)
:构造一个带有指定列数的空文本域。JTextField(String text)
:构造一个带有初始文本的文本域。synchronized void addActionListener(ActionListener l)
为当前文本域添加指定的监听器,接受操作事件。
synchronized void removeActionListener(ActionListener l)
移除当前文本域的监听器。
void setFont(Font f)
:设置字体大小。
void setHorizontalAlignment(int alignment)
设置文本的水平对齐方式。
在构造方法中指定的列数是一个希望数值;由于组件的大小和位置受布局管理器的决定,所以指定的数值有可能不准确。
文本区是要给多行多列的文本输入框。
JTextArea()
:构造一个空的文本区。JTextArea(String text)
:构造一个显示初始字符的文本区。JTextArea(String text, int rows, int columns)
:构造一个显示初始字符,并且指定文本区的行数和列数。void append(String str)
:追加字符到文本区中。void insert(String str, int pos)
:将指定文本插入到文本区的pos
特定位置处。void replaceRange(String str, int start, int end)
:将指定起始位置上的文本替换为str
新文本。通常时在文本区旁提供一个按钮,当用户点击时表示输入完成;我们只需要对按钮的点击事件进行监听即可。
JSrollPane
滚动窗格中。菜单组件的分类
菜单分为下拉式菜单和弹出式菜单两种。
菜单栏是窗口的主菜单,用来包容一组菜单。
菜单是最基本的下拉菜单,用来包容一组菜单项或子菜单。
JMenuBar()
,用于构建菜单栏。
方法:void setJMenuBar(JMenuBar menubar)
,将菜单栏放置窗口的上方。
JMenu()
:构造一个没有文本的菜单。JMenu(String s)
:构造一个带有指定标签的菜单。JMenu(String s, boolean b)
:构造一个具有指定便签的菜单,b
代表该菜单是否可以分离。使用JMenuBar
提供的JMenu add(JMenu c)
方法,放菜单加入菜单栏中。
如果将整个菜单系统看作是一棵树,那么菜单项就是这棵树的叶子,是菜单系统最下面的一级。
菜单项是挂载在菜单下的。
JMenuItem()
:构造一个空的菜单项。JMenuItem(Icon icon)
:构造一个具有指定图标的菜单项。JMenuItem(String text)
:构造一个具有指定文本标签的菜单项。JMenuItem(String text, Icon icon)
:构造一个具有指定图标和文本的菜单项。JMenuItem(String text, int mnemonic)
:构造一个具有指定文本和快捷键的菜单项;mnemonic
指定快捷键。在菜单被创建后,还可以通过JMenuItem
类提供的void setMnemonic(char mnemonic)
方法,设置菜单项的快捷键。
Menu类中定义的方法
void addSeparator()
:在菜单项后加入分割线。void insertSeparator(int index)
:在指定的索引位置处加入菜单项的分割线。java.swing包中的JSepatator类
JSeparator()
:创建一个分割线实例,然后通过JMenu
类中的Component add(Component c)
方法,将分割线实例加入菜单。当菜单中的菜单项被选中的时候,将会引发一个ActionEvent
事件,因为在定义菜单项的时候,可以其注册ActionListener
监听器,以便做出响应。
awt包中的MenuItem类
addActionListener(ActionListener l)
JMenuItem类
void addMenuKeyListener(MenuKeyListener l)
复选菜单项和单选菜单项是两种特殊的菜单项,复选菜单项前有一个小方框,单选菜单项前有个小圈圈。
由于复选菜单项与单选菜单项具有选中与未选中两种状态,所以在其各自的构造方法中,只用boolean
参数指定菜单项的初始状态。(默认未选中)
JCheckBoxMenuItem()
:创建一个空白复选菜单项。JCheckBoxMenuItem(Icon icon)
:创建一个带有图标的复选菜单项。JCheckBoxMenuItem(String text)
:创建一个带有文字标签的复选菜单项。JCheckBoxMenuItem(String text, Icon icon, boolean b)
:创建一个带有文字标签和图标的复选菜单项,b
参数指定该菜单项默认状态是否被选中。JRadioButtonMenuItem()
:创建一个空白的单选菜单项。JRadioButtonMenuItem(String text, Icon icon)
:创建一个带有文字标签和图标的单选菜单项。JRadioButtonMenuItem(String text, Icon icon, boolean selected)
:创建一个带有文字标签和图标的单选菜单项,selected
参数指定该菜单项默认状态是否被选中。当菜单项的状态发生改变时,会引发ItemEvent
事件,可以使用ItemListener
接口中的itemStateChanged()
方法,处理菜单项的状态改变事件。
setMenuBar()
方法,加入框架中。add()
方法添加到菜单栏中。add()
方法添加到菜单中。对话框是一个临时的可移动的窗口,且要依赖于其他窗口;当他依赖的窗口消失或最小化时,对话框也将消失;当依赖窗口还原时,对话框也将自动恢复。
首先要创建一个窗口类,再创建一个对话框类,且让对话框依赖于窗口。
分类
对话框分为强制型和非强制型。
特点
强制型的对话框被关闭前,其它窗口无法接受任何形式的输入,也就是该对话框不能中断,这样的窗口称为模式窗口。
非强制型对话框可以终端对话过程,去响应对话框之外的事件。这样的窗口称为无模式窗口。
JDialog()
:创建一个空白对话框。JDialog(Dialog owner, String title, boolean modal)
:创建一个具有指定标题和指定所有者的对话框,modal
参数指定对话框是有模式窗口还是无模式窗口。JDialog(Frame owner, String title, boolean modal)
:创建一个具有指定标题和指定所有者的对话框,modal
参数指定对话框是有模式窗口还是无模式窗口。刚刚创建的对话框是不可见的,需要调用setVisble(true)
方法才能将其显示出来。
当对话框不需要显示的时候,调用setVisble(false)
方法可以隐藏对话框。
注:对话框也是顶层容器,可以向对话框的内容窗格中添加各种组件。
JDialog
类通常用于创建自定义的对话框;在swing
包下还提供了JOptionPane
类,此类用于显示标准的对话框。
确认对话框,显示问题,要求用户进行确认(yes/no/cancel)
static int showConfirmDialog(Component parentComponent, Object message)
输入对话框,提时用户输入。
String showInputDialog(Component parentComponent, Object message)
信息对话框,显示信息,提示用户。
static void showMessageDialog(Component parentComponent, Object message)
选项对话框,显示选项,要求用户选择。
static int showOptionDialog(Component parentComponent, Object message, String title, int optionType, int messageType, Icon icon, Object[] options, Object initialValue)
文件对话框时专门用于对文件或目录进行浏览和选择的对话框。
JFileChooser()
:构造一个执行用户默认目录的文件对话框。JFileChooser(File currentDirectory)
:使用给定的File
作为路径来构造一个文件对话框。JFileChooser(String currentDirectoryPath)
:构造一个给定路径的文件对话框。住:刚刚创建的文件对话框是不见的,需要调用以下方法将其显示,在让其显示的时候,也就定义了文件对话框的类型。
int showOpenDialog(Component parent)
:弹出一个“打开”类型文件对话框。int showSaveDialog(Component parent)
:弹出一个“保存”类型文件对话框。当用户进行文件选择后,可以通过File getSelectedFile()
方法获取用户所选文件。(JFileChooser
类的方法)
进程就是程序在处理机中的一次运行,简单来说,进程就是计算机中运行的应用程序。
在进程运行的时候,计算机会为其分配资源,如CPU、内存、端口等;不同进程所占用的系统资源相对独立。
线程是进程中的最小执行单位。
多线程可以使系统资源的利用率得到提高,也能够提升整个程序的执行效率。
java的线程是由java.lang
包下的Thread
类来实现的;当生成一个Thread
类对象的时候,及创建了一个线程,通过该对象,可以控制线程的启动、终止、或挂起线程。
Thread
类中的run()
方法,称为线程体,里面就是线程要执行的程序。
线程的状态
线程一共有4中状态,新建、可运行、阻塞、死亡。
线程对象通过Thread
类创建,此时还处于未运行状态,但是已经有了相应的内存空间和其他资源。
此时线程已经启动,在这种状态下线程有可能正在运行,也有可能没有运行,处于等待状态;只要CPU有空闲,那么处于等待状态的线程马上就会运行。
处于等待状态的线程都排在一个就绪队列中。
可运行状态下,正在运行的线程处于运行状态,等待运行的线程处于就绪状态。
线程死亡的原因有两个:一是线程体执行完毕,线程正常死亡,二是当线程遇到异常退出便进入了死亡状态。
一个正在执行的线程因特殊原因被暂停执行,进入阻塞状态,
阻塞线程不能进入就绪队列,必须等阻塞状态移除,才可进入就绪状态。
在Thread
类中提供了方法可以手动中断线程的执行:
void interrupt()
:中断当前线程的执行。boolean interrupted()
:检测并中断当前线程。boolean isInterrupted()
:检测当前线程是否中断。创建线程的两种方法,一是继承Thread
类,二实现Runnable
接口。
java.lang
包下的Thread
类是Java中表示线程的类,如果将一个类定义为Thread
的子类,那么这个类的对象就可以用来表示线程。
Thread(Runnable target)
:通过Runnabel
对象,构造一个Thread
线程对象。
Thread(ThreadGroup group, Runnable target, String name)
group
表示当前构造的Thread
对象属于哪个线程组。
target
表示当前线程任务对象。
name
设置当前线程对象的名称。
PS:Thread
类本身也是Runnable
接口的实现类。
Thread
类。run()
线程体。start()
方法启动线程。PS:只要是Thread
类的子类,都是线程类。
Runable
是Java中用以实现线程的接口,任何实现线程功能的类都必须实现此接口;Thread
类本身也实现了Runnable
接口。
@FunctionalInterface public interface Runnable { public abstract void run(); }
在Thread
接口中只有一个run()
方法,这个方法就是线程的线程体。
Runnable
接口。run()
方法。Thread(Runnable target)
构造函数创建Thread
对象,并通过Thread
对象的run()
方法启动线程。个人理解:在我的理解看来,Runnable
接口的实现类相当于一个线程任务,想要执行这个线程任务,还是需要Thread
类来启动执行这个线程任务。
其实不管用那种方法都可以用来创建线程类,但是需要注意的是Java是单继承制;也就是说一个子类只能直接继承一个父类。所以如果在创建线程类的同时还要继承其他父类,则用Runnable
接口的方法比较好。
通过Thread
类的run()
方法启动。
void start()
:启动线程。void run()
:线程体,也就是线程启动后要执行的方法。void yield()
:强制终止线程的执行。boolean isAlive()
:测试当前线程是否在活动。void sleep(long millis)
:是线程休眠一段时间。void wait()
:使线程处于等待状态。虽然就绪线程可以运行,但并不意味着当前线程就能够立刻运行。
在单核CPU的计算机中,CPU同一时间只能分配给一个线程。
在Java中,线程的调度通常是抢占式,而不是时间片式。抢占式调度指的是可能有多个线程准备运行,但是只有一个在真正运行。只有运行着的线程执行完毕,或因原因阻塞,另一个高优先级的线程才能够抢占CPU从而运行。
Thread
类有3个与线程优先级相关的静态常量。
MAX_PRIORITY
:最高优先级,值为10。MIN_PRIORITY
:最低优先级,值为1。NORM_PRIORITY
:默认优先级,值为5。Thread
类中:
void setPriority(int newPriority)
:重置线程优先级。int getPriority()
:获取当前线程的优先级。void yield()
:停止当前正在执行的线程。所有被阻塞的线程按次排序,组成一个阻塞队列;而所有就绪但未运行的线程则根据优先级进入一个就绪队列。
当CPU空闲时,如果就绪队列不为空,则队列中的第一个具有最高优先权的线程将运行。
当一个线程被抢占而停止运行是,它的运行状态被改变,并放到就绪队列的尾列。
一个被阻塞的线程就绪后,通常也放置就绪队列的尾列。
Sleep()
是Thread
类的静态方法,这个方法只保证当前休眠的线程在一定的时间后回到就绪状态,至于是否能够得到CPU的运行权,则要视线程调度而视,所以通常实际暂停时间比指定时间长。
run()
方法执行完毕,线程自动死亡。interrupt()
方法中断当前线程的执行。PS:Thread currentThread()
获取当前线程。
暂停一个线程也称为挂起,在挂起后,必须重新唤醒线程进入运行状态。
sleep()
sleep()
方法用于暂时停止线程的运行,一段时间后线程会自动醒来;醒来后的线程不会立刻执行,要看线程调度的安排。
wait()、notify()、notifyAll()
wait()
方法用于当前线程等待,直到其他对象调用此线程对象的notify()
方法或者notifyAll()
方法,唤醒等待的线程。
join()
join()
将引起现行线程等待,直至join()
方法所调用的线程结束。
比如在B线程中调用A线程的join()
方法,那么需要等A线程执行完毕后,才会继续执行B线程。
线程的互斥指在同一时间,只能有一个线程访问共享数据,具有排他性和唯一性。
所以需要一种机制来保证线程操作的完整性,要么一段代码全部执行成功,要么都不执行。(原子性操作)
在Java语言中引入了 “对象互斥锁” 的概念,也称监视器;使它用来实现不同线程对共享数据操作的同步。
“对象互斥锁” 用来阻止多个线程同时访问同一个变量。
在Java中有两种方法可以实现 “对象互斥锁”:
volatile
关键字来声明共享数据变量。synchronized
关键字操作共享数据的一个方法或代码。PS:在同一时刻只能有一个任务访问的代码区称为临界区。
当持有锁标志的线程执行完synchronied
包含的程序块后,这个锁标志将会自动返还。
用synchronied
标识的代码段或方法即为 “对象互斥锁” 锁住的部分。
如果一个程序内有两个或以上的方式使用synchronized
标志,则它们在同一个 “对象互斥所” 的管理下。
使用synchronized
关键字锁在方法上要比锁住某个代码块的效率要低一点。
使用synchronized
关键字的程序也叫做同步代码块
线程的同步指的是在线程互斥的基础上,实现线程的有序访问,最终让程序正确执行。
在Java语言中,可以用wait()
、notify()
与notifyAll()
,来协调线程之间的执行速度,达到有序访问的效果。
wait()
方法让当前线程等待,进去等待队列,并释放当前线程所持有的锁对象。
notify
与notifyAll
方法则是唤醒使用wait()
等待的线程,并将它们移入抢锁队列中,抢到锁则执行线程。
在使用一个对象的wait()
、notify()
与notifyAll()
方法时,必须持有该对象的所标志。
当一个线程调用了wait()
方法后,这个线程就进入了等待状态,等待被线程唤醒。
而将等待线程唤醒的方法有两种,一种是使用notify()
方法,而另一种是使用interrupt()
方法。
完!