Java概述
Java的三个版本:标准版Java SE,企业版Java EE,微型版Java ME。
编译:源程序通过Java编译器生成可执行代码(字节码)。
解释:字节码通过Java虚拟机(JVM)实现:代码的装入,代码的校验,代码的运行。
目前Java代码有两种执行方式:
解释执行方式:每次翻译,执行一小段。
即时编译方式:字节码全部转换成机器码再执行。
面向对象的特性:
封装:将对象内的数据和代码联编起来,形成一个对象。
继承:某一类对象直接使用另一类对象的所有属性和行为。
多态性:一个接口有多个内在实现形式表示。
Java语言的开发工具包:JDK
javac:Java编译器
java:Java解释器
appletviewer:下载并运行HTML文件中的applet程序
Java解释器在解释执行的时候,解释处理的是类名,而不是文件名。
Java语言基础知识
一个Java源程序文件中可包含三个基本组成部分:
一个包声明package语句(可选);
任意数量的引入import语句(可选);
类和接口声明。
类和接口组成Java程序的最基本单元。
在一个Java源程序中,只能有一个类可以被声明为public类;若某个类中有main()方法,则声明该类为public类。
应该用public类作为源程序的文件名,且注意大小写一致。
举例:
package nameOfPackage; //注意分号!
import example.OtherClassName; //引入类OtherClassName
public class ClassName {
int x, y; //声明成员变量x,y
public static void main(String args[]) { //固定格式,声明成员方法main()
System.out.println(“Hello, World!”); //类System,成员变量out,方法println
}
}
在C/C++中一般采用ASCII码,而Java则采用Unicode码(统一码字符集)。
无sizeof运算符,所有类型的长度和表示是固定的,不能在程序运行时改变它。
true、false和null为小写;不使用goto和const。
数据类型:
简单类型:整型(byte,short,int,long),浮点型(float,double),字符型(char),布尔型(boolean);
引用类型:数组(type[]),类(class),接口(interface)。
Java语言数据中的数值类型都是有符号的。
整型默认int,浮点型默认double。
整型和boolean型之间不能互相转换,boolean型只允许使用boolean值。
当变量所标识的是简单数据类型,则直接访问其值;当变量所标识的是引用类型,则变量所代表的是堆空间的地址。
Java虚拟机自动初始化成员变量(boolean型赋值false,所有引用类型赋值null),局部变量需要显示地初始化。
在Java语言中,任何类型的数据都可以用“==”或“!=”判等。
位运算符:>>(无符号右移),>>>(有符号右移,符号位不变),<<(无符号左移)
流程控制、数组
在Java语言中,流控制语句分为:分支语句,循环语句,异常处理语句,跳转语句。
多选择语句switch用于判断跳转的表达式类型只能是:byte,short,char,int。
举例:
class PrimeNumber { //求100~200之间的所有素数
public static void main(String args[]) {
System.out.println(“Prime numbers between 100 and 200”);
outLoop: for(int i=101; i<200; i+=2) { //注意标识符后面的冒号
int k=(int) Math.sqrt(i); //求n的开方,注意强制类型转换
for(int j=3; j<=k; j+=2) { //从2~sqrt(n)作为除数,看是否能整除
if(i%j==0)
continue outLoop; //如果能整除则不是素数,判断下一个数i
}
System.out.println(“ ”+i);
}
}
}
在Java中没有多维数组,只有数组的数组。
数组是一个对象,数组声明创建的是引用,而不是对象本身,需要用new语句实例化。
数组声明不能确定数组大小,用new运算符确定元素数量。
举例:
int score[][]; //数组声明方式1
int[][] score; //数组声明方式2
score=new int[3][4]; //数组实例化方式1
score[3][4]=new int; //数组实例化方式2
score=new int[3]; //数组实例化方式3
score[0]=new int[4];
score[1]=new int[5];
score[2]=new int[2]; //数组实例化方式3,非矩阵
char[][] ch=new char[3][5]; //数组声明和实例化合体
String[] colors={“Red”, ”Green”, “Blue”}; //匿名数组初始化
类和对象
类包括:类声明,类成员(成员变量,成员方法),类的构造器(构造方法)
class前面可使用的修饰符:public,abstract,final
类成员访问控制权限的修饰符有public,protected,private等;使用限制的修饰符有final,abstract,static,transient,volatile等
方法过载(方法重载)是指在一个类中有多个方法同名,但是它们的参数必须不同,返回类型无关。
构造方法同其它方法一样具有参数和语句体,但是没有返回类型的声明(返回该类的实例的引用),如果有返回类型声明,则此方法将成为一般的成员方法。
构造方法不是类的成员方法,所以不能用对象调用它,由new运算符实现调用。
构造方法之间的相互调用,可以通过this()形式调用。this必须在构造器的第一个语句。
构造方法中的语句实现对成员变量的初始化。
默认构造方法是指不带参数的构造方法;非默认构造方法是指带参数的构造方法。
类成员是指由static修饰的成员,属于类而不属于对象,在编译时就确定了存储空间。
类变量为该类的对象所共有,可以利用类变量实现多个对象的数据共享;
类方法能够直接访问类中的类成员,但是不能直接访问非类成员,即不能直接(需要先创建类的实例)访问类的实例成员。
超类、子类和继承性
在Java语言中,类只支持单一继承,接口可以实现多重继承。
单一继承性:子类只能有一个超类,而超类可以有多个子类。
子类不能继承超类的构造器,只能在构造器中通过super()调用超类的构造器;子类的构造器首先要调用超类的构造器。
多态性之一:子类的成员隐藏和覆盖(同名,同参数,同返回类型)超类中相同的成员。
多态性之二:超类的对象可以对子类的实例引用。
super用来引用当前对象的超类。它的使用有三种情况:
访问被隐藏的超类成员变量,例如super.varName
调用超类中被覆盖的方法,例如super.methodName([paramList])
调用超类中的构造方法,例如super([paramList])
在实现子类的构造方法时,先调用超类的构造方法;在实现子类的finalize()时,最后调用超类的finalize()。
即初始化过程由高级向低级,资源回收过程由低级向高级。
超类的对象可以引用子类的实例。
对于覆盖或继承的方法,Java运行时系统根据调用该方法的实例的类型来决定选择哪个方法调用。
final类不能被继承(如Java中的String类);final方法不能被覆盖。
abstract类必须被继承,不能被实例化对象(如Java中的Number类);abstract方法必须被覆盖,只有声明,没有方法体。
abstract类中不一定要包含abstract方法;但如果一个类包含了abstract方法,则该类必须是abstract类。
如果子类实现了全部的abstract方法,则该类可以被声明为非abstract类。
Object类是所有类的超类,所以类都继承它的成员方法。
clone()方法:生成类的实例的拷贝,返回值为该拷贝的实例。
equals()方法:比较两个对象类是否相同,而“==“比较的是引用。例如one.equals(another)
toString()方法:以字符串形式返回当前对象的有关信息。
包、访问控制和接口
接口可以看作一种抽象类,它具有和类相似的形成和使用;包可以看作类库。
接口和包体现了Java语言的对象重用。
Java语言提供了一些常用的基本类包,如java.io和java.lang(包括System类和String类,自动引入)。
package语句,例如package users.java.sample
包层次的根目录是由环境变量classpath确定的。
编译时带-d选项,运行时指明包含这个类的包,还要在适当的目录下运行,设置好环境变量classpath(Java解释器在当前目录和环境变量指明Java类库中查找)。
在类中只实现一个私有的构造方法,则该类不能创建对象也不能被继承。
接口是抽象方法(由public、static和abstract修饰)和常量(由public、final和static修饰)的集合;抽象类中可以包含非抽象方法和一般的的成员变量。
实现接口的类必须实现接口中的所有方法(与接口方法声明一致,且必须有public修饰符)
,而抽象类的子类只必须实现抽象类中的所有抽象方法;接口中的变量(即常量)可以用接口名直接访问,而抽象类的变量则不完全可以用类名直接访问。
接口可以用extends关键字实现多重继承(子接口可以有多个超接口);接口实现的类由关键字implements声明(一个类可以实现多个接口)。
Java支持在一个类中声明另一个类,这样的类称作内部类。
四种类型的内部类:常规内部类(内部成员类),局部内部类,匿名内部类,静态内部类
接口实现中,接口变量引用子类对象的机制称为回调。
举例:
//有两个类Person和Student,Student类是Person类的子类。
//在Person中,有成员变量name/sex/age;
//有构造方法Person(String, char, int);
//有成员方法setData(String, char, int)和getData()。
//在Student中,有成员变量sID/classNo;
//有成员方法setData(5个参数)和getData()。
class Person {
String name;
char sex;
int age;
Person(String name, char sex, int age) { //构造方法Person(String, char, int)
this.name=name;
this.sex=sex;
this.age=age;
}
void setData(String name, char sex, int age) { //成员方法setData(String, char, int)
this.name=name;
this.sex=sex;
this.age=age;
}
String getData() { //成员方法getData()
return “Name: ”+name+”Sex: ”+sex+”Age: ”+age;
}
}
class Student extends Person {
int sID, classNo;
Student(String name, char sex, int age, int sID,int calssNo) { //没有构造方法会报错
super(name, sex, age); //放在第一行
this.sID=sID;
this.classNo=classNo;
}
void setData(String name, char sex, int age, int sID, int classNo) {
this.setData(name, sex, age);
this.sID=sID;
this.classNo=classNo;
}
String getData() {
return “Name: ”+name+”Sex: ”+sex+”Age: ”+age+”SID: ”+sID+”ClassNo: ”+classNo;
}
}
//抽象类Person如下定义:
abstract class Person {
String name;
char sex;
int age;
abstract void setData(String name, char sex, int age);
abstract String getDetail();
}
//类Student和类Teacher均是抽象类Person的子类。
//在Student中,有成员变量name/sex/age/sID/speciality;
//在Teacher中,有成员变量name/sex/age/tID/department。
//请编写出类Student和Teacher所需要的最基本构成。
class Student extends Person{
int sID;
String speciality;
}
class Teacher extends Person{
int tID;
String department;
}
//创建Person接口,有setData()和getData()方法对Person属性name/sex/birthday赋值和获得这些属性组成的字符串信息。
//创建类Student实现Person接口,并对自己的Student属性的成员变量sID/speciality设置值和获得它们值所组成的字符串信息。
interface Person {
void setData(String name, char sex, String birthday);
String getData();
}
class Student implements Person {
String name;
char sex;
String birthday;
int sID;
String speciality;
public void setData(String name, char sex, String birthday) {
this.name=name;
this.sex=sex;
this.birthday=birthday;
}
public String getData() {
return "Name: "+name+"Sex: "+sex+"Birthday: "+birthday+"SID: "+sID+"Speciality: "+speciality;
}
void setStudentData(String name, char sex, String birthday, int sID, String speciality) {
setData(name,sex,birthday);
this.sID=sID;
this.speciality=speciality;
}
}
异常处理
采用throw-catch(抛出 - 捕获)方式,捕获并处理异常。
所有异常类都是Throwable类(自动引入)的子类。常用方法有:
getMessage():获得详细的异常信息。
toString():获得异常的简短描述。
printStackTrace():打印异常发生处堆栈跟踪的信息。
常见的异常类:
ArithmeticException:算术运算中,整数被零除,如int i = 12/0;
ArrayIndexOutOfBoundsException:访问数组超界异常,如int[] a=new int[3]; k=a[5];
IndexOutOfBoundsException:是ArrayIndexOutOfBoundsException类的超类,是抽象类
NullPointerException:试图访问空对象的变量、方法或空数组的元素
NumberFormatException:试图把一字符串非法转换成数组(或相反)
ArrayStoreException:进行写数组操作时,对象或数据类型不兼容
NegativeArraySizeException:创建数组时规定数组大小的参数是负数
IllegalArgumentException:在方法的参数表中参数无效
IllegalThreadStateException:非法改变线程状态,如启动已执行线程
ClassCastException:把对象A转换为对象B,且对象A不是对象B的同类或子类
举例:
throw new IOException(“Cannot find the directory”);
throw new MyException(); //自定义的异常类
void exam(int mark) throws OutofMarkException { 异常抛出 } //该方法抛出异常不处理
多线程设计
线程就是应用程序中的一个可执行线索;多线程就是同一个应用程序中有多个可执行线索,它们可以并发执行。
线程与进程相似,但线程的划分比进程小,同类的多个线程共享内存单元。
一个进程可以包含多个线程。
举例:
//新建一个线程的方法一
class NewThread
extends Thread { //生成Thread类的子类
public void run() { } //在子类中覆盖run()方法
}
//在其他类或方法(主线程)中生成和启动新线程
NewThread t=new NewThread(); //生成子类的对象
t.start(); //调用start()方法启动新线程
//新建一个线程的方法二
class NewThread
implements Runnable { //声明实现Runnable接口
public void run() { } //在类中实现run()方法
}
//在其他类或方法(主线程)中生成和启动新线程
NewThread t=new NewThread(); //声明实现了Runnable接口的对象t
Thread thread=new Thread(t); //利用构造器生成Thread对象,参数是Runnable实例
thread.start(); //调用start()方法启动新线程
线程的状态:新生态,可执行态,阻塞态,停止态
线程的优先级(1-10):数值越大,优先级越高
setPriority(int a):设置线程优先级
把所有被保护资源都加上锁标志(synchronized),使得只有一个线程能取得锁标志访问资源,对被访问的数据进行同步限制。
在方法前加上synchronized修饰符,或synchronized(对象名/this) { 代码段 }
wait():使线程处于阻塞态,自动释放其占有的对象锁。
notify():使线程脱离阻塞态,唤醒一个线程并允许获得锁。
输入输出流
字节流(byte stream)顶层的抽象类:InputStream类和OutputStream类
字符流(character stream)顶层的抽象类:Reader类和Writer类
管道的输入和输出字节流:PipedInputStream类和PipedOutputStream类
对象序列化:实现Serializable接口,可以将对象进行输入输出。
常见的数据来源和数据流目的地:System.in,System.out,System.err
网络编程
以太网:一种计算机局域网技术
TCP/IP:传输控制协议/互联网协议
UDP:用户数据报协议
FTP:文件传输协议
IP地址:TCP/IP协议为每台主机分配一个唯一的32位网络地址,如202.115.5.80
socket(套接字):TCP协议利用IP数据报服务,引入socket区分一台主机的不同进程
域名:是由一串用点分隔的名字组成的Internet上某一台计算机或计算机组的名称,用于在数据传输时对计算机的定位标识(有时也指地理位置)。
java.net包:
Internet寻址:InetAddress类和URL类
TCP/IP面向连接服务类:Socket类和ServerSocket类
UDP/IP无连接服务类:DatagramPacket类和DatagramSocket类
MIME内容类型处理器:ContentHandler类和URLStreamHandler类
WWW相关类:URLConnection类和URLStreamHandler类
GUI编程
界面设计包:java.awt和java.swing
Applet的生命周期:init(); start(); stop();
AWT库中有两类部件:Component类和MenuComponent类
容器:Frame(窗口)、Panel(面板)、Dialog等
部件:Button、Canvas、Checkbox、Choice、Label、List、Scrollbar、TextArea、TextField及菜单
布局管理器:FlowLayout、BorderLayout、GridLayout、CardLayout、GridBageLayout
选择容器;为容器选择一种布置管理器;将部件加入到容器中。
AWT事件处理
当用户对GUI界面进行操作时,就将引发一个事件。
事件源:产生事件的对象
事件处理器(监听器):负责处理事件的方法
当事件源产生事件时,通过事件调用监听器相应的事件处理方法。
委托事件模型:事件被传递给所有希望收到事件的部件或容器(声明为该事件的监听者),使得产生事件的部件可以把事件托付给另一个类处理。
ActionEvent事件,ActionListener监听接口名,actionPerformed(ActionEvent)事件处理方法。