Java语法基础
Java的特点:
面向对象,跨平台,解释型,多线程,安全,动态
Java源程序(.java)编译生成字节码文件(.class)
Java 程序结构
源文件(.java)由类组成(一个或多个)
一个源文件至多有一个public类
源文件名与( public )类名相同,如果源文件没有public类,那么源文件的名字只要和某个类的名字相同,并且扩展名是.java就可以了
标识符:
1.标识符由字母、下划线、美元符号和数字组成,且第一个字符不能为数字。
2. 标识符不能是关键字、true、false、null。
注:标识符区分大小写!
Java的数据类型
基本类型:整型、浮点型、布尔型和字符型;
整型:byte(1B),short(2B),int(4B),long(8B用后缀L来表示)
浮点型:float(4B必须要有后缀“f”或“F”),double(8B后面可以有后缀“d”或“D”,但允许省略该后缀)
字符型:char(2B)
布尔型:boolen
输入、输出数据
输入数据
从键盘为基本型变量输入值的主要步骤:import java.util.Scanner;
使用Scanner类创建一个对象 Scanner reader = new Scanner(System.in);
reader对象调用下列方法,读取用户在命令行输入的各种基本类型数据:
nextBoolean(),nextByte(),nextShort(),nextInt(),nextLong(),
nextFloat(),nextDouble()。
例:double x=reader. nextDouble()
输出数据
(1)println()
System.out.println()或System.out.print()可输出串值、表达式的值,二者的区别是前者输出数据后换行,后者不换行。
(2)printf()
printf输出数据的格式如下:
System.out.printf("格式控制部分",表达式1,表达式2,…表达式n)
格式控制部分由格式控制符号:%b、%d、%c、%f、%s
数组
使用数组四步走:
- 声明数组 int [] a;
Java不允许在声明数组中的方括号内指定数组元素的个数。
2、分配空间 a=new int[5;]
3、赋值 a[0]=8;
4、处理数据 a[0]=a[0]*10;
赋值
a.静态初始化: 指定每个数组元素的初始值,系统决定数组长度。
int[ ] a = {89, 79, 76}; 或
int[ ] a = new int[ ]{89, 79, 76}; 边声明边赋值
b.动态初始化: 指定数组长度,系统默认赋初值
int[ ] a = new int[3];
a[0] = 89; a[1] = 79; a[2] = 76;
动态地从键盘录入信息并赋值
Scanner input = new Scanner(System.in);
for(int i = 0; i < 30; i ++){
score[i] = input.nextInt();
}
Java数组的for循环遍历数组元素
for(声明循环变量:数组的名字) { }
例: for(int i:a)
System.out.println(i);
//循环变量i依次取数组a中的每一个元素的值
二维数组
int[ ][ ] a = new int[3][4];
类 类的目的是抽象出一类事物共有的属性和行为。
编程风格:1)类名的首字母大写,如果类名是由几个单词复合而成的,每个单词的首字母都应大写;
2)一行只声明一个变量;
3)变量的名字首单词的首字母使用小写,如果变量的名字由多个单词组成,从第二个单词开始的其它单词的首字母使用大写;
类由两部分组成:1.变量的声明(用来存储属性的值)2方法的定义(对类中声明的变量进行操作,即给出算法)
区分成员变量和局部变量:
成员变量在整个类内都有效,其有效性与它在类体中书写的先后位置无关
局部变量只在方法内有效,而且与声明的位置有关,从它声明的位置之后开始有效
如果局部变量的名字和成员变量的名字相同,则成员变量被隐藏,如果想在该方法中使用被隐藏的成员变量,必须使用关键字this
成员变量有默认值,但局部变量没有默认值,因此在使用局部变量之前,必须保证局部变量有具体的值
构造方法:
构造方法是类中的一种特殊的方法,当程序用类创建对象时需使用它的构造方法
类中的构造方法的名字必须使用与它所在的类的名字完全相同,而且没有类型(也不能是void),允许一个类中编写若干个构造方法,但必须保证他们的参数不同
注:如果类中没有编写构造方法,系统会默认该类只有一个构造方法,该默认的构造方法是无参数的,且方法体中没有语句;如果类里定义了一个或多个构造方法,那么java不提供默认的构造方法
创建对象
包括对象的声明和为对象分配变量
声明:类的名字 对象的名字
分配变量:使用new运算符
使用对象:对象.变量 对象.方法 实现对自己的变量的访问和方法的调用
对象的创建过程:
- New 首先在堆上为对象分配内存空间;
- 存储空间清零;(基本类型赋0,引用类型设置为null)
- 执行出现于字段定义处的初始化动作;
- 执行构造函数;
- New返回该块内存的首地址,赋给对象名。
Java中,方法的所有参数都是“传值”的。
基本类型:传递值的拷贝
引用类型:传递引用 (引用类型包括:数组、对象、接口等)
类是体现封装的一种数据类型,类声明的变量称为对象,对象中负责存放引用
一个Java应用程序(也称为一个工程)是由若干个类所构成,这些类可以在一个源文件中,也可以分布在若干个源文件中 。
关联关系(组合)
如果A类的变量成员是B类的对象(A类的对象组合了B类的对象)称:A关联于B
依赖关系:
A类中某个方法的参数是B类的对象或A类中某个方法的返回值类型是B类的对象,则称A依赖于B
实例变量和类变量:
成员变量可以细分为实例变量和类变量
在声明成员变量时,用关键字static修饰的称作类变量(类变量也称为static变量——静态变量),否则称作实例变量。不同对象的实例变量互不相同,而所有对象共享类变量
用关键字static修饰的方法称为类方法
通过类名直接访问类变量
类变量/方法既可以通过类名调用(即不创建任何对象也可以调用),也可以通过对象名调用。实例变量/方法只能通过对象名调用。
注:static方法不能访问非static的变量或方法,实例方法不仅可以操作实例变量,也可以操作类变量
方法的重载
一个类中可以有多个方法具有相同的名字,但这些方法的参数必须不同(参数个数不同或某个参数类型不同)
注:方法的返回值类型和参数的名字不参与比较,也就是说如果两个方法的名字相同,即使返回类型不同,也必须保证参数不同
this关键字
this代表“当前对象”的引用
this不能出现在类方法中,因为这时可能还没有任何对象产生
this多用在区分变量成员(成员变量和局部变量)与形参
包
包的本质就是文件夹(目录)。
包的意义:文件(字节码)管理。
如果源程序中没有声明类所在的包,则类在默认包(default)中
Import使用:一个类需要使用的类和它不在一个包中
Import位置: package语句和类的定义之间
特别:如果要引入一个包中的全部类,则可以用通配符号星号(*)来代替,如:import java.util.*;
访问权限修饰符:
类成员(属性和方法)的权限
private(私有)、default(友好/包权限)、protected(保护)和public(公共)
访问权限排序:(高à低)public > protected > default(默认的/友好的/包权限) > private
类的访问权限public、default(包),不能用protected,private修饰
1.public
用public修饰的成员变量和方法被称为共有变量和共有方法。
无论是谁,无论在哪里,都可以访问该成员。在任何地方都可以访问
2. default默认(包权限,友好权限)
不用private、public、protected修饰符的成员变量和方法被称为友好变量和友好方法。
处于相同的目录且没有设定任何包名称,Java将这样的文件看作隶属于该目录的默认包(default package)中。
包权限:同一包内的类或对象可以访问类的成员,包外的不可以。在类的内部,同一个包中访问
3.protected
用protected修饰的成员变量和方法被称为受保护的成员变量和受保护的方法。
应用场景:基类(父类)将某个成员的访问权限赋予派生类,而不是所有类。
protected也提供包访问权限。即相同包内的其他类可访问protected成员。在类的内部,同一个包中,子类中访问
4. private权限
用关键字private修饰的成员变量和方法称为私有变量和私有方法。
除了包含该成员的类之外,其他任何类都无法访问这个成员。只能在该类的内部访问
继承
Java是单继承,即有且仅有一个父类。
树形结构的根节点为Object类
没使用extends默认是Object的子类
注:有些父类成员不能被继承,private成员、子类与父类不在同包,使用默认访问权限的成员、构造方法
protected可以修饰属性和方法本类、同包、子类(同包、不同包)可以访问
继承是代码重用的一种方式
符合is-a关系的设计使用继承
将子类都有的属性和行为放到父类中
变量隐藏
子类中有和父类有重名的变量,名字相同,声明的类型可以不同,子类将隐藏父类变量,
变量隐藏的特点:
子类对象及子类自定义的方法操作的是子类新声明的变量
继承的方法操作的是父类的变量(被隐藏的变量)
方法重写:
重写的目的是通过方法的重写隐藏继承的方法,可以把父类的状态和行为改变为自身的状态和行为
子类中有和父类相同名字的方法,子类将重写父类方法
方法重写必须满足如下要求:
重写方法和被重写方法必须具有相同的方法名;
重写方法和被重写方法必须具有相同的参数列表;
重写方法的返回值类型必须和被重写方法的返回值类型相同或者是其子类;
重写方法的不能缩小被重写方法的访问权限。
方法重写的规则
在继承关系的子类中
重写的方法名、参数、返回值类型必须与父类相同
私有方法不能继承因而也无法重写
方法的重写和方法的重载
位置 | 方法名 | 参数表 | 返回值 | 访问修饰符 | |
方法重写 | 子类 | 相同 | 相同 | 相同 | 不能比父类更严格 |
方法重载 | 同类 | 相同 | 不同 | 无关 | 无关 |
子类访问被隐藏的父类成员
在子类中可以通过super关键字来访问父类的成员。
super必须是出现在子类中(子类的方法和构造方法中),而不是其他位置。
是访问父类的成员,例如父类的属性、方法、构造方法。
注意访问权限的限制,例如无法通过super访问private成员。
注:加super可以访问父类,构造方法不能被继承因此不能被重写继承中的构造方法
构造方法不能被继承因此不能重写
子类如何访问被隐藏的父类成员
super();默认的
super(参数表);必须是子类构造方法中的头一条语句
当用子类的构造方法创建一个子类的对象时,子类的构造方法总是先调用父类的某个构造方法,也就是说,如果子类的构造方法没有明显的指明使用父类的哪个构造方法,子类就调用父类的不带参数的构造方法;由于子类不继承父类的构造方法,因此,子类在其构造中需使用super关键字来调用父类的构造方法,而且super必须是子类构造方法中的头一条语句。
继承条件下构造方法的调用规则如下:
如果子类的构造方法中没有通过super显式调用父类的有参构造方法,也没有通过this显式调用自身的其他构造方法,则系统会默认先调用父类的无参构造方法。在这种情况下,写不写“super();”语句,效果是一样的。
如果子类的构造方法中通过super显式调用父类的有参构造方法,那将执行父类相应构造方法,而不执行父类无参构造方法。
如果子类的构造方法中通过this显式调用自身的其他构造方法,在相应构造方法中应用以上两条规则。
特别注意的是,如果存在多级继承关系,在创建一个子类对象时,以上规则会多次向更高一级父类应用,一直到执行顶级父类Object类的无参构造方法为止。
继承后的初始化顺序
先调用父类的构造方法,再执行子类的构造方法。当创建了一个子类的对象时,该对象包含了一个父类的对象。
final用法
final类:不能被继承。
final方法:不允许子类重写。
final 变量:变量变常量。在运行期间不允许被修改
(常量分为编译时常量-基本类型和运行时常量-如对象引用。对象引用一旦指定就不可以再指向其他的对象,但不影响对象本身的改变。
由于常量在运行时不再发生变化,于是常量在声明时没有默认值,这就要求程序在声明常量时必须指定该常量的值)
多态
Java中使用抽象类,限制实例化,不允许实例化,即不能使用new关键字
abstract也可用于方法——抽象方法
抽象方法没有方法体(只允许声明,不允许实现,而且不允许使用final和abstract同时修饰一个方法或类,也不允许使用static修饰abstract方法,即abstract方法必须是实例方法,不允许使用private修饰abstract方法,因为abstract方法必须被子类重写)
抽象方法必须在抽象类里
抽象方法必须在子类中被实现,除非子类是抽象类,Abstract类中可以没有Abstract方法。
Abstract类的对象作为上转型对象
将父类的对象变量指向一个子类对象。——自动完成
Pet p = new Dog(); 目的是实现多态。
注:向上转型时,调用被子类重写的方法时,调用的是子类的方法,从而实现了多态。
向下转型:将子类的对象变量指向一个父类对象。——强制类型转换
Dog d = (Dog) p;
对象 instanceof 类或接口
该运算符用来判断一个对象是否属于一个类或者实现了一个接口,结果为true或false
接口
接口是一种极度抽象的类型,它比抽象类更加“抽象”
为什么使用接口
飞机和鸟是不同类的事物,但是它们都有一个共性,就是都会飞。
接口的定义
使用关键字interface来定义一个接口。接口的定义和类的定义很相似,分为接口的声明和接口体,
接口使用关键字interface来声明自己是一个接口
格式: interface 接口的名字
接口体中包含常量的声明和抽象方法两部分。
接口体中所有的常量的访问权限一定都是public,而且是static常量。
所有的抽象方法的访问权限一定都是public
接口由类来实现,即由类来重写接口中的方法。一个类可以在类声明中使用关键字implements声明实现一个或多个接口。如果类实现多个接口,用逗号隔开接口名。
如果一个非抽象类实现了某个接口,那么这个类必须重写这个接口中的所有方法。
抽象类既可以重写接口中的方法,也可以直接拥有接口中的方法。
由于接口中的方法一定是public abstract方法,所以类在重写接口方法时不仅要去掉abstract修饰符、给出方法体,而且方法的访问权限一定要明显地用public来修饰
- 接口就是一些方法特征的集合。
- 接口的定义:用interface关键字
- 接口的属性只能为公共、静态常量,即需要用用关键字public、static、final修饰。但是这三个关键字可以省略。
- 接口的方法只能是公共的抽象方法,即用关键字public 和abstract修饰,但是这两个关键字可以省略。
- 接口和抽象类的用法类似!
- 接口和抽象类的区别:从语法上看一个类可以实现多个接口,但是一个类只能有一个父类。
- 接口的实现:通过类使用implements关键字类实现。
- 接口回调:可以把实现某一接口类创建的对象的引用赋值给该接口声明的接口变量,那么该接口变量就可以调用被类实现的接口的方法。
- 接口的思想在于它可以要求某些类有相同名称的方法,但方法的具体内容可以不同,即要求这些类实现接口,以保证这些类一定有接口中所声明的方法(即所谓的方法绑定)。
抽象类作为很多子类的父类,它是一种模板式设计。而接口是一种行为规范,它是一种辐射式设计
接口回调就是指:可以把实现某一接口的类创建的对象的引用赋给该接口声明的接口变量中,那么该接口变量就可以调用被类实现的接口方法。实际上,当接口变量调用被类实现的接口方法时,就是通知相应的对象调用这个方法。
接口与多态
把实现接口的类的实例的引用赋值给接口变量后,该接口变量就可以回调类重写的接口方法。
由接口产生的多态就是指不同的类在实现同一个接口时可能具有不同的实现方式,那么接口变量在回调接口方法时就可能具有多种形态。
异常
异常就是在程序的运行过程中所发生的不正常的事件,它会中断正在运行的程序
异常处理是通过5个关键字来实现的:try(执行可能产生异常的代码)、catch(抛出异常)、 finally(无论是否发生异常,代码总能执行)、throw(抛出异常)、throws(声明异常)
printStackTrace的堆栈跟踪功能显示出程序运行到当前类的执行流程
在try-catch块后加入finally块,可以确保无论是否发生异常,finally块中的代码总能被执行
finally块中语句不执行的唯一情况
异常处理代码中执行System.exit(1)退出Java虚拟机
常见的异常类型
Exception | 异常层次结构的根类 |
ArithmeticException | 算术错误情形,如以零作除数 |
ArrayIndexOutOfBoundsException | 数组下标越界 |
NullPointerException | 尝试访问 null 对象成员 |
ClassNotFoundException | 不能加载所需的类 |
InputMismatchException | 欲得到数据类型与实际输入类型不匹配 |
IllegalArgumentException | 方法接收到非法参数 |
ClassCastException | 对象强制类型转换出错 |
NumberFormatException | 数字格式转换异常,如把"abc"转换成数字 |
throws出现在方法函数头;而throw出现在函数体
throw new Exception();抛出异常
throw不能单独使用,必须和catch一起使用,或者在方法头上加上throws Exception
图形用户界面
java.awt包中的类创建的组件称为重组件,重组件用来实现和本地操作系统的交互。
AWT组件相比,Swing组件的名字前多一个“J”字母。AWT组件在java.awt包中,Swing组件在javax.swing包中。
java.awt包中Component类的直接子类或间接子类创建的对象称为组件,Container的直接子类或间接子类创建的对象称为容器。容器用来放置组件,组件放置在容器中。由于Container类是Component类的子类,所以容器也是组件,可以添加到其他容器中实现容器的嵌套。
Swing容器主要有两类:
- 顶层容器:包含其它容器的容器。每个图形界面程序都有一个顶层容器,主要有JApplet、JFrame和JDialog。这三个容器都是重组件。
- 中间层容器:用来添加其它组件的容器,不能做顶层容器,可以添加到顶层容器或其它容器中。主要有JPanel(面板)、JScrollPane(滚动窗格) 、JSplitPane(拆分窗格)、JLayeredPane(分层窗格)等。
.容器和组件的使用
- 可以向容器中添加组件。Container类提供了一个方法add(),被所有的容器类所继承,一个容器可以调用这个方法将组件添加到自身中。
- 调用removeAll()方法可以移除容器中的全部组件,调用remove(Component c)方法可以移除容器中的指定组件。
- 往容器中添加组件或移除组件后,接下来应当调用容器的validate()方法,以保证容器中的组件能正确显示出来。
- javax.swing中有4个最重要的类JApplet,JFrame,JDialog和JComponent。JFrame、JApplet、JDialog是重组件,因而窗体(JFrame)、对话框(JDialog)、小应用程序(JApplet)可以和本地操作系统直接交互。而JComponent的子类都是轻组件,
当应用程序需要一个窗口时,可使用JFrame或其子类创建一个对象,不允许将一个窗口添加到另一个容器中。包括JFrame在内,每个顶层容器包含一个狭窄的矩形区域,称为菜单条区域,另一个是菜单条下面的区域,称为内容窗格(Content pane)。
JFrame类常用方法:
JFrame():创建一个无标题的窗口;JFrame(String s):创建一个标题为s的窗口。
void setBounds(int a, int b, int width, int height):同时设置窗口的位置和大小:
void setLocation(int x, int y):将组件移到指定位置
void setSize(int width, int height):设置窗口的大小
void setVisible(boolean b):设置窗口是可见还是不可见,窗口默认是不可见的。设置窗口可见性,必须
void setResizable(boolean b):设置窗口是否可调整大小,窗口默认是可调整大小的。
void setDefaultCloseOperation(int operation):该方法用来设置单击窗体右上角的关闭图标后,程序会做出怎样的处理,如果不调用该方法,则点击关闭按钮后,窗口关闭操作无响应。设置窗口关闭方式,必须四种关闭方式。
JFrame.DO_NOTHING_ON_CLOSE:无操作(什么也不做);
JFrame.HIDE_ON_CLOSE:隐藏窗口(窗口对象还在,只是看不见);
JFrame.DISPOSE_ON_CLOSE:移除窗口(窗口对象撤销,不退出程序);
JFrame.EXIT_ON_CLOSE:退出应用程序(撤销窗口对象并退出程序);
Container getContentPane():获得内容窗格
Component add(Component comp):往内容窗格里添加组件
菜单组件
菜单条、菜单、菜单项是窗口常用的组件,菜单放在菜单条里,菜单项放在菜单里
(1)菜单条(JMenuBar)
JComponent类的子类JMenuBar负责创建菜单条,JMenuBar的一个实例就是一个菜单条。(只能向窗口添加一个菜单条)。
(2) 菜单(JMenu)
JComponent类的子类JMenu类负责创建菜单,JMenu类的一个实例就是一个菜单。JMenu类的主要方法有以下几种:
JMenu(String s):建立一个指定标题菜单,标题由参数s确定
public void add(JMenuItem item):向菜单增加由参数item指定的菜单选项对象。
public void add(String s):向菜单增加指定的选项。
public JMenuItem getItem(int n):得到指定索引处的菜单选项。
public int getItemCount():得到菜单选项数目。
菜单项(JMenuItem)
JMenuItem是JMenu的父类,该类负责创建菜单项,JMenuItem类的一个实例就是一个菜单项。
- JMenuItem(String s) 构造有标题的菜单项。
- JMenuItem(String text, Icon icon) 构造有标题和图标的菜单项
- public void setEnabled(boolean b)设置当前菜单项是否可用。
- public String getLabel() 得到菜单项的名字。
public void setAccelerator(KeyStroke keyStroke) 为菜单项设置快捷键
为了向该方法的参数传递一个KeyStroke对象,可以使用KeyStroke类的静态方法KeyStroke getKeyStroke(int keyCode,int modifiers)返回一个KeyStroke对象
keyCode取值范围为KeyEvent.VK_A~KeyEvent.VK_Z
modifiers的取值如下:InputEvent.ALT_MASK,InputEvent.CTRL_MASK和InputEvent.SHIFT_MASK,表示快捷键的执行方式
为了使得菜单项有一个图标,可以用图标类Icon声明一个图标,然后使用其子类ImageIcon类创建一个图标,如: Icon icon = new ImageIcon(“dog.gif “);
对话框
JDialog是Swing的另外一个顶层容器。JDialog对话框分为两种:模态对话框和非模态对话框。
模态对话框是指用户需要处理完(关闭)该对话框后才能继续与其它窗口交互,非模态对话框允许用户在处理该对话框的同时可以与其它窗口交互。
JDialog类创建的对话框都要依赖于某个父窗口
- JDialog(JFrame owner, String title): 构造一个具有标题的初始不可见的非模态对话框,参数title是对话框的标题的名,owner是对话框所依赖的窗口,如果owner取null , 对话框依赖一个默认的不可见的窗口,该窗口由Java运行环境提供。
- JDialog(JFrame owner, String title, boolean modal): 构造一个具有标题title的初始不可见的对话框。参数modal决定对话框为模态或非模态,参数owner是对话框所依赖的窗口,如果owner取null , 对话框依赖一个默认的不可见的窗口,该窗口由Java运行环境提供。
- setModal(boolean b): 设置对话框的模式,b取true时为模态,取false为非模态。
- setVisible(boolean b): 显示或隐藏对话框。
- public void setJMenuBar(JMenuBar menu): 对话框添加菜单条。
对话框分为两大类:功能对话框和自定义对话框。
功能对话框提供特定功能,由其他类创建,也是JDialog类的对象,但是不可直接访问该对象,只能通过输入一些参数来设定对话框。而自定义对话框是自己创建JDialog或其子类的对象,可以直接访问
1. 功能对话框
消息对话框:是模态对话框,用于对操作进行提示。
2 输入对话框:
含有供用户输入文本的文本框、一个确认和取消按钮,是模态对话框。
3 颜色对话框:是模态对话框,用javax.swing包的JColorChooser类的静态方法
4 文件对话框:是模态对话框,提供从文件系统中进行文件选择的界面。
常用组件
1. 组件
- 文本组件:用于接收用户输入的信息或向用户展示信息,包括文本框(JTextField)和文本域(JTextArea), JTextField只能接收单行文本的输入,JTextArea能接收多行文本的输入。JTextField有一个子类JPasswordField,用于创建密码框。
- 按钮组件:常用的按钮组件有JButton、JCheckBox、JRadioButton等, JCheckBox组件被称为复选框,它有选中/未选中两种状态,如果复选框有多个,则用户可以选中其中一个或者多个。JRadioButton组件称为单选按钮,与JCheckBox复选框不同的是,单选按钮只能选中一个,当一个按钮被选中时,先前被选中的按钮就会自动取消选中(使用ButtonGroup实现单选)。
- 标签:使用JComponent的子类JLabel类创建标签,标签用来显示静态信息,不能编辑。
- 下拉列表框:使用JComponent的子类JComboBox类创建下拉列表框。它将所有选项折叠收藏在一起,当用户点击组合框时,会出现下拉式的选择列表,用户可以从中选择其中一项并显示。
组件的常用方法
- public void setBackground(Color c):设置组件的背景色。
- public void setForeground(Color c):设置组件的前景色。
- public Color getBackground():获取组件的背景色。
- public Color getForeground():获取组件的前景色。
布局管理
FlowLayout布局把组件从左到右、从上到下一行接一行的依次放置在容器中。
BorderLayout将整个容器划分为5个区域:North(上部)、South(下部)、East(右侧)、West(左侧)和Center(中部)。
BoxLayout称为盒式布局。将组件排列在一行或一列,就像一个按行或列分隔的盒子。Box类的类(静态)方法createHorizontalBox()可以获得一个具有行型盒式布局的盒式容器;Box类的静态方法createVerticalBox()可以获得一个具有列型盒式布局的盒式容器。
CardLayout布局管理器提供一种基于卡片式的布局管理。它所产生的效果就像一副扑克牌叠在一起,每次只显示最上面的一张牌,需要显示下一张时,只需把最上面的一张牌放到最底下即可。
GridLayout是一种网格式的布局管理器,它将容器空间划分成若干行乘若干列的网格,组件依次放入其中,每个组件占据一格。各组件的排列方式为按行从左到右,从上到下
null布局
null布局(空布局)。使用空布局的容器可以编程设置组件在容器中的位置和大小,setBounds(int a, int b, int width, int height)方法是所有组件都有的一个方法,调用该方法设置组件的大小和位置。
中间容器
(1)JPanel面板
使用JPanel创建一个面板,再向这个面板添加组件,然后把这个面板添加到顶层容器或其他中间容器。JPanel面板的默认布局是FlowLayout布局。JPanel类构造方法JPanel()可以构造一个面板容器对象。
(2) JScrollPane窗格
通过JScrollPane窗格实现组件的滚动功能,方法是将组件作为JScorollPane的构造方法JScorollPane(component c)的参数传入,则可以构造出一个滚动窗口,使该组件具有滚动功能。
(3) JSplitPane窗格
拆分窗格有两种类型:水平拆分和垂直拆分。水平拆分窗口用一条拆分线把容器分成左右两部分,左面放一个组件,右面放一个组件,拆分线可以水平移动。垂直拆分窗格由一条拆分线分成上下两部分,上面放一个组件,下面放一个组件,拆分线可以垂直移动。
事件处理
事件的三要素:事件源、事件类型、事件监听器
事件编程:
步骤1:确定事件源与事件类型;
步骤2:确定监听器接口并实现事件监听器;
步骤3:将事件监听器注册到事件源。
按钮是事件源,而点击按钮产生的事件是ActionEvent事件,ActionEvent事件对应的监听器接口是ActionListener,需要编写事件监听器类来实现这个接口,重写其中的抽象方法actionPerformed
事件源.addXxxListener(事件监听器实例);
监听器接口
常用监听器接口1:ActionListener
ActionListener是使用得最多的监听器,与之对应的事件类型是ActionEvent,
常用监听器接口2:KeyListener
KeyListener专门用来处理键盘事件,其对应事件类型是KeyEvent。
常用监听器接口3:MouseListener
操作鼠标时会产生鼠标事件MouseEvent,而MouseListener用来处理鼠标的动作
常用监听器接口4:MouseMotionListener
MouseMotionListener是专门处理鼠标运动事件MouseMotionEvent的,比如将鼠标进行移动和拖动的时候
常用监听器接口5:ItemListener
对于象下拉列表、单选按钮、复选按钮这些有选项的组件而言,当它们的选项发生改变的时候,都会产生选项事件ItemEvent
常用监听器接口6:WindowListener
操作窗口时会产生窗口事件WindowEvent,其对应监听器是WindowListener
常用监听器接口7:FocusListener
某个组件得到/丢失焦点时将产生焦点事件FocusEvent,可以使用FocusListener来处理这样的事件
同一个事件源可以注册多个事件监听器,同一个事件监听器也可以在多个事件源上注册
Java集合框架
集合类按照存储结构可以分为两大类,即单列集合(Collection)和双列集合(Map)
- Collection:单列集合类的根接口。它有两个重要的子接口List和Set。List接口的主要实现类有ArrayList和LinkedList,Set接口的主要实现类有HashSet和TreeSet。List集合的特点是元素有序、元素可重复。Set集合的特点是元素无序并且不可重复。这里有序是指元素的存储位置有序,不是指元素的大小有序。
Iterator接口
用于迭代的遍历Collection中的元素,也称为迭代器
通过迭代器的next()方法读取集合中的元素时,都是将这些元素当做Object类型来看待,如果想得到该元素的具体类型,需要进行强制类型转换。在调用next()方法读取下一个元素时,要保证下一个元素存在,否则会抛出NoSuchElementException异常
当使用Iterator迭代器时,如果调用集合的remove()方法删除元素,或者调用add()方法添加元素,都会引发异常。原因是增删集合中的元素会导致预期的迭代次数无效,从而执行后抛出异常
双列集合(Map)
Map集合是实现了Map接口的集合类,它的每个元素都包含一个键对象Key和值对象Value
往Map集合中添加元素使用put(Object k, Object v)方法,使用get(Object k)方法查找键k对应的值
泛型
泛型类型在逻辑上看以看成是多个不同的类型,实际上都是相同的基本类型
泛型的本质是将类型参数化。允许在创建类、接口或方法时,将其中所使用的数据类型指定为一个参数。我们把这样的参数叫做类型参数(或泛型参数)。
类型参数T只能是引用类型,一定不能是int、float、double等基本类型,但可以是对应的封装类型Integer、Float、Double等。
在泛型类中,可以使用多个泛型参数。
多线程
继承Thread类创建多线程
Java提供了一个线程类Thread,通过继承Thread类,并重写Thread类的run()方法,在该方法中实现线程的执行代码;
Thread类提供了一个start()方法用于启动新线程。线程启动后,系统会自动调用Thread类的run()方法,如果子类重写了该方法调用的就是子类的run()方法。
实现Runnable接口创建多线程
线程整个生命周期可以分为五个阶段,分别是新建状态(New)、就绪状态(Runnable)、运行状态(Running)、阻塞状态(Blocked)和死亡状态(Terminated),线程的不同状态表明了线程当前正在进行的活动。
线程休眠
使用Thread类的静态方法sleep(long millis)。该方法可以让当前正在执行的线程暂停一段时间,进入休眠状态(阻塞状态)。当线程调用sleep(long millis)方法后,在指定的时间内该线程不会执行,其它线程就可以得到占用CPU的机会。
线程让步
通过Thread类的yield()方法来实现。该方法和sleep()方法有点相似,都可以让当前正在运行的线程暂停。区别在于yield()方法不阻塞该线程,它只是将线程转换成就绪状态,让系统重新调度该线程。
同步代码块
保证处理共享资源的代码在任何时刻只能有一个线程访问
synchronized(lock){
操作共享资源的代码块
}
网络编程
InetAdderss类常用的方法如下所示:
static InetAddress getByName(String host):在给定主机名的情况下确定主机的 IP 地址,返回该IP地址的InetAddress对象。参数host表示指定的主机名,也可以是IP地址的字符串。
static InetAddress getLocalHost():返回一个表示本地主机的InetAddress对象。
static InetAddress getByAddress(byte[] addr):在给定 IP 地址的情况下返回 InetAddress 对象。参数按网络字节顺序:地址的高位字节位于addr[0] 中。
String getHostName():获取当前IP 地址的主机名。如果是本机则是计算机名,不是本机则是主机名(域名),查不到域名则返回IP地址。
String getHostAddress():返回当前IP 地址的字符串。
boolean isReachable(int timeout):测试在指定的时间内地址是否可达。
. TCP和UDP协议
UDP称为用户数据报协议,是一种无连接通信协议,在数据传输时,数据的发送端和接收端不需要事先建立连接。
TCP
Java语法基础
Java的特点:
面向对象,跨平台,解释型,多线程,安全,动态
Java源程序(.java)编译生成字节码文件(.class)
Java 程序结构
源文件(.java)由类组成(一个或多个)
一个源文件至多有一个public类
源文件名与( public )类名相同,如果源文件没有public类,那么源文件的名字只要和某个类的名字相同,并且扩展名是.java就可以了
标识符:
1.标识符由字母、下划线、美元符号和数字组成,且第一个字符不能为数字。
2. 标识符不能是关键字、true、false、null。
注:标识符区分大小写!
Java的数据类型
基本类型:整型、浮点型、布尔型和字符型;
整型:byte(1B),short(2B),int(4B),long(8B用后缀L来表示)
浮点型:float(4B必须要有后缀“f”或“F”),double(8B后面可以有后缀“d”或“D”,但允许省略该后缀)
字符型:char(2B)
布尔型:boolen
输入、输出数据
输入数据
从键盘为基本型变量输入值的主要步骤:import java.util.Scanner;
使用Scanner类创建一个对象 Scanner reader = new Scanner(System.in);
reader对象调用下列方法,读取用户在命令行输入的各种基本类型数据:
nextBoolean(),nextByte(),nextShort(),nextInt(),nextLong(),
nextFloat(),nextDouble()。
例:double x=reader. nextDouble()
输出数据
(1)println()
System.out.println()或System.out.print()可输出串值、表达式的值,二者的区别是前者输出数据后换行,后者不换行。
(2)printf()
printf输出数据的格式如下:
System.out.printf("格式控制部分",表达式1,表达式2,…表达式n)
格式控制部分由格式控制符号:%b、%d、%c、%f、%s
数组
使用数组四步走:
- 声明数组 int [] a;
Java不允许在声明数组中的方括号内指定数组元素的个数。
2、分配空间 a=new int[5;]
3、赋值 a[0]=8;
4、处理数据 a[0]=a[0]*10;
赋值
a.静态初始化: 指定每个数组元素的初始值,系统决定数组长度。
int[ ] a = {89, 79, 76}; 或
int[ ] a = new int[ ]{89, 79, 76}; 边声明边赋值
b.动态初始化: 指定数组长度,系统默认赋初值
int[ ] a = new int[3];
a[0] = 89; a[1] = 79; a[2] = 76;
动态地从键盘录入信息并赋值
Scanner input = new Scanner(System.in);
for(int i = 0; i < 30; i ++){
score[i] = input.nextInt();
}
Java数组的for循环遍历数组元素
for(声明循环变量:数组的名字) { }
例: for(int i:a)
System.out.println(i);
//循环变量i依次取数组a中的每一个元素的值
二维数组
int[ ][ ] a = new int[3][4];
类 类的目的是抽象出一类事物共有的属性和行为。
编程风格:1)类名的首字母大写,如果类名是由几个单词复合而成的,每个单词的首字母都应大写;
2)一行只声明一个变量;
3)变量的名字首单词的首字母使用小写,如果变量的名字由多个单词组成,从第二个单词开始的其它单词的首字母使用大写;
类由两部分组成:1.变量的声明(用来存储属性的值)2方法的定义(对类中声明的变量进行操作,即给出算法)
区分成员变量和局部变量:
成员变量在整个类内都有效,其有效性与它在类体中书写的先后位置无关
局部变量只在方法内有效,而且与声明的位置有关,从它声明的位置之后开始有效
如果局部变量的名字和成员变量的名字相同,则成员变量被隐藏,如果想在该方法中使用被隐藏的成员变量,必须使用关键字this
成员变量有默认值,但局部变量没有默认值,因此在使用局部变量之前,必须保证局部变量有具体的值
构造方法:
构造方法是类中的一种特殊的方法,当程序用类创建对象时需使用它的构造方法
类中的构造方法的名字必须使用与它所在的类的名字完全相同,而且没有类型(也不能是void),允许一个类中编写若干个构造方法,但必须保证他们的参数不同
注:如果类中没有编写构造方法,系统会默认该类只有一个构造方法,该默认的构造方法是无参数的,且方法体中没有语句;如果类里定义了一个或多个构造方法,那么java不提供默认的构造方法
创建对象
包括对象的声明和为对象分配变量
声明:类的名字 对象的名字
分配变量:使用new运算符
使用对象:对象.变量 对象.方法 实现对自己的变量的访问和方法的调用
对象的创建过程:
- New 首先在堆上为对象分配内存空间;
- 存储空间清零;(基本类型赋0,引用类型设置为null)
- 执行出现于字段定义处的初始化动作;
- 执行构造函数;
- New返回该块内存的首地址,赋给对象名。
Java中,方法的所有参数都是“传值”的。
基本类型:传递值的拷贝
引用类型:传递引用 (引用类型包括:数组、对象、接口等)
类是体现封装的一种数据类型,类声明的变量称为对象,对象中负责存放引用
一个Java应用程序(也称为一个工程)是由若干个类所构成,这些类可以在一个源文件中,也可以分布在若干个源文件中 。
关联关系(组合)
如果A类的变量成员是B类的对象(A类的对象组合了B类的对象)称:A关联于B
依赖关系:
A类中某个方法的参数是B类的对象或A类中某个方法的返回值类型是B类的对象,则称A依赖于B
实例变量和类变量:
成员变量可以细分为实例变量和类变量
在声明成员变量时,用关键字static修饰的称作类变量(类变量也称为static变量——静态变量),否则称作实例变量。不同对象的实例变量互不相同,而所有对象共享类变量
用关键字static修饰的方法称为类方法
通过类名直接访问类变量
类变量/方法既可以通过类名调用(即不创建任何对象也可以调用),也可以通过对象名调用。实例变量/方法只能通过对象名调用。
注:static方法不能访问非static的变量或方法,实例方法不仅可以操作实例变量,也可以操作类变量
方法的重载
一个类中可以有多个方法具有相同的名字,但这些方法的参数必须不同(参数个数不同或某个参数类型不同)
注:方法的返回值类型和参数的名字不参与比较,也就是说如果两个方法的名字相同,即使返回类型不同,也必须保证参数不同
this关键字
this代表“当前对象”的引用
this不能出现在类方法中,因为这时可能还没有任何对象产生
this多用在区分变量成员(成员变量和局部变量)与形参
包
包的本质就是文件夹(目录)。
包的意义:文件(字节码)管理。
如果源程序中没有声明类所在的包,则类在默认包(default)中
Import使用:一个类需要使用的类和它不在一个包中
Import位置: package语句和类的定义之间
特别:如果要引入一个包中的全部类,则可以用通配符号星号(*)来代替,如:import java.util.*;
访问权限修饰符:
类成员(属性和方法)的权限
private(私有)、default(友好/包权限)、protected(保护)和public(公共)
访问权限排序:(高à低)public > protected > default(默认的/友好的/包权限) > private
类的访问权限public、default(包),不能用protected,private修饰
1.public
用public修饰的成员变量和方法被称为共有变量和共有方法。
无论是谁,无论在哪里,都可以访问该成员。在任何地方都可以访问
2. default默认(包权限,友好权限)
不用private、public、protected修饰符的成员变量和方法被称为友好变量和友好方法。
处于相同的目录且没有设定任何包名称,Java将这样的文件看作隶属于该目录的默认包(default package)中。
包权限:同一包内的类或对象可以访问类的成员,包外的不可以。在类的内部,同一个包中访问
3.protected
用protected修饰的成员变量和方法被称为受保护的成员变量和受保护的方法。
应用场景:基类(父类)将某个成员的访问权限赋予派生类,而不是所有类。
protected也提供包访问权限。即相同包内的其他类可访问protected成员。在类的内部,同一个包中,子类中访问
4. private权限
用关键字private修饰的成员变量和方法称为私有变量和私有方法。
除了包含该成员的类之外,其他任何类都无法访问这个成员。只能在该类的内部访问
继承
Java是单继承,即有且仅有一个父类。
树形结构的根节点为Object类
没使用extends默认是Object的子类
注:有些父类成员不能被继承,private成员、子类与父类不在同包,使用默认访问权限的成员、构造方法
protected可以修饰属性和方法本类、同包、子类(同包、不同包)可以访问
继承是代码重用的一种方式
符合is-a关系的设计使用继承
将子类都有的属性和行为放到父类中
变量隐藏
子类中有和父类有重名的变量,名字相同,声明的类型可以不同,子类将隐藏父类变量,
变量隐藏的特点:
子类对象及子类自定义的方法操作的是子类新声明的变量
继承的方法操作的是父类的变量(被隐藏的变量)
方法重写:
重写的目的是通过方法的重写隐藏继承的方法,可以把父类的状态和行为改变为自身的状态和行为
子类中有和父类相同名字的方法,子类将重写父类方法
方法重写必须满足如下要求:
重写方法和被重写方法必须具有相同的方法名;
重写方法和被重写方法必须具有相同的参数列表;
重写方法的返回值类型必须和被重写方法的返回值类型相同或者是其子类;
重写方法的不能缩小被重写方法的访问权限。
方法重写的规则
在继承关系的子类中
重写的方法名、参数、返回值类型必须与父类相同
私有方法不能继承因而也无法重写
方法的重写和方法的重载
位置 | 方法名 | 参数表 | 返回值 | 访问修饰符 | |
方法重写 | 子类 | 相同 | 相同 | 相同 | 不能比父类更严格 |
方法重载 | 同类 | 相同 | 不同 | 无关 | 无关 |
子类访问被隐藏的父类成员
在子类中可以通过super关键字来访问父类的成员。
super必须是出现在子类中(子类的方法和构造方法中),而不是其他位置。
是访问父类的成员,例如父类的属性、方法、构造方法。
注意访问权限的限制,例如无法通过super访问private成员。
注:加super可以访问父类,构造方法不能被继承因此不能被重写继承中的构造方法
构造方法不能被继承因此不能重写
子类如何访问被隐藏的父类成员
super();默认的
super(参数表);必须是子类构造方法中的头一条语句
当用子类的构造方法创建一个子类的对象时,子类的构造方法总是先调用父类的某个构造方法,也就是说,如果子类的构造方法没有明显的指明使用父类的哪个构造方法,子类就调用父类的不带参数的构造方法;由于子类不继承父类的构造方法,因此,子类在其构造中需使用super关键字来调用父类的构造方法,而且super必须是子类构造方法中的头一条语句。
继承条件下构造方法的调用规则如下:
如果子类的构造方法中没有通过super显式调用父类的有参构造方法,也没有通过this显式调用自身的其他构造方法,则系统会默认先调用父类的无参构造方法。在这种情况下,写不写“super();”语句,效果是一样的。
如果子类的构造方法中通过super显式调用父类的有参构造方法,那将执行父类相应构造方法,而不执行父类无参构造方法。
如果子类的构造方法中通过this显式调用自身的其他构造方法,在相应构造方法中应用以上两条规则。
特别注意的是,如果存在多级继承关系,在创建一个子类对象时,以上规则会多次向更高一级父类应用,一直到执行顶级父类Object类的无参构造方法为止。
继承后的初始化顺序
先调用父类的构造方法,再执行子类的构造方法。当创建了一个子类的对象时,该对象包含了一个父类的对象。
final用法
final类:不能被继承。
final方法:不允许子类重写。
final 变量:变量变常量。在运行期间不允许被修改
(常量分为编译时常量-基本类型和运行时常量-如对象引用。对象引用一旦指定就不可以再指向其他的对象,但不影响对象本身的改变。
由于常量在运行时不再发生变化,于是常量在声明时没有默认值,这就要求程序在声明常量时必须指定该常量的值)
多态
Java中使用抽象类,限制实例化,不允许实例化,即不能使用new关键字
abstract也可用于方法——抽象方法
抽象方法没有方法体(只允许声明,不允许实现,而且不允许使用final和abstract同时修饰一个方法或类,也不允许使用static修饰abstract方法,即abstract方法必须是实例方法,不允许使用private修饰abstract方法,因为abstract方法必须被子类重写)
抽象方法必须在抽象类里
抽象方法必须在子类中被实现,除非子类是抽象类,Abstract类中可以没有Abstract方法。
Abstract类的对象作为上转型对象
将父类的对象变量指向一个子类对象。——自动完成
Pet p = new Dog(); 目的是实现多态。
注:向上转型时,调用被子类重写的方法时,调用的是子类的方法,从而实现了多态。
向下转型:将子类的对象变量指向一个父类对象。——强制类型转换
Dog d = (Dog) p;
对象 instanceof 类或接口
该运算符用来判断一个对象是否属于一个类或者实现了一个接口,结果为true或false
接口
接口是一种极度抽象的类型,它比抽象类更加“抽象”
为什么使用接口
飞机和鸟是不同类的事物,但是它们都有一个共性,就是都会飞。
接口的定义
使用关键字interface来定义一个接口。接口的定义和类的定义很相似,分为接口的声明和接口体,
接口使用关键字interface来声明自己是一个接口
格式: interface 接口的名字
接口体中包含常量的声明和抽象方法两部分。
接口体中所有的常量的访问权限一定都是public,而且是static常量。
所有的抽象方法的访问权限一定都是public
接口由类来实现,即由类来重写接口中的方法。一个类可以在类声明中使用关键字implements声明实现一个或多个接口。如果类实现多个接口,用逗号隔开接口名。
如果一个非抽象类实现了某个接口,那么这个类必须重写这个接口中的所有方法。
抽象类既可以重写接口中的方法,也可以直接拥有接口中的方法。
由于接口中的方法一定是public abstract方法,所以类在重写接口方法时不仅要去掉abstract修饰符、给出方法体,而且方法的访问权限一定要明显地用public来修饰
- 接口就是一些方法特征的集合。
- 接口的定义:用interface关键字
- 接口的属性只能为公共、静态常量,即需要用用关键字public、static、final修饰。但是这三个关键字可以省略。
- 接口的方法只能是公共的抽象方法,即用关键字public 和abstract修饰,但是这两个关键字可以省略。
- 接口和抽象类的用法类似!
- 接口和抽象类的区别:从语法上看一个类可以实现多个接口,但是一个类只能有一个父类。
- 接口的实现:通过类使用implements关键字类实现。
- 接口回调:可以把实现某一接口类创建的对象的引用赋值给该接口声明的接口变量,那么该接口变量就可以调用被类实现的接口的方法。
- 接口的思想在于它可以要求某些类有相同名称的方法,但方法的具体内容可以不同,即要求这些类实现接口,以保证这些类一定有接口中所声明的方法(即所谓的方法绑定)。
抽象类作为很多子类的父类,它是一种模板式设计。而接口是一种行为规范,它是一种辐射式设计
接口回调就是指:可以把实现某一接口的类创建的对象的引用赋给该接口声明的接口变量中,那么该接口变量就可以调用被类实现的接口方法。实际上,当接口变量调用被类实现的接口方法时,就是通知相应的对象调用这个方法。
接口与多态
把实现接口的类的实例的引用赋值给接口变量后,该接口变量就可以回调类重写的接口方法。
由接口产生的多态就是指不同的类在实现同一个接口时可能具有不同的实现方式,那么接口变量在回调接口方法时就可能具有多种形态。
异常
异常就是在程序的运行过程中所发生的不正常的事件,它会中断正在运行的程序
异常处理是通过5个关键字来实现的:try(执行可能产生异常的代码)、catch(抛出异常)、 finally(无论是否发生异常,代码总能执行)、throw(抛出异常)、throws(声明异常)
printStackTrace的堆栈跟踪功能显示出程序运行到当前类的执行流程
在try-catch块后加入finally块,可以确保无论是否发生异常,finally块中的代码总能被执行
finally块中语句不执行的唯一情况
异常处理代码中执行System.exit(1)退出Java虚拟机
常见的异常类型
Exception | 异常层次结构的根类 |
ArithmeticException | 算术错误情形,如以零作除数 |
ArrayIndexOutOfBoundsException | 数组下标越界 |
NullPointerException | 尝试访问 null 对象成员 |
ClassNotFoundException | 不能加载所需的类 |
InputMismatchException | 欲得到数据类型与实际输入类型不匹配 |
IllegalArgumentException | 方法接收到非法参数 |
ClassCastException | 对象强制类型转换出错 |
NumberFormatException | 数字格式转换异常,如把"abc"转换成数字 |
throws出现在方法函数头;而throw出现在函数体
throw new Exception();抛出异常
throw不能单独使用,必须和catch一起使用,或者在方法头上加上throws Exception
图形用户界面
java.awt包中的类创建的组件称为重组件,重组件用来实现和本地操作系统的交互。
AWT组件相比,Swing组件的名字前多一个“J”字母。AWT组件在java.awt包中,Swing组件在javax.swing包中。
java.awt包中Component类的直接子类或间接子类创建的对象称为组件,Container的直接子类或间接子类创建的对象称为容器。容器用来放置组件,组件放置在容器中。由于Container类是Component类的子类,所以容器也是组件,可以添加到其他容器中实现容器的嵌套。
Swing容器主要有两类:
- 顶层容器:包含其它容器的容器。每个图形界面程序都有一个顶层容器,主要有JApplet、JFrame和JDialog。这三个容器都是重组件。
- 中间层容器:用来添加其它组件的容器,不能做顶层容器,可以添加到顶层容器或其它容器中。主要有JPanel(面板)、JScrollPane(滚动窗格) 、JSplitPane(拆分窗格)、JLayeredPane(分层窗格)等。
.容器和组件的使用
- 可以向容器中添加组件。Container类提供了一个方法add(),被所有的容器类所继承,一个容器可以调用这个方法将组件添加到自身中。
- 调用removeAll()方法可以移除容器中的全部组件,调用remove(Component c)方法可以移除容器中的指定组件。
- 往容器中添加组件或移除组件后,接下来应当调用容器的validate()方法,以保证容器中的组件能正确显示出来。
- javax.swing中有4个最重要的类JApplet,JFrame,JDialog和JComponent。JFrame、JApplet、JDialog是重组件,因而窗体(JFrame)、对话框(JDialog)、小应用程序(JApplet)可以和本地操作系统直接交互。而JComponent的子类都是轻组件,
当应用程序需要一个窗口时,可使用JFrame或其子类创建一个对象,不允许将一个窗口添加到另一个容器中。包括JFrame在内,每个顶层容器包含一个狭窄的矩形区域,称为菜单条区域,另一个是菜单条下面的区域,称为内容窗格(Content pane)。
JFrame类常用方法:
JFrame():创建一个无标题的窗口;JFrame(String s):创建一个标题为s的窗口。
void setBounds(int a, int b, int width, int height):同时设置窗口的位置和大小:
void setLocation(int x, int y):将组件移到指定位置
void setSize(int width, int height):设置窗口的大小
void setVisible(boolean b):设置窗口是可见还是不可见,窗口默认是不可见的。设置窗口可见性,必须
void setResizable(boolean b):设置窗口是否可调整大小,窗口默认是可调整大小的。
void setDefaultCloseOperation(int operation):该方法用来设置单击窗体右上角的关闭图标后,程序会做出怎样的处理,如果不调用该方法,则点击关闭按钮后,窗口关闭操作无响应。设置窗口关闭方式,必须四种关闭方式。
JFrame.DO_NOTHING_ON_CLOSE:无操作(什么也不做);
JFrame.HIDE_ON_CLOSE:隐藏窗口(窗口对象还在,只是看不见);
JFrame.DISPOSE_ON_CLOSE:移除窗口(窗口对象撤销,不退出程序);
JFrame.EXIT_ON_CLOSE:退出应用程序(撤销窗口对象并退出程序);
Container getContentPane():获得内容窗格
Component add(Component comp):往内容窗格里添加组件
菜单组件
菜单条、菜单、菜单项是窗口常用的组件,菜单放在菜单条里,菜单项放在菜单里
(1)菜单条(JMenuBar)
JComponent类的子类JMenuBar负责创建菜单条,JMenuBar的一个实例就是一个菜单条。(只能向窗口添加一个菜单条)。
(2) 菜单(JMenu)
JComponent类的子类JMenu类负责创建菜单,JMenu类的一个实例就是一个菜单。JMenu类的主要方法有以下几种:
JMenu(String s):建立一个指定标题菜单,标题由参数s确定
public void add(JMenuItem item):向菜单增加由参数item指定的菜单选项对象。
public void add(String s):向菜单增加指定的选项。
public JMenuItem getItem(int n):得到指定索引处的菜单选项。
public int getItemCount():得到菜单选项数目。
菜单项(JMenuItem)
JMenuItem是JMenu的父类,该类负责创建菜单项,JMenuItem类的一个实例就是一个菜单项。
- JMenuItem(String s) 构造有标题的菜单项。
- JMenuItem(String text, Icon icon) 构造有标题和图标的菜单项
- public void setEnabled(boolean b)设置当前菜单项是否可用。
- public String getLabel() 得到菜单项的名字。
public void setAccelerator(KeyStroke keyStroke) 为菜单项设置快捷键
为了向该方法的参数传递一个KeyStroke对象,可以使用KeyStroke类的静态方法KeyStroke getKeyStroke(int keyCode,int modifiers)返回一个KeyStroke对象
keyCode取值范围为KeyEvent.VK_A~KeyEvent.VK_Z
modifiers的取值如下:InputEvent.ALT_MASK,InputEvent.CTRL_MASK和InputEvent.SHIFT_MASK,表示快捷键的执行方式
为了使得菜单项有一个图标,可以用图标类Icon声明一个图标,然后使用其子类ImageIcon类创建一个图标,如: Icon icon = new ImageIcon(“dog.gif “);
对话框
JDialog是Swing的另外一个顶层容器。JDialog对话框分为两种:模态对话框和非模态对话框。
模态对话框是指用户需要处理完(关闭)该对话框后才能继续与其它窗口交互,非模态对话框允许用户在处理该对话框的同时可以与其它窗口交互。
JDialog类创建的对话框都要依赖于某个父窗口
- JDialog(JFrame owner, String title): 构造一个具有标题的初始不可见的非模态对话框,参数title是对话框的标题的名,owner是对话框所依赖的窗口,如果owner取null , 对话框依赖一个默认的不可见的窗口,该窗口由Java运行环境提供。
- JDialog(JFrame owner, String title, boolean modal): 构造一个具有标题title的初始不可见的对话框。参数modal决定对话框为模态或非模态,参数owner是对话框所依赖的窗口,如果owner取null , 对话框依赖一个默认的不可见的窗口,该窗口由Java运行环境提供。
- setModal(boolean b): 设置对话框的模式,b取true时为模态,取false为非模态。
- setVisible(boolean b): 显示或隐藏对话框。
- public void setJMenuBar(JMenuBar menu): 对话框添加菜单条。
对话框分为两大类:功能对话框和自定义对话框。
功能对话框提供特定功能,由其他类创建,也是JDialog类的对象,但是不可直接访问该对象,只能通过输入一些参数来设定对话框。而自定义对话框是自己创建JDialog或其子类的对象,可以直接访问
1. 功能对话框
消息对话框:是模态对话框,用于对操作进行提示。
2 输入对话框:
含有供用户输入文本的文本框、一个确认和取消按钮,是模态对话框。
3 颜色对话框:是模态对话框,用javax.swing包的JColorChooser类的静态方法
4 文件对话框:是模态对话框,提供从文件系统中进行文件选择的界面。
常用组件
1. 组件
- 文本组件:用于接收用户输入的信息或向用户展示信息,包括文本框(JTextField)和文本域(JTextArea), JTextField只能接收单行文本的输入,JTextArea能接收多行文本的输入。JTextField有一个子类JPasswordField,用于创建密码框。
- 按钮组件:常用的按钮组件有JButton、JCheckBox、JRadioButton等, JCheckBox组件被称为复选框,它有选中/未选中两种状态,如果复选框有多个,则用户可以选中其中一个或者多个。JRadioButton组件称为单选按钮,与JCheckBox复选框不同的是,单选按钮只能选中一个,当一个按钮被选中时,先前被选中的按钮就会自动取消选中(使用ButtonGroup实现单选)。
- 标签:使用JComponent的子类JLabel类创建标签,标签用来显示静态信息,不能编辑。
- 下拉列表框:使用JComponent的子类JComboBox类创建下拉列表框。它将所有选项折叠收藏在一起,当用户点击组合框时,会出现下拉式的选择列表,用户可以从中选择其中一项并显示。
组件的常用方法
- public void setBackground(Color c):设置组件的背景色。
- public void setForeground(Color c):设置组件的前景色。
- public Color getBackground():获取组件的背景色。
- public Color getForeground():获取组件的前景色。
布局管理
FlowLayout布局把组件从左到右、从上到下一行接一行的依次放置在容器中。
BorderLayout将整个容器划分为5个区域:North(上部)、South(下部)、East(右侧)、West(左侧)和Center(中部)。
BoxLayout称为盒式布局。将组件排列在一行或一列,就像一个按行或列分隔的盒子。Box类的类(静态)方法createHorizontalBox()可以获得一个具有行型盒式布局的盒式容器;Box类的静态方法createVerticalBox()可以获得一个具有列型盒式布局的盒式容器。
CardLayout布局管理器提供一种基于卡片式的布局管理。它所产生的效果就像一副扑克牌叠在一起,每次只显示最上面的一张牌,需要显示下一张时,只需把最上面的一张牌放到最底下即可。
GridLayout是一种网格式的布局管理器,它将容器空间划分成若干行乘若干列的网格,组件依次放入其中,每个组件占据一格。各组件的排列方式为按行从左到右,从上到下
null布局
null布局(空布局)。使用空布局的容器可以编程设置组件在容器中的位置和大小,setBounds(int a, int b, int width, int height)方法是所有组件都有的一个方法,调用该方法设置组件的大小和位置。
中间容器
(1)JPanel面板
使用JPanel创建一个面板,再向这个面板添加组件,然后把这个面板添加到顶层容器或其他中间容器。JPanel面板的默认布局是FlowLayout布局。JPanel类构造方法JPanel()可以构造一个面板容器对象。
(2) JScrollPane窗格
通过JScrollPane窗格实现组件的滚动功能,方法是将组件作为JScorollPane的构造方法JScorollPane(component c)的参数传入,则可以构造出一个滚动窗口,使该组件具有滚动功能。
(3) JSplitPane窗格
拆分窗格有两种类型:水平拆分和垂直拆分。水平拆分窗口用一条拆分线把容器分成左右两部分,左面放一个组件,右面放一个组件,拆分线可以水平移动。垂直拆分窗格由一条拆分线分成上下两部分,上面放一个组件,下面放一个组件,拆分线可以垂直移动。
事件处理
事件的三要素:事件源、事件类型、事件监听器
事件编程:
步骤1:确定事件源与事件类型;
步骤2:确定监听器接口并实现事件监听器;
步骤3:将事件监听器注册到事件源。
按钮是事件源,而点击按钮产生的事件是ActionEvent事件,ActionEvent事件对应的监听器接口是ActionListener,需要编写事件监听器类来实现这个接口,重写其中的抽象方法actionPerformed
事件源.addXxxListener(事件监听器实例);
监听器接口
常用监听器接口1:ActionListener
ActionListener是使用得最多的监听器,与之对应的事件类型是ActionEvent,
常用监听器接口2:KeyListener
KeyListener专门用来处理键盘事件,其对应事件类型是KeyEvent。
常用监听器接口3:MouseListener
操作鼠标时会产生鼠标事件MouseEvent,而MouseListener用来处理鼠标的动作
常用监听器接口4:MouseMotionListener
MouseMotionListener是专门处理鼠标运动事件MouseMotionEvent的,比如将鼠标进行移动和拖动的时候
常用监听器接口5:ItemListener
对于象下拉列表、单选按钮、复选按钮这些有选项的组件而言,当它们的选项发生改变的时候,都会产生选项事件ItemEvent
常用监听器接口6:WindowListener
操作窗口时会产生窗口事件WindowEvent,其对应监听器是WindowListener
常用监听器接口7:FocusListener
某个组件得到/丢失焦点时将产生焦点事件FocusEvent,可以使用FocusListener来处理这样的事件
同一个事件源可以注册多个事件监听器,同一个事件监听器也可以在多个事件源上注册
Java集合框架
集合类按照存储结构可以分为两大类,即单列集合(Collection)和双列集合(Map)
- Collection:单列集合类的根接口。它有两个重要的子接口List和Set。List接口的主要实现类有ArrayList和LinkedList,Set接口的主要实现类有HashSet和TreeSet。List集合的特点是元素有序、元素可重复。Set集合的特点是元素无序并且不可重复。这里有序是指元素的存储位置有序,不是指元素的大小有序。
Iterator接口
用于迭代的遍历Collection中的元素,也称为迭代器
通过迭代器的next()方法读取集合中的元素时,都是将这些元素当做Object类型来看待,如果想得到该元素的具体类型,需要进行强制类型转换。在调用next()方法读取下一个元素时,要保证下一个元素存在,否则会抛出NoSuchElementException异常
当使用Iterator迭代器时,如果调用集合的remove()方法删除元素,或者调用add()方法添加元素,都会引发异常。原因是增删集合中的元素会导致预期的迭代次数无效,从而执行后抛出异常
双列集合(Map)
Map集合是实现了Map接口的集合类,它的每个元素都包含一个键对象Key和值对象Value
往Map集合中添加元素使用put(Object k, Object v)方法,使用get(Object k)方法查找键k对应的值
泛型
泛型类型在逻辑上看以看成是多个不同的类型,实际上都是相同的基本类型
泛型的本质是将类型参数化。允许在创建类、接口或方法时,将其中所使用的数据类型指定为一个参数。我们把这样的参数叫做类型参数(或泛型参数)。
类型参数T只能是引用类型,一定不能是int、float、double等基本类型,但可以是对应的封装类型Integer、Float、Double等。
在泛型类中,可以使用多个泛型参数。
多线程
继承Thread类创建多线程
Java提供了一个线程类Thread,通过继承Thread类,并重写Thread类的run()方法,在该方法中实现线程的执行代码;
Thread类提供了一个start()方法用于启动新线程。线程启动后,系统会自动调用Thread类的run()方法,如果子类重写了该方法调用的就是子类的run()方法。
实现Runnable接口创建多线程
线程整个生命周期可以分为五个阶段,分别是新建状态(New)、就绪状态(Runnable)、运行状态(Running)、阻塞状态(Blocked)和死亡状态(Terminated),线程的不同状态表明了线程当前正在进行的活动。
线程休眠
使用Thread类的静态方法sleep(long millis)。该方法可以让当前正在执行的线程暂停一段时间,进入休眠状态(阻塞状态)。当线程调用sleep(long millis)方法后,在指定的时间内该线程不会执行,其它线程就可以得到占用CPU的机会。
线程让步
通过Thread类的yield()方法来实现。该方法和sleep()方法有点相似,都可以让当前正在运行的线程暂停。区别在于yield()方法不阻塞该线程,它只是将线程转换成就绪状态,让系统重新调度该线程。
同步代码块
保证处理共享资源的代码在任何时刻只能有一个线程访问
synchronized(lock){
操作共享资源的代码块
}
网络编程
InetAdderss类常用的方法如下所示:
static InetAddress getByName(String host):在给定主机名的情况下确定主机的 IP 地址,返回该IP地址的InetAddress对象。参数host表示指定的主机名,也可以是IP地址的字符串。
static InetAddress getLocalHost():返回一个表示本地主机的InetAddress对象。
static InetAddress getByAddress(byte[] addr):在给定 IP 地址的情况下返回 InetAddress 对象。参数按网络字节顺序:地址的高位字节位于addr[0] 中。
String getHostName():获取当前IP 地址的主机名。如果是本机则是计算机名,不是本机则是主机名(域名),查不到域名则返回IP地址。
String getHostAddress():返回当前IP 地址的字符串。
boolean isReachable(int timeout):测试在指定的时间内地址是否可达。
. TCP和UDP协议
UDP称为用户数据报协议,是一种无连接通信协议,在数据传输时,数据的发送端和接收端不需要事先建立连接。
TCP称为传输控制协议,是一种面向连接的通信协议,可以保证两台计算机之间可靠无差错的数据传输。在TCP连接中必须要明确客户端与服务器端,由客户端向服务端发出连接请求,每次连接的创建都需要经过“三次握手”。
- TCP通信是严格区分客户端与服务器端的。在通信时,必须由客户端去连接服务器端才能实现通信,服务器端不可以主动连接客户端。并且服务器端需要先启动,等待客户端的连接。
- 实现TCP程序。一个是ServerSocket类,用于创建服务器端对象,一个是Socket类,用于创建客户端对象。这两个对象也称为套接字(socket)对象。
- ServerSocket(int port):创建绑定到指定端口port的ServerSocket对象。
accept()方法接收来自客户端的请求
Socket(String host, int port):创建一个Socket对象,连接IP地址和端口分别为host和port的服务器端程序。
称为传输控制协议,是一种面向连接的通信协议,可以保证两台计算机之间可靠无差错的数据传输。在TCP连接中必须要明确客户端与服务器端,由客户端向服务端发出连接请求,每次连接的创建都需要经过“三次握手”。
- TCP通信是严格区分客户端与服务器端的。在通信时,必须由客户端去连接服务器端才能实现通信,服务器端不可以主动连接客户端。并且服务器端需要先启动,等待客户端的连接。
- 实现TCP程序。一个是ServerSocket类,用于创建服务器端对象,一个是Socket类,用于创建客户端对象。这两个对象也称为套接字(socket)对象。
- ServerSocket(int port):创建绑定到指定端口port的ServerSocket对象。
accept()方法接收来自客户端的请求
Socket(String host, int port):创建一个Socket对象,连接IP地址和端口分别为host和port的服务器端程序。