java基础日志

培训日志
培训科目:core java javaSE
第一阶段:2011、7、18——2011、8、11(周末除外)
培训目录:
Module 1: Getting Started 第1章入门
Module 2: dentifiers, Keywords and Types 第2章标识符、关键字以及数据类型
Module 3: Expressions and Flow Control 第3章表达式和流程控制
Module 4:Array 第4章数组
Module 5: Objects and Classes 第5章对象和类
Module 6:Advanced Language Features 第6章高级特性
Module 7: Exceptions 第7章异常
Module 8: Building GUIs 第8章创建GUI界面
Module 9: The AWT Component Library 第9章AWT组件库
Module 10: The AWT Event Model 第10章AWT事件模型
Module 11: JFC 第11章JFC框架
Module 12:Applets 第12章应用小程序
Module 13:Thread 第13章线程
Module 14: Stream I/O and Files 第14章输入输出流和文件系统
Module 15: Networking 第15章网络
重点:前7 章
难点:第14章
了解:第8-11章
日志内容:
1、课堂讲解知识点
2、课后作业
3、网上资料搜集
2011.7.18 周一
1.类的组成:5部分
*包(package)几个具有相同功能的类放在一个包;没写(默认的包);只能放在第一行,
最多只能写一行(一个类只放在一个包);规范:包名必须全部是小写字母
*导入(import)system 在java.lang 中,常使用,可以不用import 导入
使用了其它包的类,需要引入,本类要使用另一个类,并且这2 个类不在同一包中
*表示包中所的有类;在同一包中不需要引入;可以写多行,放在Class 类声明之前
*类的声明(public class)
一个源文件中只能包含一个public 类,但是可以存多个类,文件名必须是public 类.java
类名首字母必须大写;类名在有意义的基础上要简略;一般使用英文单词,但是可以使
用中文
多个单词时,每个单词的首字母都要大写
*{类体}中的属性,变量【封装类的属性-->项目有哪些需求,特征】
*{类体}中的方法
main()方法,入口方法;参数名可以改,其它格式固定;要运行,测试必须写main()
构造方法:方法名与类名相同,没有返回类型,也不是void 类型
业务方法:set(),get()方法
方法名首字母要小写,多个字母时,从第二个字母开始首字母要大写
方法组成:修饰符+返回类型+方法名+参数列表+抛异常+方法体主要考虑(返回类
型和参数列表)
2.Java 环境的搭配:
从官网下载JDK(JavaSE)(分为windows 环境下和Linux 环境下)
安装JDK(jdk-6u12-windows-i586-p.exe)
配置环境变量:JAVA_HOME,CLASSPATH,PATH
JAVA_HOME= C:\Program Files\Java\jdk1.6.0_12 //bin 文件夹之前java 的根目录
PATH=% JAVA_HOME %\bin; //path+原有路径
CLASSPATH=.; //类路径,运行java 路径.代表当前路径
3.java 程序的编译和运行:
编译:javac –d . FirstJava.java
运行:java smple. FirstJava
4.3 种注释符
//单行注释符(快捷键Shift+/)
/* */多行注释符(快捷键Shift+Alt+/)
/** */文档注释
注意:只有文档注释将来使用javadoc 命令可以产生文档,并在文档中作为注释信息
5.标识符:类、方法和变量名称
以字母,_ ,$ 开头,由字母,数字,_ ,$组成
区分大小写
没有长度限制
Example: Student2 ,getName() , $99 ,ab12
6.java 中的原始类型:8种
boolean true or false 不能用数字
byte 8-bit integer 1 个字节8 位-128—127
char 16-bit unicode character 2 个字节16 位
double 64-bit floating-point number 8 个字节64 位
float 32-bit floating-point number 4 个字节32 位
int 32-bit integer 4 个字节32 位
long 64-bit integer 8 个字节64 位
short 16-bit integer 2 个字节16 位
记忆:4 个整数型(byte、short、int、long ),2 个小数型,1 个布尔型,1 个字符型
7.String 字符串:
是类,不是原始类型
不能被继承,是final 类
不用\0 结尾在默认情况下字符串包含一个unicode 字符序列创建对象的方式有2 种:
(1 直接赋值String name="张三";
(2)使用构造方法创建String name=new String("张三");
考题:String name=new String("zhangsan")创建了几个对象?
2 个对象
String 字符串一旦创建,是定长的字符转,是不可以改变的
String n="zhangsan";
n=n+"1234";这样性能低,通常使用StringBuffer 或StringBuilder 类
8.48个关键字
abstract do implements private throw boolean double
import protected throws break else instanceof public
transient byte extends int return true case
false interface short try catch final long
static void char finally native super volatile
class float new switch while continue for
null synchronized default if package this
其中instanceof 是判断类型匹配的
transient 是临时状态的
native 是本地的
volatile 是隔离的
synchronized 是线程同步
9.java 中的基础包:
java.lang
java.awt/
javax.swing/
java.awt.event
java.applet
Java.io //流
Java.net //网络
Java.util //
10.语句用“;”结束程序块用{}包含代码多个空格是没有意义的
11.整数有三种表示方法:8进制(零开头),10 进制,16 进制(零X开头)
在java 中出现的整数默认是int 型
java 中的浮点数缺省是double
long float 是32 位长的浮点数long double 是64 位长的浮点数
float 数字以F 或者f 结尾double 数字以D 或d 结尾
考题: short s3=1;
s3+s3+1; 错误要统一类型改成S3=(short)(s3+1); 正确
s3+=1; 正确相当于直接赋值
12.推荐的标识符命名规则
类名以大写字母开头class Account {…}
接口以大写字母开头interface AccountBase {…}
方法以小写字母或单词开头String getStudentName() {…}
变量以小写字母或单词开头String studentName;
常量以大写字母表示final public static int MAX_ROW= 100;
13.编写一个老师Teacher 类
属性name、sex、salary
方法set get 方法main 方法
《1》测试:创建两个老师,打印每个老师的信息
《2》增加方法:增加工资方法addSalary 方法,实现工资增加500 功能,测试
《3》增加方法:增加工资方法addSalary2 方法,实现工资可以任意增加功能,测试
public class Teacher{
private String name;
private String sex;
private double salary;
public Teacher(){} //无参数构造方法
public Teacher(String name,String sex,double salary){ //带参数构造方法
this.name=name;
this.sex=sex;
this.salary=salary;
}
public void setName(String name){
name=name;
}
public String getName(){
return name;
}
public void setSex(String sex){
sex=sex;
}
public String getSex(){
return sex;
}
public void setSalary(double salary){
salary=salary;
}
public double getSalary(){
return salary;
public String toString(){ //重写toString()方法
return name+" "+sex+" "+salary;
}
public void addSalary(){ //增加工资方法addSalary 方法,实现工资增加500 功能
salary+=500;
}
public void addSalary2(double salary2){ //增加工资方法addSalary2,工资可以任意增加
salary=salary+salary2;
}
public static void main(String []args){
Teacher t=new Teacher("张三","男",73364.2464);
System.out.println(t);
t.addSalary();
System.out.println(t);
t.addSalary2(526354.2136);
System.out.println(t);
}
}
14.学习使用API 文档,查看String,练习String 类的一些方法的使用完成如下作业:
String str = "abc3dfg";
判断str 中是否有1-9 数字
如果有将字符串逆序输出
如果没有原序输出
public class StringTest{
public static void main(String []args){
System.out.println("请输入字符串"); //键盘输入字符串
Scanner reader=new Scanner(System.in);
String str=reader.next();
char[] cs=str.toCharArray(); //字符数组
int i;
for(i=0;i if(cs[i]>='1'&&cs[i]<='9'){
for(int j=cs.length-1;j>=0;j--){
System.out.print(cs[j]);
}
break;
}
}
if(i>=cs.length){
System.out.println(cs);
}
}
}
2011.7.19 周二
1.Java 中小数默认是double
float f=3.14 错误改成float f=3.14f 或是float f=3.14F 对
原始类型范围:[-2n -1,2n-1-1]
2.变量的声明:
intx,y,z; //只声明
float z=3.144f; //声明并赋初值
public class Assign{
private int i; //成员变量实例变量
private String student_name;
private final double PI=3.14; //常量
public void setStudent_name(String n){
student_name = n;
}
public static void main(String [] args){
int i; //局部变量内存不会自动初始化
//i =10; //在使用局部变量前必须初始化
System.out.println(i); //只声明变量i 未初始化
Assign assign = new Assign();
System.out.println(assign.i); //输出0
}
}
3.类与对象:
类:描述群体的共性
(1)变量或属性或: 名词
(2)方法或功能:set()和get() 动词
万物皆对象在大多数情况下是名词具有属性或者成员
有对自身属性或成员操作的方法使用new 关键字创建实例
4.原始类型和引用类型的区别:
原始类型变量的赋值
int x = 10; int y = x;
引用类型变量的赋值
Teacher teacher = new Teacher(“John Smith”, 30, 10000);
或Teacher teacher, teacher_Clone;
teacher = new Teacher(“John Smith”, 30, 10000);
teacher_Clone = teacher;
实例:public class PrimitiveRefType{
public static void main(String [] args){
//原始类型将x值10赋值给y 之后x和y没有关系
int x =10;
int y = x;
x =100;
System.out.println("x="+x); //输出x=100
System.out.println("y="+y); //输出y=10
//引用类型
Teacher t1;//声明变量
t1 = new Teacher("z3",30,5000.0);
System.out.println("t1 第一次:"+t1.getName()); //t1 第一次:z3
Teacher t2 = t1; //将t1 引用地址赋值给t2
t2.setName("L4");
System.out.println("t1===="+t1.getName()); //t1====L4
System.out.println("t2===="+t2.getName()); //t2====L4
}
}
5.局部变量及作用范围:
自动变量,临时变量,栈变量在方法中或者在类{}中的{}定义的
使用前必须初始化
6.实例变量及作用范围:
在类的{}定义的
自动初始化,并有初始值
byte short int long float double char boolean All reference types
0 0 0 0L 0.0f 0.0d ‘\u0000’ false null
实例:public class LocalVariable{
private int i; //成员变量或实例变量
private boolean bl; //boolean 默认false
private String name; //所有类类型默认值null
private Teacher t; //默认值null
//private int a = 8;
public void a(){
int a = 9; //局部变量出了包含的{}就不可用
}
public void b(){
//int b = a; //错误的a 出了a()方法就不可用
}
public static void main(String[]args){
int c ; / /局部变量
c = 0; //局部变量使用前必须初始化
int d = c; //编译报错可能尚未初始化变量c
System.out.println(c);
//成员变量,如果没有初始化,程序会采用各种类型的默认值初始化
LocalVariable lv = new LocalVariable();
System.out.println(lv.i);
System.out.println(lv.bl);
System.out.println(lv.name);
System.out.println(lv.t);
}
}
7.Operators(操作符)
赋值运算符:= 、*=、+=、-=、/=、%=、>>=、<<=、>>>=、&=、^=、|=
比较运算符:<、<=、>、>=、instanceof
相等运算符:== 、!=
算术运算符:+ 、- 、* 、/ 、%
移位运算符:>> 、<< 、>>> (没有<<<) (二进制运算)
位比较运算符:& 、^ 、| 、~ (&都为1 得到1,|有一个1 得到1) (二进制运算)
逻辑运算符:&& 、|| 、! (&&与||称为短路运算)
条件运算符:?、:
实例:public class OperatorTest{
public static void main(String []args){
int i = 4;
int b = i<<2; //左移扩大2n 次方4*2 的n 次方
int c = i>>3; //右移缩小2n 次方4/2 的n 次方
System.out.println(b);
System.out.println(c);
int j1 = 3;
int j2 = 4;
int j3 = j1&j2;
int j4 = j1|j2;
System.out.println(j3);
System.out.println(j4);
String str = "aaaaa";
if(str!=null&&str.length()>3){
System.out.println("字符串长度大于3");
}
String str2 = null;//str2 不一定是什么值
if("abc".equals(str2)){
System.out.println("字符串为abc");
}
? :
(条件表达式)?值1:值2
可以嵌套的
int m1 = 10;
int m2 = 20;
int m3 =(m1>m2)?m1:m2; //返回较大值
System.out.println(m3);
int sc = 70;
}
}==用在原始类型中,类类型不用==
短路运算:String str=null;
if(str!=null&&str.length()>3) 因为str!=null 为False,所以str.length()>3 不执行
String str2=null;
if("abc".equal(str2))或if(str2!=null&&str2.equal("abc"))
8.类型转换两大类
《1》隐式类型转换小---》大
原始类型(大小指范围)
int---->long
float--->double
int--->double
引用类型(大小指父子关系)
String-->Object
Student-->Object
《2》强制类型转换大---》小(损失精度)
原始类型(大小指范围)
long---->int
double--->float
double--->int
引用类型(大小指父子关系)
Object-->String
Object-->Student
语法(强制转换的类型)变量
例如: long l = 100L;
int i = (int)l;
注意:当我们将变量1 强制转换为某类型时,一定注意是否能够转换过去
实例:public class Casting{
public static void main(String[]args){
int i = 10;
long l = i; //隐式转换
float f = 2.0f;
double d = f;
String str = "abc";
Object o1 = str; //o1 类型是Object o1 对象是String
int j = (int)l; //强制类型转换
float f2 = (float)d;
float f3 = (float)2.0;
String str2 = (String)o1;
System.out.println(str2);
//注意
Object o2 = new Object();
//强制类型转换异常java.lang.ClassCastException
//String str3 =(String) o2; //出错
}
}
9.if....else
<1>. if (布尔表达式){
代码语句块
}
<2>. if(布尔表达式){
代码语句块
} else {
代码语句块
}
<3>. if(布尔表达式){
代码语句块
} else if(布尔表达式){
代码语句块
}
else {
代码语句块
}
注意:if 中{}可以省略,但是代码块出现多行时必须加上{},因为If 只控制后面一行
10.switch(变量a){
case 1:
case 2:
...
...
default:
}
Switch(a)中的变量a必须是byte,short,char,int中的一种
每个case 语句中需要加上break;语句
而default 语句可以放在开始,中间或者末尾位置实例:
public class SwitchTest{
public static void main(String[]args){
int month = 4;
switch(month){
case 1:
System.out.println("1 月"+31);
break; //break 跳出switch 循环
case 2:
System.out.println("2 月"+29);
break;
case 3:
System.out.println("3 月"+31);
break;
case 4:
System.out.println("4 月"+30);
break;
case 5:
System.out.println("5 月"+31);
break;
case 6:
System.out.println("6 月"+30);
break;
default:
System.out.println("default"+30);
}
}
}
11.for(循环变量;循环表达式;循环变量的变化){
}
for括弧中必须为3部分,每部分可以不写代码,但两个;必须有
for(;;){} //死循环
实例:int sum =0;
for(int i=1;i<=100;i++){
sum = sum+i; //求1 加到100 的和
}
System.out.println(sum);
增强型for each 循环
for(String s:args)—>(变量:数组或集合){
System.out.println(s);
}
12.(1)While:
实例:int sum2 = 0;
int j =1;
while(j<=100){
sum2 = sum2+j; //求1 加到100 的和
j++;
}
System.out.println(sum2);
(2)Do...while:
实例:int sum3 =0;
j=1;
do{
sum3 = sum3+j; //求1 加到100 的和
j++;
}while(j<=100);
System.out.println(sum2);
区别:Do...while 至少执行一次语句,While 可能一次也不执行;当条件一开始为真时一样
13.//for 求10!
public class ForTest{
public static void main(String []args){
int sum=1;
for(int i=1;i<=10;i++){
sum=sum*i;
}
System.out.println(sum);
}
}
14.//while 求10!
public class WhileTest{
public static void main(String []args){
int sum=1;
int i=1;
while(i<=10){
sum=sum*i;
i++;
}
System.out.println(sum);
}
15.//do while 求10!
public class DoWhileTest{
public static void main(String []args){
int sum=1;
int i=1;
do{
sum=sum*i;
i++;
}while(i<=10);
System.out.println(sum);
}
}
16.使用递归求10!
public class DiGui{
public static void main(String []args){
System.out.println(fun(10));
}
public static int fun(int n){
if(n==1)
return 1;
else
return n * fun(n-1);
}
}
17.有一对兔子,从出生后第3 个月起每个月都生一对兔子,小兔子长到第三个月后每个月
又生一对兔子,
* 假如兔子都不死,问每个月的兔子总对数为多少?
* 程序分析: 兔子的规律为数列1,1,2,3,5,8,13,21....(递归)
public class TuZi{
public static void main(String []args){
int t1=1,t2=1,t3=0;
for(int i=1;i<=20;i++){
if(i==1||i==2){
System.out.println("第"+i+"个月的兔子总数为:"+t1);
}
else{
t3=t1+t2;
System.out.println("第"+i+"个月的兔子总数为:"+t3);
t1=t2;
t2=t3;
}
}
}
}
18.利用条件运算符的嵌套来完成此题:学习成绩> =90 分的同学用A 表示,60-89 分之间的
用B 表示,60 分以下的用C 表示。
* 程序分析:(a> b)?a:b 这是条件运算符的基本例子。
public class OperatorTest{
public static void main(String []args){
int score =97;
String result = score>=90?"A":((score>=60&&score<90)?"B":"C");
System.out.println(result);
}
}
//(条件表达式)?值1:值2
19.打印出所有的"水仙花数",所谓"水仙花数"是指一个三位数,其各位数字立方和等于
该数本身。
* 例如:153 是一个"水仙花数",因为153=1 的三次方+5 的三次方+3 的三次方。
* 程序分析:利用for 循环控制100-999 个数,每个数分解出个位,十位,百位。
public class ShuiXianHua{
public static void main(String[] args){
int n=0,x,y;
for (int i=1; i<=9; i++) {
for (int j=0; j<=9; j++) {
for (int k=0; k<=9; k++) {
x=i*i*i+j*j*j+k*k*k;
y=i*100+j*10+k;
if (x==y) {
n++;
System.out.print(y+" ");
}
}
}
}
}
}
20.判断101-200 之间有多少个素数,并输出所有素数。
* 程序分析:判断素数的方法:用一个数分别去除2...直到这个数,如果能被整除,则表明
此数不是素数,反之是素数。
public class SuShu{
public static void main(String []args){
System.out.println("101 到200 间的素数有: ");
for(int i=101;i<=200;i++){
boolean flag=true;
for(int j=2;j<=Math.sqrt(i);j++){
if(i%j==0){
flag=false;
break;
}
}
if(flag==true){
System.out.print(i+" ");
}
continue;
}
}
}
21.编写程序,实现字母的加密,首先输出原始字母password!,然后将这个一系列原始字母
加密,每个字母都变成字母表中其后的5 个字符输出。
public class PassWord{
public static void main(String [] args){
String str="password";
System.out.println("原字符串:" + str);
char [] c=str.toCharArray();
for(int i=0;i<=c.length-1;i++){
c[i]=(char)(c[i]+5);
System.out.print(c[i]);
}
}
}
2011.7.20 周三(数组)
1.Eclipse 的使用
先新建一个java project 工程,然后在src 下新建一个包sample,最后在sample 下新建一
个类Book。
快捷键Alt + /
多行注释:选中内容+ Ctrl + Shift + / 或是:Ctrl + /
撤销注释:选中内容+ Ctrl + Shift + \ 或是:按2 次Ctrl + /
添加构造方法,set&get 方法,toString()(在Source 下)
2.使用递归求阶乘
package test;
public class DiGui {
public long jieCheng(int n){
if(n<0){
return -1;
}else if(n<=1){
return 1;
}else{
return n* jieCheng(n-1);
/**
* n=10
* 10!= 10*9!
* 9*8!
* 8*7!
* ...
*
* ...
* 2*1!
* 1
*/
}
}
public static void main(String[] args) {
DiGui dg = new DiGui();
long result = dg.jieCheng(10); //成员方法要New对象调用方法
System.out.println(result);
}
}
3.数组:一个有固定大小,可以容纳相同类型数据的集合
一个数组就是一个对象;声明数组并没有创建数组
声明数组语法:int[] iArray ; //原始类型//常用
int iArray2 []; //也可以
Teacher[] tArray; //引用类型,Teacher 为一个类
创建数组用New 关键字,New 类型[长度],创建数组时必须指明长度;
创建好数组后,数组中元素并没有被初始化
创建数组语法:iArray = new int[3];
tArray = new Teacher[3];
数组中元素的位置由索引index 决定;index 从0---长度-1;
* 当我们使用索引index 超出范围就会报异常
* 越界异常运行时异常java.lang.ArrayIndexOutOfBoundsException
初始化数组语法:iArray[0]=1;
iArray[1]=2;
iArray[2]=3;
Teacher t1 = new Teacher();
t1.setName("zhangsan");
tArray[0] = t1;
tArray[1] = new Teacher();
tArray[2] = new Teacher();
System.out.println(tArray[0].getName());
数组的声明创建初始化一步完成
double[] dArray = new double[]{2.2,3.0,4.8};
Teacher [] tArray={t1,new Teacher(),new Teacher()}
打印输出数组:
for(int i=0;i System.out.println(iArray[i]);
}
for(int i=1;i<=dArray.length;i++){ //打印输出数组
System.out.println(dArray[i-1]);
}
for(int i=0;i<=lArray.length-1;i++){ //打印输出数组
System.out.println(lArray[i]);
}
数组的长度:iArray.length 字符串有String.length()
增强型:for(int i:iArray){ //从头循环到尾
i 为取出的元素
多维数组:int [][] iArray;
iArray=new int[4][] 或iArray=new int[4][3] 但是不能iArray=new int[][3]
创建多维数组必须指明第一维长度,第二维可以不指定
int [][]iArray={{11,12,13},{5,4,7,6,8}} 取6 iArray[1][3]
多维数组的长度:iArray.length 为第一维的长度
iArray[1].length 为第二维的长度
打印输出用两层For 循环:int [][] iArray1={{1,2,3,4},{7,5,4}};
for(int i=0;i for(int j=0;j System.out.println(iArray1[i][j]);
}
}
4.break与continue的区别:
break:终止当前的循环语句跳出, 立刻结束包含它的循环
continue:终止当前循环,进入下一个循环,立刻结束当前循环,进入下次循环
public static void main(String[] args) {
for(int i=1;i<=10;i++){
if(i%2==0){
break; //break 执行就立刻结束包含它的循环
}
System.out.println(i); // 输出1
if(i%2==0){
continue; //continue 执行就立刻结束当前循环,进入下次循环
}
System.out.println(i); //输出1,3,5,7,9
}
}
5.给定一个多维数组,找最大最小值:
public class Max_Min {
public static void main(String[] args) {
int[][] mXnArray = { {16, 7, 12},{9, 20, 18}, {14, 11, 5}, {8, 5, 10} };
int max=mXnArray[0][0];
int min=mXnArray[0][0];
for(int i=0;i for(int j=0;j if (mXnArray[i][j]>max){
max=mXnArray[i][j];
}
if (mXnArray[i][j] min=mXnArray[i][j];
}
}
}
System.out.println("最大值为"+max);
System.out.println("最小值为"+min);
}
}
定义一个String[][] 求最小和最大的字符串
public class StringTest {
public static void main(String[] args) {
String[][]s={{"gy","ffd","g12","e44","2f","3w","4dg"},
{"hwr","hv","uwee","ed","tj","tg","2kk","1hk","4gh"},
{"ghk","ehgj","t2","35t","233y","21y"},
{"134","554","f5","jv","sde","dtyt","12"}};
String max=s[0][0];
String min=s[0][0];
for(int i=0;i for(int j=0;j if(s[i][j].compareTo(max)>0){
max=s[i][j];
}
if(s[i][j].compareTo(min)<0){
min=s[i][j];
}
}
}
System.out.println("最大字符串为:"+max);
System.out.println("最字小符串为:"+min);
}
}
6.冒泡排序
public static void main(String[] args) {
int [] b={10,4,9,3,4,23,164};
for(int i=0;i for(int j=0;j if(b[j]>b[j+1]){
int temp =b[j];
b[j]=b[j+1]; //交换
b[j+1]=temp;
}
}
}
for(int maopao:b)
System.out.println(maopao);
}
7.有一组具有名称、价格、作者的书籍资料,可以按照书籍的价格升序进行排序,并打印出
结果;按书名排序输出
public class Book { //先创建Book 类
private String title;
private String author;
private int price;
public Book() {}
public Book(String title, String author, int price) {
this.title = title;
this.author = author;
this.price = price;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String toString(){
return title+" "+author+" "+price;
}
}
public class BookSort { //创建书的对象类
public static void main(String[] args) {
Book b1=new Book("Java","耿祥义",23);
Book b2=new Book("C++","郑旭丽",135);
Book b3=new Book("C","韩非",76);
Book b4=new Book("asp","李四",734);
//按价格排序输出
Book [] a={b1,b2,b3,b4}; //Book 类型数组
for(int i=0;i for(int j=0;j if(a[j].getPrice()>a[j+1].getPrice()){ //调用get 和setPrice 方法
Book temp=a[j]; //交换顺序
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
for(Book jiage:a)
System.out.println(jiage);
System.out.println(" ");
//按书名排序输出
Book [] c={b1,b2,b3,b4};
for(int i=0;i for(int j=0;j if(c[j].getAuthor().compareTo(c[j+1].getAuthor())>0){ //用compareTo 比较字符串大小
Book temp=c[j];
c[j]=c[j+1];
c[j+1]=temp;
}
}
}
for(Book shuming:c) //增强型循环输出
System.out.println(shuming);
}
}
8.编写程序将华氏温度78 度转换为摄氏温度,转换成的摄氏温度在屏幕上显示出来:
转换公式为:摄氏度=(5/9)*(华氏度-32)
public class TemperatureConverse {
//华氏温度转换为摄氏温度
public double hToc(double h){
return (5.0/9)*(h-32);
}
public static void main(String[] args) {
TemperatureConverse tc=new TemperatureConverse(); //必须先创建对象
double h1=78;
System.out.println("78℉= "+tc.hToc(h1)+" ℃"); 通过对象调用方法
System.out.println();
}
}
9:异常:
空值异常
类型转换异常
数组越界异常
10.Eclipse 快捷键:
运行作用域功能快捷键
全局单步返回F7
全局单步跳过F6
全局单步跳入F5
全局单步跳入选择Ctrl+F5
全局调试上次启动F11
全局继续F8
全局使用过滤器单步执行Shift+F5
全局添加/去除断点Ctrl+Shift+B
全局显示Ctrl+D
全局运行上次启动Ctrl+F11
全局运行至行Ctrl+R
全局执行Ctrl+U
重构作用域功能快捷键
全局撤销重构Alt+Shift+Z
全局抽取方法Alt+Shift+M
全局抽取局部变量Alt+Shift+L
全局内联Alt+Shift+I
全局移动Alt+Shift+V
全局重命名Alt+Shift+R
全局重做Alt+Shift+Y
源代码作用域功能快捷键
Java 编辑器格式化Ctrl+Shift+F
Java 编辑器取消注释Ctrl+
Java 编辑器注释Ctrl+/
Java 编辑器添加导入Ctrl+Shift+M
Java 编辑器组织导入Ctrl+Shift+O
Java 编辑器使用try/catch 块来包围Ctrl+1
项目作用域功能快捷键
全局全部构建Ctrl+B
文件作用域功能快捷键
全局保存Ctrl+X Ctrl+S
全局打印Ctrl+P
全局关闭Ctrl+F4
全局全部保存Ctrl+Shift+S
全局全部关闭Ctrl+Shift+F4
全局属性Alt+Enter
全局新建Ctrl+N
文本编辑
作用域功能快捷键
文本编辑器改写切换Insert
文本编辑器上滚行Ctrl+↑
文本编辑器下滚行Ctrl+↓
搜索
作用域功能快捷键
全局出现在文件中Ctrl+Shift+U
全局打开搜索对话框Ctrl+H
全局工作区中的声明Ctrl+G
全局工作区中的引用Ctrl+Shift+G
导航作用域功能快捷键
Java 编辑器打开结构Ctrl+F3
全局打开类型Ctrl+Shift+T
全局打开类型层次结构F4
全局打开声明F3
全局打开外部javadoc Shift+F2
全局打开资源Ctrl+Shift+R
全局后退历史记录Alt+←
全局前进历史记录Alt+→
全局上一个Ctrl+,
全局下一个Ctrl+.
Java 编辑器显示大纲Ctrl+O
全局在层次结构中打开类型Ctrl+Shift+H
全局转至匹配的括号Ctrl+Shift+P
全局转至上一个编辑位置Ctrl+Q
Java 编辑器转至上一个成员Ctrl+Shift+↑
Java 编辑器转至下一个成员Ctrl+Shift+↓
文本编辑器转至行Ctrl+L
窗口作用域功能快捷键
全局激活编辑器F12
全局切换编辑器Ctrl+Shift+W
全局上一个编辑器Ctrl+Shift+F6
全局上一个视图Ctrl+Shift+F7
全局上一个透视图Ctrl+Shift+F8
全局下一个编辑器Ctrl+F6
全局下一个视图Ctrl+F7
全局下一个透视图Ctrl+F8
文本编辑器显示标尺上下文菜单Ctrl+W
全局显示视图菜单Ctrl+F10
全局显示系统菜单Alt+-
查看作用域功能快捷键
全局放大Ctrl+=
全局缩小Ctrl+-
编辑作用域功能快捷键
全局查找并替换Ctrl+F
文本编辑器查找上一个Ctrl+Shift+K
文本编辑器查找下一个Ctrl+K
全局撤销Ctrl+Z
全局复制Ctrl+C
全局恢复上一个选择Alt+Shift+↓
全局剪切Ctrl+X
全局快速修正Ctrl1+1
全局内容辅助Alt+/
全局全部选中Ctrl+A
全局删除Delete
全局上下文信息Alt+?
Java 编辑器显示工具提示描述F2
Java 编辑器选择封装元素Alt+Shift+↑
Java 编辑器选择上一个元素Alt+Shift+←
Java 编辑器选择下一个元素Alt+Shift+→
文本编辑器增量查找Ctrl+J
文本编辑器增量逆向查找Ctrl+Shift+J
全局粘贴Ctrl+V
全局重做Ctrl+Y
F3: 察看声明打开声明
ctrl + shift + g:查看引用
ctrl + shift + n:重命名
ctrl + shift + o:导入类
ctrl + shift + r:启动上次运行
ctrl + shift + f:格式化代码
ctrl + shift + t:查找相关信息
ctrl + c:复制
ctrl + v:粘贴
ctrl + x:切剪
ctrl + a:全选
ctrl + f:查找
ctrl + z:撤销
ctrl + y:重做
ctrl + s:保存
Ctrl + M: 工作区最大化/最小化
Crtl+1: 修正错误
Shift+Alt+T: 重构
Shift+Alt+M: 提取函数
Shift+Alt+R: 重命名
Shift+Alt+C: 更改函数标记
Ctrl+Shitf+F: 格式化代
Alt + / 智能提示
Alt + shift + r 重命名变量
2011.7.21 周四
1. / 的两边可以是整数整数/整数=整数
/ 的两边也可以是double 类型9.0/5 或9/5.0 都为double 型数据
2.数组的拷贝:
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
参数:
src - 源数组。
srcPos - 源数组中的起始位置。
dest - 目标数组。
destPos - 目标数据中的起始位置。
length - 要复制的数组元素的数量。
public static void main(String[] args) {
int [] iArray =new int[]{1,2,3,4,5};
int [] destArray ={10,9,8,7,6,5,4,3,2,1};
System.arraycopy(iArray, 0, destArray, 0, iArray.length);
for(int i:destArray){
System.out.print(i+"\t");
}
//数组工具类Arrays 实现比如查找、排序(Sort)、
返回指定数组内容的字符串表示形式(toString)
}
3.导入java 工程:import->General->Existing Projects into Workspace->找到工程->选中Copy
Projects into Workspace 即可
4.查找之前必须先对数据进行排序(升序或是降序)---二分查找法
5.i++:先使用i 的原值,然后将i 加1
++i:先使i 加1,再使用i 加后的值
执行1,2 行代码后,x,a,b 三个变量的值是什么?c
1. Int x, a=6, b=7;
2. X = a++ + b++; //x = 13, a = 7, b=8
如果换成X = ++a + ++b //x = 15, a = 7, b=8;
6. int x = 4;
System.out.println(“value is “ + ((x>4)?99.9:9)); //类型自动转换为Double 型
//运行结果为:value is 9.0
7.类与对象:
封装:Encapsulation
继承:Inheritance
多态:Polymorphism------->父类型子对象
Java 中类声明的和实现同时进行。
方法的语法:一般只需考虑返回类型和参数列表
([]) [throws ] {}
修饰符返回类型方法名参数列表抛异常方法体
如果方法内没有返回值时,返回类型定义为Void
构造方法没有返回值,也没有Void
8.假设已经创建了A 类
则A a=new A() System.out.println(a+b); 是错误的
A b=new A() System.out.println(a+" "+b); 是正确的
9.参数传递:
原始类型参数传递值传递
引用类型参数传递传递引用实质也是值传注意:引用类型传递只能改变对象
的内容,而不能改变完整的对象
public class ParamPassTest {
* 原始类型参数传递值传递
public void a(int i){
i++;
System.out.println("a()===="+i);
}
* 引用类型传递引用实质也是值传递
public void changePersonName(Person p){
p.setName("zhangsan");
System.out.println(p.getName());
}
* 引用类型传递只能改变对象的内容,而不能改变完整的对象
public void changePerson(Person p){
p = new Person();//改变对象本身
p.setName("zhangsan");
System.out.println(p.getName());
}
public static void main(String[] args) {
ParamPassTest ppt = new ParamPassTest();
int i = 9;
System.out.println(i);//9
ppt.a(i);//a()====10
System.out.println(i);//9
Person p = new Person();
p.setName("aaa");
System.out.println(p.getName());//aaa
ppt.changePersonName(p);//zhangsan
System.out.println(p.getName());//zhangsan
Person p2 = new Person();
p2.setName("bbb");
System.out.println(p2.getName());//bbb
ppt.changePerson(p2);
System.out.println(p2.getName());//bbb
}
}
10.This 关键字:
this 两种主要的用法
《1》this.参数与成员变量相同时,用This 区分
this 代表当前类实例
this.属性或this.方法
《2》this(XXX,xxx) 同一个类中,构造方法之间互相调用
this()必须出现在构造方法中的第一行功能代码
public class ThisTest {
public ThisTest(){
//int i = 1; //如果有该行代码this()就报错
this(10);//调用另一个整型参数的构造方法必须放第一行
int i = 1;//可以这样
}
public ThisTest(int age){
this.age = age;
}
private int age;
public void setAge(int age){
this.age = age;
}
public void a(int a){
this.setAge(a);
}
public static void main(String[] args) {
ThisTest tt = new ThisTest();
//tt.setAge(10);
//this.setAge(10);
}
}
11.封装
习惯要求
* 一般会将属性private 私有化,提供统一的public 方法来完成属性的操作
* 私有化的属性只能在当前类中对象.属性可以使用,
* 其他类不能访问私有变量
* 增强了可维护性
12.方法的重载(Method Overloading)
要求:《1》几个方法在同一个类中
《2》方法名相同,参数列表一定不相同(参数个数、类型、顺序)
注意:参数列表是否相同不能由参数名决定
参数名只是形参
《3》返回类型可以不同
13.编写Person 类,包括姓名、年龄及熟悉setter getter 方法,根据年龄查找Person 方法
(注意:该方法要求下面测试类中初始化数据年龄不能相同)
测试类PersonTest 类
使用数组初始化10 个数据(年龄不能相同)
完成调用根据年龄查询Person 的方法,如果有打印该对象的姓名年龄信息,如果没有
打印没有此人。
public class Person {
private String name;
private int age;
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String toString(){
return name+" "+age;
}
}
public class PersonTest {
public void findPersonByAge(int a,Person[]p){
boolean flag=false;
for(int i=0;i if(p[i].getAge()==a){
System.out.println(p[i]);
flag=true;
}
}
if(flag==false){
System.out.println("没有此人");
}
}
public static void main(String[] args) {
Person p1=new Person("zhangsan",12);
Person p2=new Person("lisi",7);
Person p3=new Person("wamhwu",98);
Person p4=new Person("hangshu",76);
Person p5=new Person("gaodeng",53);
Person p6=new Person("shenyu",32);
Person p7=new Person("yangxin",26);
Person p8=new Person("liuli",32);
Person p9=new Person("xiongxiuxin",29);
Person p10=new Person("shixi",31);
Person []p={p1,p2,p3,p4,p5,p6,p7,p8,p9,p10};
PersonTest pt=new PersonTest();
pt.findPersonByAge(32, p);
}
}
14.编写函数double fun(double h),它的功能是:四舍五入并保留两位小数。
public class SheRu {
public double fun(double h){
long sheRu=Math.round(h*100);
return sheRu/100.0;
}
public static void main(String[] args) {
SheRu sh=new SheRu ();
System.out.println(sh.fun(1664776.67578));
}
}
15.青年歌手参加歌曲大奖赛,有10 个评委对她的进行打分,试编程求这位选手的平均得分
(去掉一个最高分和一个最低分)。
double a[]={7,9,8,7.5,8.6,9.2,9.7,9.4,8.5,8};
public class Average {
public static void main(String[] args) {
double a[]={7,9,8,7.5,8.6,9.2,9.7,9.4,8.5,8};
double sum=0;
double average=0;
double max=a[0];
double min=a[0];
for(int i=0;i if(a[i]>max){
max=a[i];
}
if(a[i] min=a[i];
}
}
for(int i=0;i sum+=a[i];
}
average=(sum-max-min)/8;
//System.out.println(sum);
//System.out.println(max);
//Sysem.out.println(min);
System.out.println(average);
}
}
16.编程将字符串\_0\_4d_a3 转换为\UL___0_\UL___ddddd_d___a_3
public class StringConverse {
public static void main(String[] args) {
System.out.println("请输入字符串");
Scanner reader=new Scanner(System.in);
String str=reader.next();
char[] cs=str.toCharArray();
String result=" ";
for(int i=0;i if(cs[i]=='\\'){
result +="\\UL_";
}
else if(cs[i]=='_'){
result +="_";
}
else if((cs[i]<='9'&& cs[i]>'0')&&(cs[i+1]<='z'&&cs[i+1]>'a')){
int k=cs[i]-48;
for(int j=0;j<=k;j++){
result+= cs[i+1];
}
}
else
result+=(cs[i]+"_");
}
result+= cs[cs.length-1];
System.out.print(result);
}
}
2011.7.22 周五
1、四舍五入并保留两位小数
double fun(double h)
{ return int(h*100+0.5)/100.0; }
或是public double fun(double h){
long sheRu=Math.round(h*100);
return sheRu/100.0;
}
2.创建和初始化对象:new 对象时,先对成员变量初始化,再执行构造函数
创建无参数构造方法时:先进入无参构造函数,然后给成员变量赋值,然后跳出无参构
造函数,最后结束
创建带参数构造方法时:先进入带参构造函数,然后给成员变量赋值,然后再把参数替
换成传入的参数,最后结束
3. * 构造方法
* 《1》方法名和类名相同
* 《2》没有任何返回类型也没有void
* 《3》当没有定义构造方法时,java 在编译时会
* 自动提供一个不带有参数的缺省的构造方法。
* 注意:如果自己手写了任何构造方法,
* 系统不再提供无参数构造方法。
* 习惯:如果自己手写有参数构造方法,
* 同时也不要忘记写一个无参数构造方法
4.类的继承父子关系“是”的关系
* <1>继承关键字extends 还可以扩展
* <2>是否父类所有属性和方法都被继承? 不是
* (1)构造方法不会被继承
* (2)方法和属性(包括protected 关键字)可以被继承
* 方法和属性如果修饰符是public 或protected 可以被继承
* <3>子类的每个构造方法隐式调用了父类的缺省的构造方法
* 是不是父类必须有无参数构造方法?不是
* 如果父类没有无参数构造方法,
* 子类必须每个构造方法显式指明调用父类某有参数构造方法
* <4>super(xxx) 子类构造方法调用父类构造方法
* 默认子类构造方法中都有super(),调用父类无参数构造方法
* super()也必须写在子类构造方法的第一行
* 同一个构造方法中不可能同时出现super()和this()
* <5> super.xxx 属性或方法调用父类属性或方法super(name,age,salary);
* super 指向父对象
* <6>类只能单一继承A—>B,A—>C 错A—>B—>C 对
* 接口可以多继承
This 与Super 的区别:This.与Super 的区别;This()和Super()的区别
5. 多态* 一个对象就是一个对象类型
* 一个变量可以是多个类型
* 继承与重载不同,
* 继承的关系是在运行时确认的(指向java 命令运行类时,确认对象是子对象还是父
对象),
* 而重载则是在编译时确认的(两个方法是否构成重载,编译时就能识别语法)
* 多态出现形式:
父类型子对象Employee m = new Manager();
接口类型实现类对象
6.InstanceOf 操作符:是一个布尔操作符;判断一个对象是否是另一个类的实例
如:Employee 是父类Manager 是子类
Employee e = new Employee();
Manager m = new Manager();
Employee m2 = new Manager();
Object o1 = e;
Object o2 = m;
m2 instanceof Employee //true
m2 instanceof Manager /true
7.类型转换
用InstanceOf 操作符判断对象的类型;子类类型隐式的升级到父类类型;父类类型必须要
强制转换才能降到子类类型
//强制类型转换大---》小
Manager m3 = (Manager)o2;
//强制类型转换大---》小注意:对象是否真正能够转换过去
8.方法重写Overridden
* 《1》是父子类中的两个方法才能说子类中方法是否重写父类方法
* 《2》名称相同,参数列表相同,返回类型相同(基本上保证和父类方法一致)
* 《3》方法的可见性不能缩小(方法修饰符范围不能缩小)
* 《4》异常的抛出数量不能增加(异常个数异常大小)
* 多态的多种形式最终能够表现出来,关键是子类重写父类方法
父类:
public class Animal {
protected void eat(){
System.out.println("Animal eat()");
}
}
子类
public class Dog extends Animal {
public void eat(){
System.out.println("Dog eat()");
}
public static void main(String[] args) {
Animal a = new Dog();
a.eat();
}
}
9.考题Overload和Override 的区别
Overload 是重载的意思,Override 是覆盖的意思,也就是重写。
重载Overload 表示同一个类中可以有多个名称相同的方法,但这些方法的参数列表各不
相同(即参数个数或类型不同)。
重写Override 表示子类中的方法可以与父类中的某个方法的名称和参数完全相同,通过子
类创建的实例对象调用这个方法时,将调用子类中的定义方法,这相当于把父类中定义的那
个完全相同的方法给覆盖了,这也是面向对象编程的多态性的一种表现。子类覆盖父类的方
法时,只能比父类抛出更少的异常,或者是抛出父类抛出的异常的子异常,因为子类可以解
决父类的一些问题,不能比父类有更多的问题。子类方法的访问权限只能比父类的更大,不
能更小。如果父类的方法是private 类型,那么,子类则不存在覆盖的限制,相当于子类中
增加了一个全新的方法。
10.编写图形类Shape,
包括求面积的方法getArea()方法,该方法实现就输出”Shape 求面积方法“
编写长方形类Rectangle 继承Shape 类
定义长宽属性及setter getter 方法
重写getArea 方法,实现求面积并打印
编写圆形类Circle 继承Shape
定义半径r 及setter getter 方法
重写getArea 方法,实现求面积打印
编写测试类ShapeTest
main 方法测试,创建一个Shape 类型数组,初始化数组,包含Shape、Rectangle、
Circle 对象,然后循环该数组分别调用求面积方法测试。
public class Shape {
//要重写的方法getArea()
public void getArea(){
System.out.println("Shape 求面积方法");
}
}
public class Rectangle extends Shape {
private double a;
private double b;
public double getA() {
return a;
}
public void setA(double a) {
this.a = a;
}
public double getB() {
return b;
}
public void setB(double b) {
this.b = b;
}
public Rectangle() {
super();
}
public Rectangle(double a, double b) {
super();
this.a = a;
this.b = b;
}
//重写基类的方法getArea()
public void getArea(){
System.out.println("长方形的面积是" +a*b);
}
}
public class Circle extends Shape {
private double r;
public double getR() {
return r;
}
public void setR(double r) {
this.r = r;
}
public Circle(double r) {
super();
this.r = r;
}
public Circle() {
super();
}
//使得小数点后面保留2 位小数,并四舍五入
public double count(double x){
long lx=Math.round(x*100);
return lx/100.0;
}
//重写基类的方法getArea()
public void getArea(){
System.out.println("圆的面积是" + count(Math.PI*Math.pow(r, 2))); //Math.pow(r, 2)
为r*r
}
}
public class ShapeTest {
public static void main(String[] args) {
//创建Shape、Rectangle、Circle 对象并调用构造函数初始化
Shape s=new Shape();
Rectangle r=new Rectangle(4.0,5.0);
Circle c=new Circle(3.0);
//创建Shape 类型的数组,用来存放Shape、Rectangle、Circle 对象
Shape [] s1={s,r,c};
//循环数组s1 分别调用Shape、Rectangle、Circle 的求面积方法
for(Shape sh:s1){
sh.getArea(); //Shape 求面积方法
//长方形的面积是20.0
//圆的面积是28.27
}
}
}
11.在10 的基础上,在ShapeTest 类中编写个getArea(。。。)方法,该方法可以传入Shape、
Rectangle、Cricle 任何类型对象,执行getArea()方法
public class ShapeTest {
public void getArea(Shape s2){
s2.getArea();
}
public void getArea(Rectangle r1){
r1.getArea();
}
public void getArea(Circle c1){
c1.getArea();
}
public static void main(String[] args) {
ShapeTest st=new ShapeTest();
st.getArea(s);
st.getArea(r);
st.getArea(c);
}
}
12.编写唱片Track 和时间Duration 类及测试类Driver
Write three classes:
Track, Duration and Driver.
Duration class has three fields, i.e. hours, minutes and seconds, and two overloaded
constructors.
Track has two fields, i.e. title and duration which has Duration type, and get/set methods.
The Driver class has a main method to set track’s duration and then, print out the duration.
//Duration 类
public class Duration{
private int hours;
private int minutes;
private int seconds;
public Duration(){}
public Duration(int hours,int minutes,int seconds){
this.hours=hours;
this.minutes=minutes;
this.seconds=seconds;
}
public Duration(int timeseconds){
hours = timeseconds/3600;
timeseconds = timeseconds-(hours * 3600);
minutes = timeseconds / 60;
timeseconds = timeseconds - (minutes * 60);
seconds = timeseconds;
}
public void sethours(int hours){
this.hours=hours;
}
public void setminutes(int minutes){
this.minutes=minutes;
}
public void setseconds(int seconds){
this.seconds=seconds;
}
public int gethours(){
return hours;
}
public int getminutes(){
return minutes;
}
public int getseconds(){
return seconds;
}
}
//类
public class Track {
private String title;
private Duration duration;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Duration getDuration() {
return duration;
}
public void setDuration(Duration duration) {
this.duration = duration;
}
public Track(String title, Duration duration) {
super();
this.title = title;
this.duration = duration;
}
public Track() {
super();
}
}
// 类Driver
public class Driver {
public static void main(String[] args) {
Duration da=new Duration(12345);
Track t=new Track("雪之光",da);
System.out.println(t.getTitle()+ " : " +da.gethours()+":" +da.getminutes()+":"
+da.getseconds());
}
}
//输出雪之光0:42:14
2011.7.25 周一
1.抽象类
* 《1》有抽象方法的类,必须声明为抽象类
但是,抽象类中可以存在实现的方法,甚至抽象类中一个抽象方法也没有
* 《2》抽象类不能被实例化(不能new 对象) AbstractTest at = new AbstractTest();
* 《3》可以声明一个变量是抽象类类型的AbstractTest at = null;
* <4>是否子类继承抽象父类,必须重写父类中抽象方法吗?
不是,如果子类没有将父类所有抽象方法实现,子类也必须声明为抽象类:
抽象方法:没有{}实现体,直接;结束的方法
* 抽象方法必须有abstract 修饰public abstract void b();
* 有抽象方法的类,必须声明为抽象类abstract class
2.接口--抽象类继续抽象,没有任何实现的方法就叫接口
* interface 关键字
* 《1》所有方法都抽象
定义方法时抽象abstract 关键字可省略public 可省略
* 《2》接口中定义的所有的变量都会被定义成public final static 的
//接口中变量都是public final static 的
public static final int i = 10;
等价于int j = 100;
* 《3》类不叫继承接口,而是实现接口implements
* 注意:接口可以继承吗?
* 可以而且可以多重继承一个接口可以继承(extends) 多个接口
* 类实现接口,需要实现接口中所有抽象方法
* 一个类可以实现多个接口, 语法implements 接口1,接口2,...
* 《4》接口不能new 对象,但是可以作为一种类型声明变量
考题:abstract class 和interface 有什么区别?
1.抽象类可以有构造方法,接口中不能有构造方法。
2.抽象类中可以有普通成员变量,接口中没有普通成员变量
3.抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非
抽象的普通方法。
4. 抽象类中的抽象方法的访问类型可以是public,protected 和(默认类型,虽然
eclipse 下不报错,但应该也不行),但接口中的抽象方法只能是public 类型的,并且
默认即为public abstract 类型。
5. 抽象类中可以包含静态方法,接口中不能包含静态方法
6. 抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可
以任意,但接口中定义的变量只能是public static final 类型,并且默认即为
public static final 类型。
7. 一个类可以实现多个接口,但只能继承一个抽象类。
3.<1>静态变量(类变量):
静态变量被类的所有实例共享, 不依赖任何一个对象所有对象都是用一个静态变量
静态变量是类一旦被加载,就立刻初始化,没有创建对象,也可以直接使用
在类的外部直接存取,直接使用类名.静态变量
静态变量可以不需要创建对象直接类名.静态变量使用,也可以对象.静态变量来使

所有对象共用一个静态变量,
所以任何一个对象将静态变量改变,其他对象调用的静态变量也改变
<2>成员变量(实例变量):
直接包含在类的{}内,非静态变量
<3> 静态代码块:
只被调用一次类加载时,就立刻会调用,而且只调用一次
作用:一般完成静态变量的初始化工作或者完成类中程序只加载一次的功能代码
<4>普通代码块:
每创建一个对象,就会执行一次,而且在创建对象的构造方法之前执行
4.成员方法:必须先有成员对象才能够使用成员方法
静态方法:静态方法也是在类加载时就初始化,可以没有对象,直接类名.静态方法
静态方法初始化先于对象
由于静态方法先于对象初始化,所以不能够在静态方法中直接使用成员方法
由于静态方法先于对象初始化,所以不能够在静态方法中直接使用成员变量
静态方法可以直接使用静态变量
实例:
public class StaticTest {
//成员变量或实例变量
private int i;
//静态变量或类变量或全局变量
private static int b;
// 静态代码块
static{
//i=10;
System.out.println("静态代码块执行=====");
b = 10;
}
//普通代码块
{
System.out.println("普通代码块执行====");
}
public StaticTest(){
System.out.println("构造对象========");
}
//成员方法
public void a(){
b++;
b();
}
public void c(){
a();
}
//静态方法
public static void b(){
//this.a(); 错
//i++; 错
b++; 对
}
public static void main(String[] args) {
StaticTest st1 = new StaticTest();
StaticTest st2 = new StaticTest();
* 两个对象分别有自己的实例变量i
* st1.i=100 不会改变st2.i st2.i=10
st1.i = 100;
System.out.println(st1.i);
System.out.println(st2.i);
System.out.println(StaticTest.b);
System.out.println(st1.b);
System.out.println(st2.b);
st1.b = 1000;
System.out.println(st2.b);//1000
//静态方法可以直接调用静态方法
b();
}
}
5.要覆盖或重写父类静态方法,重写的方法必须是static 静态的
我们准确叫做隐藏父类静态方法
只有子类型子对象时,才能真正将父类静态方法隐藏起
a.b(); //==》SuperA.b(); 所以没有将父类的静态方法完全隐藏
public class SubA extends SuperA {
public void a() {
System.out.println("Sub A a()");
}
public static void b(){
System.out.println("Sub A b()");
}
public static void main(String[] args) {
SuperA a = new SubA();
a.a();
a.b(); //==》SuperA.b(); 所以没有将父类的静态方法完全隐藏
}
}
6.final 关键字
* 《1》如果变量前加final 就是常量
要求(1)值不能再改变
(2)声明时必须初始化
习惯:常量定义时字母都大写
* 《2》如果方法前加final 该方法子类就不能重写
* 《3》如果类前面加final 该类就不能被继承
7.访问控制:
简答题
1. 面向对象的软件开发方法用什么把数据和基于数据的操作封装在一起? //类
2. 在一个类定义中,用什么描述对象的状态? //属性用什么描述对象的行为?//方法
3. 什么方法是一个特殊的方法,用于对对象进行初始化? //构造方法
4. 一个源程序文件中,能有多于一个的public 类吗? //不能源程序文件名=public 类.java
5. 构造方法的方法名可由编程人员任意命名吗? //不能必须与类名相同
6. 类的构造方法名必须和类名相同吗? //是
7. 构造函数有返回值吗? //没有,也没有void
8. 构造函数可以重载吗? //可以
9. 如果一个类定义中没有定义构造方法,该类有构造函数吗? //有,默认的不带参数的构
造方法
10. 如果一个类定义中已经定义了构造方法,java 还会给它定义缺省的构造方法吗? //不会
11. 类的访问控制权有哪两种? //public 和default
12. 用什么修饰符修饰的方法称为静态方法? //static
用什么修饰符修饰的属性称为静态属性? //static
13. 静态属性和静态方法仅属于类的一个具体对象吗?它属于谁?
不是,属于类
14. static 变量能是private 变量吗? //可以
15. 使用静态成员都能以什么做前缀? //类名或对象
16. static 方法中能有this 引用吗? //不能
17. 非static 方法中可以有this 引用吗? // 可以
18.static 方法能处理非static 成员吗? //不能
19.非static 方法能处理static 成员吗? //能
20. 类的私有属性和私有方法能不能被其子类直接访问? //是
填空题
1.下面是一个类的定义,请完成程序填空。
public class Myclass
{ int x, y;
Myclass ( int i, int j) // 构造方法
{
x=i; y=j;
}
}
2. 下面是一个类的定义,请将其补充完整。
class Student
{
String name;
int age;
Student( String s, int i)
{
name=s;
age=i;
}
}
3.下面是一个类的定义,请将其补充完整。
class Myclass // 定义名为Myclass 的类
{
static int var=666;
static int getvar()
{ return var; }
}
4.下面程序的功能是通过调用方法max()求给定的三个数的最大值,
请将其补充完整。
public class Class1
{
public static void main( String args[] )
{
int i1=1234,i2=456,i3=-987;
int MaxValue;
MaxValue=i1;
System.out.println("三个数的最大值:"+MaxValue);
}
public static int max(int x,int y,int z)
{ int temp1,max_value;
temp1=x>y?x:y;
max_value=temp1>z?temp1:z;
return max_value;
}
}
写出下列程序的输出结果
public class Test
{
public static void main(String[] args)
{
Count myCount = new Count();
int times = 0; //成员变量
for(int i=0;i<100;i++)
increment(myCount , times);
System.out.println("count is" + myCount.count);
System.out.println("time is"+ times);
}
public static void increment(Count c , int times) //静态方法
{
c.count++;
times++;
}
}
class Count
{
public int count;
Count(int c)
{
count =c;
}
Count()
{
count =1;
}
}
结果:count is 101
time is 0
编写一个类,要求使用单例模式
提示:单例模式就是这个类在使用时候只能new 一个对象,多个实例都是一个对象引用
public class Singleton {
private static Singleton s;
private Singleton(){
System.out.println("A Singleton Model example");
}
public static Singleton getInstance() {
if(s==null)
s=new Singleton();
return s;
}
public static void main(String[] args) {
Singleton s=Singleton.getInstance();
}
}
2011.7.26 周二
1.类的访问控制权有public 和default
2.单例模式实例:
单例模式就是这个类在使用时候只能new 一个对象,多个实例都是一个对象引用
public class Singleton {
//1 构造方法私有化
private Singleton(){}
//3 声明一个该类类型的静态变量
private static Singleton s ;
//2 提供一个公有的static 返回该类类型的方法
public static Singleton getInstance(){
if(s==null)
s = new Singleton();
return s;
}
}
public class SingletonTest {
public static void main(String[] args) {
Singleton st1 = Singleton.getInstance();
Singleton st2 = Singleton.getInstance();
System.out.println(st1==st2); //true 同一个对象
}
}
3.==与equals()的区别:
* ==比较值相等
原始类型比较值大小引用类型比较对象地址
* equals(Object o)方法
判定两个对象是否具有相同的类型和内容
* equals()方法是Object 类的方法等价于== 比较对象地址
* 如果自己的类,必须重写equals()方法
* 约定:重写equals()方法,应该同时重写hashCode()方法
* 达到两个对象相等,应该对象的哈希码也相同
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
实例:
public class EqualsTest {
public static void main(String[] args) {
int x =10;
int y =10;
System.out.println(x==y); //true
Student s1 = new Student("z3",20);
Student s2 = new Student("z3",20);
System.out.println(s1==s2); //false
System.out.println(s1.equals(s2)); //true
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
//考题:
String str1 = "abc";
String str2 = new String("abc");
String str3 = "abc";
System.out.println(str1==str2); //false
System.out.println(str1.equals(str2));//true
System.out.println(str1==str3); //true
System.out.println(str1.equals(str3));//true
}
}
4.toString()方法
* 作用:对象转换为字符串时调用直接打印对象时默认会调用
* 当打印一个对象的时候,隐式调用对象的toString()方法
* 一般要重写toString()方法。
@Override
public String toString() {
return "学生名:"+this.name+"\t 学生年龄:"+this.age;
}
//println(String s)
System.out.println(s1.toString());
//println(Object o)
System.out.println(s1);
5.按照上课讲的实例开发
Track 唱片类
Duration 时间封装类要求构造方法有传递总时间的构造方法
TrackTest 测试类
测试打印唱片Track 对象和Duration 对象可以直接打印(重写toString 方法)
要求打印时间为hh:mm:ss 的格式
public class Duration {
private int hours;
private int minutes;
private int seconds;
public int getHours() {
return hours;
}
public void setHours(int hours) {
this.hours = hours;
}
public int getMinutes() {
return minutes;
}
public void setMinutes(int minutes) {
this.minutes = minutes;
}
public int getSeconds() {
return seconds;
}
public void setSeconds(int seconds) {
this.seconds = seconds;
}
public Duration(int hours, int minutes, int seconds) {
this.hours = hours;
this.minutes = minutes;
this.seconds = seconds;
}
//传递总时间的构造方法
public Duration(int total){
this.hours = total/3600;
this.minutes = total%3600/60;
this.seconds = total%60;
}
//保证为2 位数
public String format(int x){
if(x<10)
return "0"+x;
else
return " "+x;
}
//重写object 的toString()方法
控制hh:mm:ss 的格式
public String toString(){
if(hours==0)
return format(minutes)+":"+format(seconds);
else
return format(hours)+":"+format(minutes)+":"+format(seconds);
}
}
public class Track {
private String title;
private Duration duration;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Duration getDuration() {
return duration;
}
public void setDuration(Duration duration) {
this.duration = duration;
}
public Track(String title, Duration duration) {
this.title = title;
this.duration = duration;
}
public Track(String title) {
super();
this.title = title;
}
public Track(Duration duration) {
super();
this.duration = duration;
}
public Track() {}
//重写object 的toString()方法
public String toString(){
return title+" "+duration;
}
}
public class TrackTest {
public static void main(String[] args) {
Duration da=new Duration(12345);
Track t=new Track("雪之光",da);
System.out.println(t); //输出雪之光03: 25: 45
}
}
6.String 类
(1)分割字符串split(String s) 根据给定正则表达式的匹配拆分此字符串。
String str1 ="1abc_9bcd_12df3_45se6";
String [] str1s= str1.split("_");
for(String st:str1s){
System.out.println(st); //返回1abc 9bcd 12df3 45se6
(2)取子串String substring(int beginIndex)
返回一个新的字符串,它是此字符串的一个子字符串。
该子字符串从指定索引处的字符开始,直到此字符串末尾
String substring(int beginIndex, int endIndex)
返回一个新字符串,它是此字符串的一个子字符串。
该子字符串从指定的beginIndex 处开始,直到索引endIndex - 1 处的字符,
该子字符串的长度为endIndex-beginIndex
String str1 ="1abc_9bcd_12df3_45se6";
String subStr1 = str1.substring(3,16);
System.out.println(subStr1); //返回c_9bcd_12df3_
(3)boolean contains(CharSequence s)
当且仅当此字符串包含指定的char 值序列时,返回true。
String str1 ="1abc_9bcd_12df3_45se6";
boolean bl = str1.contains("d");
(4)public int indexOf(String str)返回指定子字符串在此字符串中第一次出现处的索引。
如果字符串参数作为一个子字符串在此对象中出现,则返回第一个这种子字符串
的第一个字符的索引;
如果它不作为一个子字符串出现,则返回-1。
String str1 ="1abc_9bcd_12df3_45se6"
int index = str1.indexOf("d");
System.out.println(index); //返回8
(5) boolean equals(Object anObject)
将此字符串与指定的对象比较。
String s1 = new String("Hello");
String s2 = s1;
String s3 = new String("Hello");
System.out.println("s1.equals(s3):" + s1.equals(s3)); //true
(6)忽略大小写比较相等public boolean equalsIgnoreCase(String anotherString)
将此String 与另一个String 比较,不考虑大小写。如果两个字符串的长度相同,
并且其中的相应字符都相等(忽略大小写),则认为这两个字符串是相等的。
String code ="aBcD";
String myCode ="abcd";
if(code.equalsIgnoreCase(myCode)){
System.out.println("验证码正确"); //验证码正确
}
(7)char charAt(int index)
返回指定索引处的char 值。索引范围为从0 到length() - 1
String str1 ="1abc_9bcd_12df3_45se6";
char c= str1.charAt(3);
System.out.println(c); //返回c
(8)int compareTo(String anotherString)
按字典顺序比较两个字符串。
如果按字典顺序此String 对象位于参数字符串之前,则比较结果为一个负整数。
如果按字典顺序此String 对象位于参数字符串之后,则比较结果为一个正整数。如
果这两个字符串相等,则结果为0;
String str1 ="1abc_9bcd_12df3_45se6";
String str2 ="1abc_9bcd_12df3_45se6";
int j=str1.compareTo(str2);
System.out.println(j); //返回0
(9) String concat(String str)
将指定字符串连接到此字符串的结尾。
如果参数字符串的长度为0,则返回此String 对象。否则,创建一个新的String 对象,
用来表示由此String 对象表示的字符序列和参数字符串表示的字符序列连接而成的字
符序列。
String str3 ="1abf3_";
String str4 ="45se6";
String s=str3.concat(str4);
System.out.println(s); //返回1abf3_45se6
(10) boolean endsWith(String suffix)
测试此字符串是否以指定的后缀结束。
如果参数表示的字符序列是此对象表示的字符序列的后缀,则返回true;否则返回false。
注意,如果参数是空字符串,或者等于此String 对象(用equals(Object) 方法确定),
则结果为true。
String str4 ="45se6";
boolean b=str4.endsWith("se6");
System.out.println(b); //返回True
(11) String trim()
返回字符串的副本,忽略前导空白和尾部空白。
此字符串移除了前导和尾部空白的副本;如果没有前导和尾部空白,则返回此字符
串。
String str5 =" 1abf3_ ";
String s2=str5.trim();
System.out.println(s2);//返回1abf3_
7.StringBuilder 类
String 常量不可变
* 当程序频繁改变字符串不用使用String 的+运算
* 应该使用StringBuffer 线程安全的可变字符序列。一个类似于String 的字符串缓冲区
StringBuilder
* 一个可变的字符序列。此类提供一个与StringBuffer 兼容的API,
* 但不保证同步。该类被设计用作StringBuffer 的一个简易替换
String str3 = "abc";
//str3 = str3+"def"; 不可取
(1)StringBuffer append(StringBuffer sb) 将指定的StringBuffer 添加到此序列中。
String str3 = "abc";
StringBuffer buffer = new StringBuffer(str3);
buffer.append("def");
System.out.println(buffer.toString()); //abcdef
8.StringBuilder 类
(1)StringBuffer replace(int start, int end, String str) 用字符串str 代替start 和end 之间的字
符。
public class StringBuilderTest {
public static void main(String[] args) {
String str1="ashghgh_";
System.out.println(str1); //ashghgh_
StringBuilder sbt=new StringBuilder(str1);
StringBuilder sb=sbt.replace(1, 1, "12gyuopp");
System.out.println(sb); //a12gyuoppshghgh_
}
}
9.Date 类
public class DateTest {
public static void main(String[] args) {
//时间Date
Date d = new Date();
System.out.println(d);
//Calendar 日历提供更加强大的时间操作
//DateFormat 时间格式化抽象类子类SimpleDateFormat
//2011-07-26 10:33:36 时间格式化
SimpleDateFormat sdf = new SimpleDateFormat("yyyy 年MM 月dd 日");
String dStr = sdf.format(d);
System.out.println(dStr);
//"2011-07-26"
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");
try {
Date d2 = sdf2.parse("2011-07-26");
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
10.DateFormat 类:是抽象类,找子类SimpleDateFormat
(1) static DateFormat getDateInstance()
获取日期格式器,该格式器具有默认语言环境的默认格式化风格。
String dateString = "20110724";
try {
Date date= new Date();
SimpleDateFormat sdf3=SimpleDateFormat("yyyyMMdd");
System.out.println(sdf3.parse(dateString));
//下面将字符串转换为日期格式后显示的格式是2008-10-12
System.out.println(DateFormat.getDateInstance().format(date));
//如果想换一种别的格式,可以用下面的办法,得到任何的日期格式都可以
//输出的结果为2010/07/24
System.out.println(new SimpleDateFormat("yyyy/MM/dd").format(date));
//SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy 年MM 月dd 日");
//输出的结果为2011 年07 月24 日
System.out.println(new SimpleDateFormat("yyyy 年MM 月dd 日").format(date));
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
11.Math 类
(1)static int abs(int a) 返回int 值的绝对值。
int i=-12;
System.out.println(Math.abs(i)); //12
(2)static double ceil(double a)
返回最小的(最接近负无穷大)double 值,该值大于等于参数,并等于某个整数。
(会四舍五入)
double j=-124.32;
double h=234.56;
System.out.println(Math.ceil(j)); //-124.0
System.out.println(Math.ceil(h)); //235.0
(3) static double random()
返回带正号的double 值,该值大于等于0.0 且小于1.0。
System.out.println(Math.random()*10+1);//产生1-10 之间的随机数7.99223411269374
12.编程,产生随机数1-10 循环50 次,统计出现的数字及个数
public class RandomTest {
public static void main(String[] args) {
int A[] = new int[11];
for(int i=1;i<=50;i++){
int random = (int)(Math.random()*10+1);
for(int j=1;j<=10;j++){
if(random == j){
A[j] ++;
}
}
}
for(int i=1;i<=10;i++){
System.out.println("数字"+i+ "出现了:"+A[i]+"次");
}
}
}
结果:数字1 出现了:4 次
数字2 出现了:5 次
数字3 出现了:6 次
数字4 出现了:3 次
数字5 出现了:7 次
数字6 出现了:4 次
数字7 出现了:2 次
数字8 出现了:4 次
数字9 出现了:10 次
数字10 出现了:5 次
13.字符串String str ="asdfghjkl";编写程序将该字符串逆序输出
public class StringTest {
public static void main(String[] args) {
String str ="asdfghjkl";
char[] cs=str.toCharArray();
for(int i=cs.length-1;i>=0;i--){
System.out.print(cs[j]);
}
}
}
或:public class StringBufferTest {
public static void main(String[] args) {
String str ="asdfghjkl";
StringBuffer buffer = new StringBuffer(str);
buffer.reverse();
System.out.println(buffer);
}
}
14.原始类型对应的包装类型
八种原始类型对应都有各自的包装类型
包装类型作用:
*《1》类型转换比如String--->int String-->float
*《2》得到原始类型对应的类类型对象
实例:public class WrapperClass {
public static void main(String[] args) {
int i = 10;
//打包
Integer integer = new Integer(i);
String s = " 10 ";
String ss = s.trim();// "10"
//String--->int
//步骤1 String-->Integer--->int
Integer is = new Integer(s.trim());
int x = is.intValue();
//步骤2 String--->int
int y = Integer.parseInt(s.trim());
System.out.println(y);
//其他例如String ---》float
String s2 ="1.2";
float f = Float.parseFloat(s2);
/**
* 新特性自动打包和拆包
*/
//Integer is2 = new Integer(10);
Integer is2 =10;
int m = is2;
}
}
14.在第二题基础上, 将字符串封装为Track 对象并输出“唱片1, 390”
public class Duration {
private int hours;
private int minutes;
private int seconds;
public int getHours() {
return hours;
}
public void setHours(int hours) {
this.hours = hours;
}
public int getMinutes() {
return minutes;
}
public void setMinutes(int minutes) {
this.minutes = minutes;
}
public int getSeconds() {
return seconds;
}
public void setSeconds(int seconds) {
this.seconds = seconds;
}
public Duration(int hours, int minutes, int seconds) {
this.hours = hours;
this.minutes = minutes;
this.seconds = seconds;
}
public Duration(int total) {
this.seconds =total;
}
public String toString(){
return seconds+"";
}
}
public class Track {
private String title;
private Duration duration;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Duration getDuration() {
return duration;
}
public void setDuration(Duration duration) {
this.duration = duration;
}
public Track(String title, Duration duration) {
this.title = title;
this.duration = duration;
}
public Track(String title) {
super();
this.title = title;
}
public Track(Duration duration) {
super();
this.duration = duration;
}
public Track() {}
public String toString(){
return title+" "+duration;
}
}
public class TrackTest {
public static void main(String[] args) {
String str="唱片1, 390";
String [] s= str.split(",");
int y = Integer.parseInt(s[1].trim());
Duration d=new Duration(y);
Track t=new Track(s[0],d);
System.out.println(t);
}
}
输出:唱片1 390
15.System 类
(1)static long currentTimeMillis()
返回以毫秒为单位的当前时间。
当前时间与协调世界时1970 年1 月1 日午夜之间的时间差(以毫秒为单位测量)。
public class Test {
public static void main(String[] args) {
long now = System.currentTimeMillis();
System.out.println(now); //1311727788672
}
}
2011.7.27 周三
1.内部类:在一个类中声明另一个类(A 类中声明B 类,则B 是A 得内部类)
作用:(1)在A 中的成员变量,在B 方法中可以直接使用成员变量(方便访问类中的局部
变量和私有变量)
(2)避免类名命名冲突
(3)在图形界面编程中常使用
分类:成员内部类、静态内部类、局部内部类、匿名内部类
(1)静态内部类
* 内部类最简单的形式
* 不能和外部包围类使用相同名称
* 编译成独立的类, 外部类和内部类分开StaticOuterClass.class 和
StaticOuterClass$StaticInnerClass.class
* 只能访问外部类的静态成员或者方法,包括私有的
* 看成静态方法
* 静态内部类创建实例语法: 外部类.内部类变量= new 外部类.内部类();
实例:
public class StaticOuterClass {
private static int i = 10;//成员变量
private int b = 10;
public void a(){
i++;
System.out.println(i); //11
}
public static void b(){
//i++;
}
static class StaticInnerClass{ //静态内部类
private int i = 8;
public void a(){
int j=StaticOuterClass.i++; //访问外部的i 变量
System.out.println(j); //11
i++; //操作内部的i 变量
System.out.println(i); //9
}
}
}
public class StaticInnerClassTest {
public static void main(String[] args) {
StaticOuterClass outer = new StaticOuterClass(); //创建外部类对象
StaticOuterClass.StaticInnerClass inner = new StaticOuterClass.StaticInnerClass();
//创建静态内部类对象
outer.a();
inner.a();
}
}
(2)成员内部类和成员变量成员方法平级
* 不使用Static 修饰符在包围类中定义
* 像成员变量
* 可以访问包围外部类的所有成员
在内部类中访问包围类的成员的语法:Outerclass.this.member 外部类.this.外部类变量
在外部类创建成员内部类对象语法:外部类.内部类inner = new 外部类(). new 内部类();
实例:
public class MemberOuterClass {
private int i = 10;
public void a(){
this.i++;
System.out.println(i); //11
}
class MemberInnerClass{
private int i = 8;
public void innerA(){
i++; //自己的8
System.out.println(i); //9
//new MemberOuterClass().i++; 错误的
this.i++;//自己的8
System.out.println(i); //10
int j=MemberOuterClass.this.i++;//外部类当前对象外部类.this
System.out.println(j); //10
}
}
}
public class MemberInnerClassTest {
public static void main(String[] args) {
MemberOuterClass outer=new MemberOuterClass();
outer.a();
MemberOuterClass.MemberInnerClass inner =new MemberOuterClass().new
MemberInnerClass();
inner.innerA();
}
}
(3)局部内部类
*在方法内定义,甚至就是方法内的代码块
* 内部类中最不常用的形式
* 象局部变量,但不能声明成public,protected,private,static
* 只能访问final 的局部变量==》如果访问成员变量,可以直接方法
如果访问局部变量,局部变量必须是final 的常

实例:
public class LocalOuterClass {
private int i =10;
public void a(final int x){
//x++; //错误:x 是常量不能改变值
i++;
System.out.println(i); //11
final int b =8;//局部变量
class LocalInnerClass{
public void a(){
i++;//错误,不能访问非final 的常量
int y = b; //局部变量必须是final 的常量8
y = x; //传入的值
}
}
}
}
(4) 匿名内部类
* 局部内部的一种特殊形式
* 直接访问final 的局部变量
* 没有class 关键字没有类名
* 没有extends/implements 关键字
* 只用一次,必须指明变量初值
* 通常都是隐式的继承父类或实现接口
* 下面例子开发一个匿名内部类隐式的实现了Shape 接口
* 并且同时创建了一个匿名内部类对象,他的类型是Shape 类型的
* 匿名内部类:
优点:代码编写简单
缺点:很难理解
* 总结:
new 抽象父类/接口(){
大括号包含的就是匿名内部类
}
实例:
public interface Shape { //定义一个Shape 接口
public void area();
}
public class UseShape {
public void area(Shape s){
s.area();
}
public static void main(String[] args) {
UseShape us = new UseShape();
us.area(new Shape(){ //匿名内部类
private double r=3;
@Override
public void area() {
System.out.println("圆形面积:"+(Math.PI*r*r));
}
});
}
}
2.练习内部类的使
<1>编写Shape 接口,包含getArea()方法
<2>编写ShapeTest 类,该类中有方法getArea(Shape s){ s.getArea();}
main 方法中测试,调用该getArea(Shape s)方法,
要求传递参数s 的值对象是通过成员内部类、静态内部类、匿名内部类的对象
public interface Shape {
public void getArea();
} public class ShapeTest {
public void getArea(Shape s){
s.getArea();
}
//成员内部类
class Circle implements Shape{
private double r=7;
public void getArea() {
System.out.println("成员内部类:圆的面积是"+(int)Math.PI*r*r);
}
} //静




static class Recgiter implements Shape{
private double w=6;
private double l=6;
@Override
public void getArea() {
System.out.println("静态内部类:长方形的面积是"+w*l);
}
} public static void main(String[] args) {
ShapeTest st=new ShapeTest();
//匿名内部类
st.getArea(new Shape (){
private double r=5;
@Override
public void getArea() {
System.out.println("匿名内部类:圆的面积是"+(int)Math.PI*r*r);
} });
st.getArea(new ShapeTest2().new Circle());
st.getArea(new ShapeTest2.Recgiter());
}
} 3.比

2



(1)在Student 类中实现接口Comparable,重写compareTo 抽象方法
public int compareTo(Student o) {
return this.age-o.getAge();
}
在测试类中:
public Student min(Student s1,Student s2){
return s1.compareTo(s2)>0?s2:s1;
}
(2)直接在测试类中:匿名内部类
StudentTest st = new StudentTest();
Student s1 = new Student("zhangsan",20);
Student s2 = new Student("lisi",30);
class StudentComparator implements Comparator{
@Override
public int compare(Student o1, Student o2) {
return o1.getAge()-o2.getAge();
}
}
4.集合框架:一个集合就是可以并只能存放其它对象的特殊对象
Java 中实现集合功能需要实现三个元素
集合与数组的区别:
(1)数组定长,集合可变长
(2)数组只能存放一种类型,集合可以存放多种类型,只要是对象就可以
习惯:一个集合中只存放同一种类型对象
接口:定义每一种集合形式必须实现的方法
实现:具体的实际类如:Hashtable,Vector
算法:存储、获得以及操作集合众元素的方法
注意:Package java.util 在java.util 包中
集合接口框架:分为两类:Collection 接口和Map 接口(结构不同分) ,
其中Collection 接口分为List 接口和Set 接口(算法不同分),
Set 接口包含Sortedset,
Map 接口包含SortedMap 接口(Map 是Key,value 键字,key
不能重复作为主键,)
Set 不允许存放相同的对象(有相同的对象不添加)、元素是无序的。
Sortedset 和Set 类似,但在Set 集合众的元素是有序存储的。
List 元素是有序的,按照添加元素的顺序保持,删除元素时也保证元素是连续有序的,
并且允许存储重复的对象。
Map 通过唯一的主键和值的影射来存放对象、不允许有相同的主键。无序的,
有相同的Key,value 值会覆盖,value 可以重复,只能根据key 取value 值。
SortedMap 和Map 类似,但存放主键是默认按照升序的方式存放,借此保证对象的有序。
只按Key 排序
集合框架中类的层次关系:分为两类:Collection 下包含HashSet[Set]类和LinkedList、
Vector、ArrayList[List]
HashSet 下包含TreeSet[Sortedset];Hashtable 、HashMap[Map] 下包含
TreeMap[SortedMap].
5.开发一个最简单的集合练习类ListTest 练习使用ArrayList 集合对应的方式使用一下
Vector 和LinkedList 集合
import java.util.*;
import simple.Student;
public class ListTest {
public static void main(String[] args) {
//1 选择自己想用的集合创建对象
List list1= new ArrayList(); //ArrayList
List list2 = new Vector(); //Vector
List list3 = new LinkedList(); //LinkedList
//2.添加元素
list1.add("abc");
list1.add(123);
list1.add(12.9);
list1.add(new Student());
list2.add("abc");
list2.add(new ShapeTest());
list2.add(9.0);
list2.add(63);
list3.add("abc");
list3.add(new ShapeTest());
list3.add(9.0);
list3.add(63);
System.out.println(list1.get(0));
System.out.println(list1.size());
System.out.println(list2.get(1));
System.out.println(list2.size());
System.out.println(list3.get(2));
System.out.println(list3.size());
//取值
System.out.println(list1);
System.out.println(list2);
System.out.println(list3);
//取值
for(int i=0;i Object o1 = list1.get(i);
System.out.println(o1);
}
for(int j=0;j Object o2 = list2.get(j);
System.out.println(o2);
}
for(int k=0;k Object o3 = list3.get(k);
System.out.println(o3);
}
}
}
6.编写一个学生类Student
编写一个学生业务类StudentBO,
该类编写一个集合属性List students, setter getter 方法
编写一个方法添加学生方法,将一个学生添加到属性students 中
实现时要求集合存在相同的学生不添加,不存在相同的添加学生
编写一个StudentBOTest 类,测试添加学生方法
public class Student implements Comparable {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student(String name,int age) {
this.name = name;
this.age = age;
}
public Student() {}
public String toString(){
return name+ " "+age;
}
//按照学生年龄升序排列如果年龄相同按照名字降序
@Override
public int compareTo(Student o) {
if(this.age!=o.getAge()){
return this.age-o.getAge();
}else{
return -this.name.compareTo(o.getName());
}
}
@Override
public int hashCode() {
return this.name.hashCode()+this.age;
}
@Override
public boolean equals(Object obj) {
Student s = (Student)obj;
if(this.name.equals(s.getName())&&this.age==s.getAge())
return true;
return false;
}
}
import java.util.*;
public class StudentBO {
List students;
public List getStudents() {
return students;
}
public void setStudents(List students) {
this.students = students;
}
public StudentBO(List students) {
this.students = students;
}
public StudentBO() {}
public void addStudent(Student s){
if(!students.contains(s))
students.add(s);
}
public String toString(){
return students+ " ";
}
}
import java.util.*;
public class StudentBOTest {
public static void main(String[] args) {
Set set = new HashSet();
Student s1 = new Student("zhangsan",14);
Student s2 = new Student("lisi",21);
Student s3 = new Student("wangwu",22);
Student s4 = new Student("zhangsan",14);
Student s5 = new Student("gaoxing",43);
set.add(s1);
set.add(s2);
set.add(s3);
set.add(s4);
set.add(s5);
Iterator it= set.iterator();
while(it.hasNext()){
Student s=it.next();
System.out.println(s);
}
}
}
2011.7.28 周四
1.泛型:<类型> 只能放一种类型
2.注意导包时有多个包的情况:如Date 和List
3.ArrayList 练习:
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
public class ListTest {
public static void main(String[] args) {
//1 创建对象
List list = new ArrayList();
//2 添加元素(对象) add(E) 向列表的尾部添加指定的元素
list.add("abc");
list.add("abc");
list.add("www");
list.add("eee");
list.add("rrr");
/**
* add(int index, E element)
* 在列表的指定位置插入指定元素(可选操作)。
*/
list.add(3, "yyy");
/**
* remove(int index)移除列表中指定位置的元素(可选操作)。
* remove(Object o)移除列表中元素
*/
list.remove(3);
//3.取某一索引对象
System.out.println(list.get(3));
System.out.println(list.get(4));
//循环
for(String s:list){
System.out.println(s);
}
/**
* 集合迭代
* 获得该集合对应的迭代器对象Iterator
*/
Iterator it = list.iterator();
while(it.hasNext()){
String str = it.next();
if(str.equals("eee")){
/*
*循环迭代集合过程中删除元素,不要使用集合对象删除
*应该使用迭代器删除//list.remove(str);
*/
it.remove();
continue;
}
System.out.println(str);
}
/**
* 此时底层的指针指向最后一个元素next 已经没有元素
* java.util.NoSuchElementException
* String str2 = it.next();
*/
}
}
4.Vector 和LinkedList 练习
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Vector;
public class VectorTest {
public static void main(String[] args) {
Vector v = new Vector();
v.add(1);
v.add(1);
v.add(2);
v.add(3);
System.out.println(v.get(1));
v.remove(0);
v.size();
Iterator it = v.iterator();
while(it.hasNext()){
Integer i = it.next();
System.out.println(i);
}
LinkedList list = new LinkedList();
list.add("abc");
list.add("abc");
list.add("www");
list.add("eee");
list.add("rrr");
Iterator it2 = list.iterator();
while(it2.hasNext()){
String str = it2.next();
if(str.equals("eee")){
/*
*循环迭代集合过程中删除元素,不要使用集合对象删除
*应该使用迭代器删除
*/
//list.remove(str);
it2.remove();
continue;
}
System.out.println(str);
}
}
}
5.HashSet 练习
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class SetTest {
public static void main(String[] args) {
Set set = new HashSet();
String str1 =new String("abc"); //set 不会出现相同元素
String str2 =new String("abc");
set.add(str1);
set.add(str2);
set.add("sdf");
set.add("bsd");
set.add("3432");
set.add("rete");
set.add("243");
set.add("qwe");
set.add("asdsad");
System.out.println(set.size());//长度
* 取某一个元素没有无法根据索引位置取对象
* 因为set 集合无序,没有确定的索引位置
/**
* 集合无序,没有确定的索引只能删除对象
*/
set.remove("3432");
System.out.println(set.size());
Iterator it = set.iterator();//迭代
while(it.hasNext()){
String str = it.next();
System.out.println(str);
}
}
}
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class SetTest2 {
public static void main(String[] args) {
Set set = new HashSet();
/**
* Set 去除重复,如何判断两个对象相等?
* 不是由equals() 而是hashCode 码
* 所以我们需要重新类的hashCode()方法
*/
Student s1 = new Student("zhangsan",20);
Student s2 = new Student("zhangsan",20);
Student s3 = new Student("lisi",22);
Student s4 = new Student("wangwu",20);
set.add(s1);
set.add(s2);
set.add(s3);
set.add(s4);
Iterator it = set.iterator();//迭代
while(it.hasNext()){
Student stu = it.next();
System.out.println(stu);
}
}
}
6.TreeSetT 练习
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;
public class TreeSetTest {
public static void main(String[] args) {
TreeSet set = new TreeSet();
/**
* 不允许重复排序功能默认升序
*/
set.add(5);
set.add(5);
set.add(2);
set.add(7);
set.add(0);
Iterator it = set.iterator();
while(it.hasNext()){
Integer i = it.next();
System.out.println(i);
}
TreeSet set2 = new TreeSet();
Student s1 = new Student("zhangsan",20);
Student s2 = new Student("zhangsan",20);
Student s3 = new Student("lisi",22);
Student s4 = new Student("wangwu",20);
set2.add(s1);
set2.add(s2);
set2.add(s3);
set2.add(s4);
Iterator it2 = set2.iterator();
while(it2.hasNext()){
Student stu = it2.next();
System.out.println(stu);
}
}
}
注意: TreeSet 比较对象大小进行排序两种方法:
《1》放入的对象对应的类实现Comparable 接口,让对象自身具有比较功能
当我们使用TreeSet 时,判断对象相等就不是hashCode 而是比较大小时compareTo()
返回0 就认为是相等对象
public class Student implements Comparable{
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Student(){}
@Override
public String toString() {
return this.name+" "+this.age;
}
@Override
public boolean equals(Object obj) {
Student s = (Student)obj;
if(this.name.equals(s.getName())&&this.age==s.getAge())
return true;
return false;
}
@Override
public int hashCode() {
return this.name.hashCode()+this.age;
}
// 按照学生年龄升序排列如果年龄相同按照名字降序
// 小心返回值0
/*@Override
public int compareTo(Student o) {
if(this.age!=o.getAge()){
return this.age-o.getAge();
}else{
return -this.name.compareTo(o.getName());
}
}
}
《2》放入的对象对应类不需要实现Comparable 接口,我们创建TreeSet 集合时,使用
TreeSet(Comparator comparator)构造方法,让集合本身具有比较器,进行添加元
素的比较大小
TreeSet set2 = new TreeSet(new Comparator(){
@Override
public int compare(Student o1, Student o2) {
if(o1.getAge()!=o2.getAge()){
return o1.getAge()-o2.getAge();
}else{
return -o1.getName().compareTo(o2.getName());
}
}
});
Student s1 = new Student("zhangsan",20);
Student s2 = new Student("zhangsan",20);
Student s3 = new Student("lisi",22);
Student s4 = new Student("wangwu",20);
set2.add(s1);
set2.add(s2);
set2.add(s3);
set2.add(s4);
Iterator it2 = set2.iterator();
while(it2.hasNext()){
Student stu = it2.next();
System.out.println(stu);
}
}
}
7.HashMap 练习
import java.util.*;
public class MapTest {
public static void main(String[] args) {
//创建对象
HashMap map = new HashMap();
* 添加元素put(E key , E value)
* map 中添加元素key 唯一如果出现相同,后放入的value 会覆盖先放入的
map.put(1, "1");
map.put(1, "111");
map.put(3, "333");
map.put(6, "666");
map.put(2, "222");
System.out.println(map.size());//获得集合长度
/**
* 取元素根据key 获取value value get(E key)
*/
String str = map.get(3);
System.out.println(str);
/**
* 删除元素remove(E key)
*/
map.remove(1);
/**
* 如果get(E key) 传入的key 不存在呢?不会抛异常,返回null
*/
String str2 = map.get(1);
System.out.println(str2);
/**
* map 清空clear()
* 判断集合中是否有数据?
* 《1》先判断集合对象是否==null
* 《2》如果集合!=null, 判断.size()>0
map.clear();
System.out.println(map.size());
if(map.size()<=0){
System.out.println("没有东西");
}else{
System.out.println("有东西");
}
* boolean containsKey(key)
* 判断集合中是否存在相应的key
* 如果存在返回true
* 否则返回false
if(!map.containsKey(1)){
map.put(1, "111");
}
}
}
import java.util.*;
public class MapTest2 {
public static void main(String[] args) {
HashMap map = new HashMap();
map.put(1, "1");
map.put(1, "111");
map.put(3, "333");
map.put(6, "666");
map.put(2, "222");
/**
* map 如何迭代? map 本身没有迭代器,实现相对麻烦
* 实现方式三种
* 《1》获得所有的value 集合
* Collection values()返回此映射中包含的值的Collection 视图
* 优点:最简单
* 缺点:无法获得key
Collection coll = map.values();
Iterator it = coll.iterator();
while(it.hasNext()){
String value = it.next();
System.out.println(value);
}
/**
* 《2》获得所有的key 的集合然后迭代,分别取value
* Set keySet()返回此映射中包含的键的Set 视图
* key 和value 都可以获得
*/
Set keys = map.keySet();
Iterator it = keys.iterator();
while(it.hasNext()){
Integer key = it.next();
String value = map.get(key);
System.out.println("key:"+key+" value:"+value);
}
/**
* 《3》可以获得key-value 键值对的集合
* key-value--->Map.Entry
* Set> entrySet()返回此映射中包含的映射关系的Set 视图
Set> entrys = map.entrySet();
Iterator > it = entrys.iterator();
while(it.hasNext()){
Map.Entry entry= it.next();
Integer key = entry.getKey();
String value = entry.getValue();
System.out.println("key:"+key+" value:"+value);
}
}
}
8.重点是TreeSet 排序的实现TreeSet(Comparator comparator) 采用静态、成员、匿名三
种内部类实现
import java.util.*;
public class TreeSetTest {
//静态内部类
static class MComparator implements Comparator{
@Override
public int compare(Student arg0, Student arg1) {
if(!(arg0.getAge()==(arg1.getAge())))
return arg0.getAge()-arg1.getAge();
else
return arg0.getSName().compareTo(arg1.getSName());
}
}
//成员内部类
public class MyCom implements Comparator{
@Override
public int compare(Student arg0, Student arg1) {
if(!(arg0.getAge()==(arg1.getAge())))
return arg0.getAge()-arg1.getAge();
else
return arg0.getSName().compareTo(arg1.getSName());
}
}
public static void main(String[] args) {
//TreeSet 排序的实现--匿名内部类
Student s1=new Student(" 张三",12);
Student s2=new Student(" 历史",43);
Student s3=new Student(" 玩个",32);
Student s4=new Student(" 张三",54);
TreeSet ts=new TreeSet(new Comparator(){
@Override
public int compare(Student arg0, Student arg1) {
if(!(arg0.getAge()==(arg1.getAge())))
return arg0.getAge()-arg1.getAge();
else
return arg0.getSName().compareTo(arg1.getSName());
}
});
ts.add(s4);
ts.add(s3);
ts.add(s2);
ts.add(s1);
Iterator it5 =ts.iterator();
while(it5.hasNext()){
Student s11 = it5.next();
System.out.println(s11);
}
//TreeSet 排序的实现--静态内部类
TreeSet ts1=new TreeSet(new ListTest.MComparator());
ts1.add(s4);
ts1.add(s3);
ts1.add(s2);
ts1.add(s1);
Iterator it6 =ts1.iterator();
while(it6.hasNext()){
Student s11 = it6.next();
System.out.println(s11);
}
//TreeSet 排序的实现--成员内部类
TreeSet ts2=new TreeSet(new ListTest().new MyCom());
ts2.add(s1);
ts2.add(s4);
ts2.add(s3);
ts2.add(s2);
ts2.add(s1);
Iterator it7 =ts1.iterator();
while(it7.hasNext()){
Student s11 = it7.next();
System.out.println(s11);
}
}
}
public class Student {
private String sName;
private int age;
public String getSName() {
return sName;
}
public void setSName(String name) {
sName = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student(String name, int age) {
super();
sName = name;
this.age = age;
}
public Student() {}
@Override
public String toString() {
return "学生姓名:"+sName+" 年龄:"+age;
}
}
9.编写
时间Duration 类:int hours ; int minutes; int seconds;
歌曲Track 类:String title ; Duration duration
CD 抽象类Recording:String title;double price;String category;String imageName;
音乐专辑MusicRecording extends Recording
String singer;Vector tracks;
合理编写每个类的属性对应的setter 和getter 方法
类的构造方法toString 方法
编写SuperVCDTest 测试类测试这些类是否正确
public class Duration {
private int hours;
private int minutes;
private int seconds;
public Duration(int hours,int minutes){
this.hours=hours;
this.minutes=minutes;
}
public Duration(int seconds){
this.hours=seconds / 3600;
this.minutes=seconds % 3600 / 60;
this.seconds=seconds % 60;
}
public Duration(){}
public void setHours(int hours){
this.hours=hours;
}
public void setMinutes(int minutes){
this.minutes=minutes;
}
public void setSeconds(int seconds){
this.seconds=seconds;
}
public int getHours(){
return hours;
}
public int getMinutes(){
return minutes;
}
public int getSeconds(){
return seconds;
}
//格式转化
public String format(int x){
String y;
if(x<10){
return y="0"+x;
}
else{
return y=x+"";
}
}
//重写toString 方法,使得时间输出格式是hh:mm:ss
public String toString(){
if(this.hours==0){
return format(minutes)+":"+this.seconds;
}
else{
return format(this.hours)+":"+format(this.minutes)+":"+this.seconds;
}
}
//把时间转化成秒数,以便计算
public int toSeconds(){
return hours*3600+minutes*60+seconds;
}
//两个时间相加
public Duration Durationadd(Duration d1){
int t=this.toSeconds()+d1.toSeconds();
return new Duration(t);
}
//两个时间相减
public Duration Durationdec(Duration d2){
int t=Math.abs(this.toSeconds()-d2.toSeconds());
return new Duration(t);
}
}
public class Track {
private String title;
private Duration d;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Duration getD() {
return d;
}
public void setD(Duration d) {
this.d = d;
}
public Track() {}
public Track(String title, Duration d) {
super();
this.title = title;
this.d = d;
}
public String toString(){
return "歌曲名: "+title+" 时长: "+d+"\n";
}
}
public class Recording {
private String title;
private double price;
private String category;
private String imageName;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getImageName() {
return imageName;
}
public void setImageName(String imageName) {
this.imageName = imageName;
}
public Recording(String title, double price, String category,
String imageName) {
super();
this.title = title;
this.price = price;
this.category = category;
this.imageName = imageName;
}
public Recording() {}
@Override
public String toString() {
return "专辑名:"+title+" 价格:"+price+" 地区:"+category+" 图片名:"+imageName;
}
}
import java.util.*;
public class MusicRecoding extends Recording {
private String singer;
private Vector tracks;
public String getSinger() {
return singer;
}
public void setSinger(String singer) {
this.singer = singer;
}
public Vector getTracks() {
return tracks;
}
public void setTracks(Vector tracks) {
this.tracks = tracks;
}
public MusicRecoding(String title, double price, String category,
String imageName, String singer, Vector tracks) {
super(title, price, category, imageName);
this.singer = singer;
this.tracks = tracks;
}
public MusicRecoding(String title, double price, String category,
String imageName) {}
@Override
public String toString() {
return super.toString()+" 歌手:"+singer+" "+tracks.size()+"\n"+tracks;
}
}
import java.util.Iterator;
import java.util.Vector;
public class SuperVCDTest {
public static void main(String[] args) {
Track t1=new Track("很受伤",new Duration(1423));
Track t2=new Track("不是我",new Duration(253));
Track t3=new Track("就是你",new Duration(644));
Track t4=new Track("爱大了",new Duration(234));
Track t5=new Track("寂寞哥",new Duration(2343));
Track t6=new Track("可惜不是你",new Duration(625));
Track t7=new Track("其实我很在乎你",new Duration(456));
Track t8=new Track("未来的你",new Duration(987));
Vector tracks=new Vector();
tracks.add(t1);
tracks.add(t2);
tracks.add(t3);
tracks.add(t4);
tracks.add(t5);
tracks.add(t6);
tracks.add(t7);
tracks.add(t8);
tracks.size();
MusicRecording mr=new MusicRecording("专辑1",35.12,"大陆地区","小刚.jpg","成
龙",tracks);
System.out.println(mr);
}
}
10.阅读ShoppingCart 类,改进功能方法并编写测试类测试
public class Book {
private String name;
private double price;
private String author;
private int quantity;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
public Book(String name, double price, String author, int quantity) {
this.name = name;
this.price = price;
this.author = author;
this.quantity = quantity;
}
public Book(){}
@Override
public String toString() {
return this.name+" "+this.price+" "+this.author+" "+this.quantity;
}
}
import java.util.*;
public class ShoppingCart {
private Map cart;
public Map getCart() {
return cart;
}
public void setCart(Map cart) {
this.cart = cart;
}
public ShoppingCart(){
cart = new HashMap();
}
/**
* 购物车功能方法
* 添加商品方法
* 改进: 添加时,如果商品存在,数量+1
* 不存在,添加商品,数量为1
*/
public void addBook(Book b){
Set keyset=cart.keySet();
Iterator it=keyset.iterator();
while(it.hasNext()){
String str=it.next();
int i=b.getQuantity();
if(str.equals(b.getName())){
b.setQuantity(i++);
}
else{
i=1;
cart.put(b.getName(), b);
}
}
}
/**
* 删除商品
* 改进: 删除时,如果数量》1 数量-1
* 如果数量=1 删除商品
*/
public void delBook(String name){
Book b=cart.get(name);
int i=b.getQuantity();
if(i==1)
cart.remove(name);
else
{
i-=1;
b.setQuantity(i);
}
}
/**
* 清空购物车
*/
public void clearCart(){
cart.clear();
}
/**
* 获得总价
* 每本书price*quantity 累加
*/
public double totalPrice(){
Collection book=cart.values();
Iterator it=book.iterator();
double t=0;
while(it.hasNext()){
Book b=it.next();
t+=b.getPrice()*b.getQuantity();
}
return t;
}
}
import java.util.*;
public class ShoppingCartTest {
public static void main(String[] args) {
Book b1=new Book("C 语言",27.6,"三毛",1);
Book b2=new Book("JAVA 面向对象程序设计",45.9,"耿祥义",39);
Book b3=new Book("很纯很暧昧",71,"老鱼",6);
Map cart=new HashMap();
cart.put(b1.getName(), b1);
cart.put(b2.getName(), b2);
cart.put(b3.getName(), b3);
cart.put(b4.getName(), b4);
Set> entrys= cart.entrySet();
Iterator> it=entrys.iterator();
while(it.hasNext()){
Map.Entry entry=it.next();
String key=entry.getKey();
Book value=entry.getValue();
System.out.println(key+ " " +value);
}
}
}
集合接口:
t
集合类:
Collection
Set List Map
SortedSet SortedMap
Collection
HashSet
(Set)
LinkedList
Vector,ArrayList
(List)
Hashtable
Hashmap
(Map)
TreeSet
(SortedSet)
TreeMap
(SortedMap)
2011.7.29 周五
1.类的反射:
确定一个对象的类
可以获得类的修饰符、属性、字段、方法、构造方法以及父类
找出一个属于一个接口的常量和在接口中声明的方法
在没有运行之前可以创建一个类的未知名称的对象
在没有运行之前,可以给未知属性设置值和得到该属性的值,叫动态访问
在没有运行之前,可以访问未知名称的方法并调用它,叫动态调用。
在没有运行之前,可以创建一个尺寸和类型都未知的数组,在运行的时候,动态修改数组的
组件。
Java 反射机制实例类:
Class: 每个类在JVM 中都拥有一个对应的java.lang.Class 对象,它提供了类结构信息的描
述。
Class 反射对象描述类的结构信息,所以我们可以从Class 对象中获取这些信息,
比如:
构造方法、成员变量、方法等元素的反射对象,并以编程的方式通过这些反射对象对目标
类对象进行操作。这些反射对象类在java.reflect 包中定义。
Constructor:类的构造方法的反射对象。可以通过Class#getDeclaredConstructors()方法获取
类的所有构造方法反射对象数组Constructor[] 。还可以通过
Class#getDeclaredConstructor(Class...parameterTypes)获取指定特定参数的构造方法反射对
象。Constructor 的一个主要方法是newInstance(Object... initargs),通过该方法可以创建一个对
象类的实例,相当于new 关键字作用。
Method:类方法的反射类。通过Class#getDeclaredMethods()方法可以获得类的所有方法反射
类对象数组Method[].
可以通过getDeclaredMethod(String name,Class... parameterTypes)获取特定的方法,name 为
方法名,Class...为方法参数类型列表。
Method 有个主要的方法invoke(Object obj,Object... args),obj 表示操作的目标对象,args 为设
置参数
此外还有其他方法:Class getReturnType()获取方法返回类型方法
Class[] getParameterTypes():获取方法参数类型数组方法。
Class[] getExceptionTypes():获取方法异常类型数组方法。
Field:类成员变量的反射类。通过Class#getDeclearedFields()方法可以获得类的成员变量反射
类对象数组。
通过Class#getDeclearedField(String name)可以获得某个特定名称的成员变量对应的反射对
象。
Field 类主要的方法是set(Object obj,Object value),obj 表示操作的目标对象,value 为给目标对
象obj 付的值。如果成员变量为原始类型,可以通过提供的带类型名的方法,
例如:setBoolean(Object obj,boolean value) setInt(Object obj,int value)
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ReflectTest1 {
public static void main(String[] args) {
//Student.class
Class classType = null;
if(args.length<1){
System.out.println("请在运行时输入参数");
}else{
try {
classType = Class.forName(args[0]);
/**
* 获得类定义的属性
*/
Field [] fields = classType.getDeclaredFields();
System.out.println("类定义的属性为:");
for(int i=0;i System.out.println(fields[i]);
}
//获得类的定义的所有方法
Method []methods = classType.getDeclaredMethods();
System.out.println("类定义的方法为:");
for(int i=0;i System.out.println(methods[i]);
}
//获得类定义的构造方法
Constructor[] constructors =classType.getDeclaredConstructors();
System.out.println("类定义的构造方法为:");
for(int i=0;i System.out.println(constructors[i]);
}
} catch (ClassNotFoundException e) {
//e.printStackTrace();
System.out.println("您输入的类没有,请重新输入");
}
}
}
}
public class ReflectTest2 {
public static void main(String[] args) throws Exception {
//根据当前类的线程获得类的加载器
ClassLoader loader = Thread.currentThread().getContextClassLoader();
//使用类加载器根据类名加载该类的反射类Class
Class clazz =loader.loadClass("sample.Student");
//获取类的一个指定构造方法方法中可以不写参数或null 来指明无参数
Constructor cons = clazz.getDeclaredConstructor(String.class,int.class);
//Constructor cons = clazz.getDeclaredConstructor(null);
//使用构造方法的反射类间接的构造一个对象方法中可以不写参数或null 来指
明无参数
Student stu =(Student) cons.newInstance("zhangsan",20);
//Student stu =(Student) cons.newInstance(null);
System.out.println(stu);
/*//获得方法的反射对象
Method setName = clazz.getDeclaredMethod("setName", String.class);
//间接的执行目标对象的方法
setName.invoke(stu, "lisi"); //等价于stu.setName("lisi");
Method setAge = clazz.getDeclaredMethod("setAge", int.class);
setAge.invoke(stu, 30);//等价于stu.setAge(30);
System.out.println(stu);*/
}
}
* Java 反射机制实例类
* 我们可以使用java 反射机制,间接的操作类的对象,并可以提供间接的访问私有及保护
的成员变量和方法
public class ReflectTest3 {
public static void main(String[] args) throws Exception {
//根据当前类的线程获得类的加载器
ClassLoader loader = Thread.currentThread().getContextClassLoader();
//使用类加载器根据类名加载该类的反射类Class
Class clazz =loader.loadClass("sample.Student");
//获取类的一个指定构造方法方法中可以不写参数或null 来指明无参数
//Constructor cons = clazz.getDeclaredConstructor(String.class,int.class);
Constructor cons = clazz.getDeclaredConstructor(null);
//使用构造方法的反射类间接的构造一个对象方法中可以不写参数或null 来指
明无参数
//Student stu =(Student) cons.newInstance("zhangsan",20);
Student stu =(Student) cons.newInstance(null);
//获得对应属性变量的反射对象
Field nameField = clazz.getDeclaredField("name");
Field ageField = clazz.getDeclaredField("age");
//清除java 语言访问检查以访问私有的变量
nameField.setAccessible(true);
ageField.setAccessible(true);
//以访问目标对象stu 私有变量方式给私有变量赋值
nameField.set(stu, "zhangsan");//等价于stu.name ="zhangsan";
ageField.setInt(stu, 30);//等价于stu.age =30;
//获得print 方法的反射对象null 代表方法无参数null 可以省略
Method printMethod = clazz.getDeclaredMethod("print",null);
//设置清除java 语言检查以访问私有的方法
printMethod.setAccessible(true);
//使用反射机制间接执行目标对象stu 的print 方法null 代表方法无参数,可以省略
printMethod.invoke(stu,null);//等价于stu.print();
}
}
2.正则表达式:
java.util.regex
类Pattern
指定为字符串的正则表达式必须首先被编译为此类的实例。然后,可将得到的模式用于创建
Matcher 对象,依照正则表达式,该对象可以与任意字符序列匹配。
执行匹配所涉及的所有状态都驻留在匹配器中,所以多个匹配器可以共享同一模式。
x 字符x
\\ 反斜线字符
\0n 带有八进制值0 的字符n (0 <= n <= 7)
\0nn 带有八进制值0 的字符nn (0 <= n <= 7)
\0mnn 带有八进制值0 的字符mnn(0 <= m <= 3、0 <= n <= 7)
\xhh 带有十六进制值0x 的字符hh
\uhhhh 带有十六进制值0x 的字符hhhh
\t 制表符('\u0009')
\n 新行(换行)符('\u000A')
\r 回车符('\u000D')
\f 换页符('\u000C')
\a 报警(bell) 符('\u0007')
\e 转义符('\u001B')
\cx 对应于x 的控制符
字符类
[abc] a、b 或c(简单类)
[^abc] 任何字符,除了a、b 或c(否定)
[a-zA-Z] a 到z 或A 到Z,两头的字母包括在内(范围)
[a-d[m-p]] a 到d 或m 到p:[a-dm-p](并集)
[a-z&&[def]] d、e 或f(交集)
[a-z&&[^bc]] a 到z,除了b 和c:[ad-z](减去)
[a-z&&[^m-p]] a 到z,而非m 到p:[a-lq-z](减去)
预定义字符类
. 任何字符(与行结束符可能匹配也可能不匹配)
\d 数字:[0-9]
\D 非数字: [^0-9]
\s 空白字符:[ \t\n\x0B\f\r]
\S 非空白字符:[^\s]
\w 单词字符:[a-zA-Z_0-9]
\W 非单词字符:[^\w]
边界匹配器
^ 行的开头
$ 行的结尾
\b 单词边界
\B 非单词边界
\A 输入的开头
\G 上一个匹配的结尾
\Z 输入的结尾,仅用于最后的结束符(如果有的话)
\z 输入的结尾
Greedy 数量词
X? X,一次或一次也没有
X* X,零次或多次
X+ X,一次或多次
X{n} X,恰好n 次
X{n,} X,至少n 次
X{n,m} X,至少n 次,但是不超过m 次
Reluctant 数量词
X?? X,一次或一次也没有
X*? X,零次或多次
X+? X,一次或多次
X{n}? X,恰好n 次
X{n,}? X,至少n 次
X{n,m}? X,至少n 次,但是不超过m 次
Possessive 数量词
X?+ X,一次或一次也没有
X*+ X,零次或多次
X++ X,一次或多次
X{n}+ X,恰好n 次
X{n,}+ X,至少n 次
X{n,m}+ X,至少n 次,但是不超过m 次
反斜线字符('\') 用于引用转义构造,同时还用于引用其他将被解释为非转义构造的字符。
因此,表达式\\ 与单个反斜线匹配,而\{ 与左括号匹配。
(1)matches public static boolean matches(String regex,CharSequence input)编译给定正则表
达式并尝试将给定输入与其匹配。
(2)split public String[] split(CharSequence input,int limit)围绕此模式的匹配拆分给定输
入序列。
如果限制n 大于零,那么模式至多应用n> - 1 次,数组的长度不大于n,并且数
组的最后条目将包含除最后的匹配定界符之外的所有输入。
如果n 非正,那么将应用模式的次数不受限制,并且数组可以为任意长度。
如果n 为零,那么应用模式的次数不受限制,数组可以为任意长度,并且将丢弃尾
部空字符串。
例如,输入"boo:and:foo" 将产生以下结果及参数:
Regex Limit Result
: 2 { "boo", "and:foo" }
: 5 { "boo", "and", "foo" }
: -2 { "boo", "and", "foo" }
o 5 { "b", "", ":and:f", "", "" }
o -2 { "b", "", ":and:f", "", "" }
o 0 { "b", "", ":and:f" }
(3)split public String[] split(CharSequence input)围绕此模式的匹配拆分给定输入序列。
得到的数组中不包括尾部空字符串。
例如,输入"boo:and:foo" 将产生以下结果及表达式:
Regex Result
: { "boo", "and", "foo" }
o { "b", "", ":and:f" }
实例:
public class Reg1 {
public static void main(String[] args) {
/**
* 判断字符串都有数字组成
*/
String str ="123a567890";
char[] chs = str.toCharArray();
boolean flag = true;//是否完全是数字组成的标志true 是false 不是
for(int i=0;i if(!(chs[i]>='0'&&chs[i]<='9')){
flag = false;
break;
}
}
if(flag)
System.out.println("该字符串完全有数字组成");
else
System.out.println("该字符串不是完全有数字组成");
/**
* 使用正则表达式
* \\d+ 就是“正则表达式”
* \d 数字:[0-9]
*/
if(str.matches("\\d+")){
System.out.println("字符串是全部由数字组成");
}else{
System.out.println("字符串不是全部由数字组成");
}
/**
* 字符串使用正则表达式的应用场合:
* 《1》比较字符串是否匹配某个规则
boolean matches(String regex)
* 《2》按照某规则切割字符串
String[] split(String regex)
* 《3》按照某规则替换字符串
String replace(CharSequence target, CharSequence replacement)
String replaceAll(String regex, String replacement)
String replaceFirst(String regex, String replacement)
*/
String str2 ="a1bb222cccc34";
//a bb - cccc
String [] str2s = str2.split("\\d",0);
System.out.println(str2s.length);
for(String s:str2s){
System.out.println(s+"&");
}
}
}
public class Reg2 {
public static void main(String[] args) {
/**
* 思考实例:
《1》验证如下格式xxx-xx-xxxx x 代表数字,正则表达式?
\\d{3}-\\d{2}-\\d{4}
《2》验证字符串是字符、数字、_ 组成,首个为字母,正则表达式?
[a-zA-Z]{1}\\w+
《3》验证字符串格式为email, 正则表达式?
正则:\\w+@\\w+.\\w+
《4》验证字符串格式为手机号,要求13xxxxxxxxx 或15xxxxxxxxx,正则表达式?
《5》给定一个ip 地址例如192.168.20.100,完成按照.分割字符,然后获得数字的
和?
*/
String ip ="192.168.20.100";
String []ips = ip.split("\\.");//容易出错
int result = 0;
for(String s:ips){
result+= Integer.parseInt(s);
}
System.out.println(result);
}
}
3.异常:
java.lang
类Exception
结构如下:
* try{
异常源
------ 第一行出现异常后面不会执行直接进入catch 从而改变代码流程
------
* }catch(异常类型){
发生异常,捕获后处理代码
}
* finally{
最终代码一定会执行的代码块
}
* 出现异常后就会改变正常的程序流程
* 异常处理try catch finally 可以嵌套
* 还可以一个try 多个catch,
* 但是注意:多个catch 必须从小到大如果异常类型没有大小关系,上下无所谓
* 通常的习惯是:上面写具体的异常类型,最后放一个Exception
public class Exception1 {
public static int div(int a,int b){
int result = 0;
try{
result = a/b;
}catch(ArithmeticException e){
//e.getMessage()获得异常信息
System.out.println("发生了异常:"+e.getMessage());
//e.printStackTrace();//打印异常栈轨迹
result = -1;
return result;
//会先检查有没有finally 如果有先执行完finally,再返回来执行return
}finally{
System.out.println("finally 一定执行");
}
return result;
}
public static void main(String[] args) {
int result = Exception1.div(10, 0);
System.out.println(result);
}
}
public class Exception2 {
public static int div(int a,int b) throws Exception{
int result = 0;
try{
result = a/b;
}catch(NullPointerException e){
}catch(ArithmeticException e){
//如果发生异常我们不处理,就要往外抛异常
//在catch 中抛异常,通常是throw 异常对象
throw new Exception();
//如果处理时抛的是受查型异常必须处理或者方法定义上使用
//throws 异常类型, 将来谁调用该方法,就处理异常
}catch (Exception e){
}
finally{
System.out.println("finally 一定执行");
}
return result;
}
public static void main(String[] args) throws Exception {
int result=0;
result = Exception2.div(10, 0);
System.out.println(result);
}
常见异常:
(1)类ClassNotFoundException 当应用程序试图使用以下方法通过字符串名加载类
时,抛出该异常:
(2)类DataFormatException 当数据格式发生错误时,抛出此异常。
(3)类InstantiationException 当应用程序试图使用Class 类中的newInstance 方法创
建一个类的实例,而指定的类对象无法被实例化时,抛出该异常。
实例化失败有很多原因,包括但不仅限于以下原因:
类对象表示一个抽象类、接口、数组类、基本类型、void
类没有非null 构造方法
(4)类NoSuchAttributeException 尝试访问不存在的属性时,抛出此异常。
(5)类NoSuchMethodException 无法找到某一特定方法时,抛出该异常。
(6)类SQLException 提供关于数据库访问错误或其他错误信息的异常。
(7)类TransformerException 此类指定了转换过程中发生的异常条件。
(8)类RuntimeException 那些可能在Java 虚拟机正常运行期间抛出的异常的超类。
可能在执行方法期间抛出但未被捕获的RuntimeException 的任何子类都无需在
throws 子句中进行声明
运行时异常包含:
(a)类ArithmeticException 当出现异常的运算条件时,抛出此异常。例如,一个
整数“除以零”时,抛出此类的一个实例。
(b)类ArrayStoreException 试图将错误类型的对象存储到一个对象数组时抛出的异常
(c)类ClassCastException 当试图将对象强制转换为不是实例的子类时,抛出该异常。
(d)类EmptyStackException 该异常由Stack 类中的方法抛出,以表明堆栈为空。
(e)类IllegalArgumentException 抛出的异常表明向方法传递了一个不合法或不正确的参
数。
(f)类IndexOutOfBoundsException 指示某排序索引(例如对数组、字符串或向量的排序)
超出范围时抛出。
越界异常包含:
类ArrayIndexOutOfBoundsException 用非法索引访问数组时抛出的异常。如果索引为
负或大于等于数组大小,则该索引为非法索引。
类StringIndexOutOfBoundsException 此异常由String 方法抛出,指示索引或者为负,
或者超出字符串的大小。
对诸如charAt 的一些方法,当索引等于字符串的大小时,也会抛出该异常。
(g)类JMRuntimeException 由JMX 实现所发出的运行时异常。
(h)类NegativeArraySizeException 如果应用程序试图创建大小为负的数组,则抛出该异
常。
(i)类NullPointerException 当应用程序试图在需要对象的地方使用null 时,抛出该
异常。
这种情况包括:
调用null 对象的实例方法。
访问或修改null 对象的字段。
将null 作为一个数组,获得其长度。
将null 作为一个数组,访问或修改其时间片。
将null 作为Throwable 值抛出。
应用程序应该抛出该类的实例,指示其他对null 对象的非法使用。
(j) 类SystemException SystemException 扩展了java.lang.RuntimeException,
考题:异常(Exception )和错误(Error)区别:
exception 表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会
发生的情况。
error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不
可能指望程序能处理这样的情况
考题:final、finally{}、finalize()区别:
Final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
内部类要访问局部变量,局部变量必须定义成final 类型,
finally 是异常处理语句结构的一部分,表示一定会执行。
finalize 是Object 类的一个方法,当垃圾回收器确定不存在对该对象的更多引用时,由
对象的垃圾回收器调用此方法。子类重写finalize 方法,以配置系统资源或执行其他清除。
考题:throw 和throws 区别
throw 通常在代码中抛异常对象
throws 是在方法定义后抛异常类型
当一个方法抛出了受查型异常,必须捕获或者方法往外throws 异常类型
考题:请写出你最常见到的5 个runtime exception。
NullPointerException 、ArrayIndexOutOfBoundsException 、ClassCastException 、
ArithmeticException、SystemException
考题:运行时异常与一般异常有何异同?
异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作
中可能遇到的异常,是一种常见运行错误。
java 编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明
抛出未被捕获的运行时异常。
4..开发supervcd 项目
开发一个DataAccess 类
编写一个方法使用Map 封装多个专辑
DataAccess 类中增加一个根据地区类别查询专辑方法
测试类测试
import java.util.*;
public class DataAccess {
protected HashMap map;
public HashMap getMap() {
return map;
}
public void setMap(HashMap map) {
this.map = map;
}
public DataAccess(HashMap map) {
super();
this.map = map;
}
public DataAccess(){
map=new HashMap();
}
public HashMap getMap(MusicRecording mr){
map=new HashMap();
map.put(mr.getCategory(), mr);
return map;
}
public Vector selectTrack (String str){
Vector vp=new Vector();
MusicRecording v=map.get(str);
vp.add(v);
return vp;
}
}
2011.8.1 周一
1.异常类:
(1)异常的传播:如果产生异常不起捕获,异常将会导致应用程序中断。
package sample;
public class ExceptionStackTest {
public void a() throws Exception{
b();
}
public void b() throws Exception{
c();
}
public void c() throws Exception{
throw new Exception(); //往外抛异常,Main函数处理
}
public static void main(String[] args) {
ExceptionStackTest est = new ExceptionStackTest();
try{ //必须有异常处理,否则程序瘫痪
est.a();
}catch(Exception e){
e.printStackTrace();
}
}
}
(2)异常的层次:
Error 一般由类产生,表示类的状态不正常。
应用程序不能不从Error 中恢复
所有的java 异常型来自于Exception 类
(3) 运行时异常也叫非受查型异常
一个非受查异常不必必须捕获
(4)普通受查异常:
java.lang.ArithmeticException
java.lang.NullPointerException
java.lang.ArrayIndexOutofBoundsException
java.lang.SecurityException / /安全异常
java.lang.NegativeArraySizeException
2.写一个类DivisionByZero,该类中有个division()方法,在division()方法中实现除法运算,用
异常处理的概念来处理产生的异常
编写测试类测试
public class DivisionByZero {
public static int divisio(int a,int b){
int result = 0;
try{
result = a/b;
}catch(ArithmeticException e){
System.out.println("发生了异常:"+e.getMessage());
result = -1;
}
catch(Exception e){
System.out.println("发生了异常:"+e.getMessage());
result = -2;
}finally{
System.out.println("执行了finally");
}
return result;
}
}
public class DivisionByZeroTest {
public static void main(String[] args) {
int result=DivisionByZero.divisio(45, 0);
System.out.println(result);
}
}
3.自定义异常类:
开发步骤
《1》受查型异常继承Exception
非受查型异常继承RuntimeException
受查型异常,捕获时,代码必须有抛出该类异常
4.写三个类:
OwnException 自定义异常类
OwnExceptionSource 异常源类
OwnExcpeitonHandler 异常处理类可以直接写测试方法
OwnExceptonSource 中有个方法a(), 在a() 中抛出一个异常OwnException, 然后在
OwnExceptionHandler 中调用a()并且要处理异常
public class OwnException extends RuntimeException {
public OwnException(String message){ //构造函数调用父类的构造函数,给message 传值
super(message); //调用父类用super()
}
public OwnException(){
this("数组索引越界了"); //同类构造函数调用用this
}
}
public class OwnExceptionSource{
public static void a()throws OwnException{
String str="abc123";
char [] ch=str.toCharArray();
try {
for(int i=0;i<=ch.length;i++){
System.out.println(ch[i]);
}
} catch (Exception e) {
throw new OwnException();
}
}
}
public class OwnExcpeitonHandler {
public static void main(String[] args) {
try {
OwnExceptionSource.a();
} catch (OwnException e) {
System.out.println(e.getMessage());
}
}
}
5.AWT:Abstract Window Toolkit 抽象窗口工具
提供了一组对象用来创建图形用户界面(GUI)
在java.awt 包中有主要的三种类型的类
(1)组件:AWT 中基础类包括容器
(2)容器:一个能容纳其它组件的特殊化的组件
(3)布局管理器:负责在一个容器内管理组件尺寸,位置信息的一个接口
6.流程:
1 选择一个容器(组件可以添加到容器中) 通常是窗体(通常要先选择一个顶级容器)
* 常用容器Frame Panel Dialog(FileDialog) Applet
* 顶级容器:自己可以直接存在,然后盛放其他组件Frame Dialog
* 二级容器:自己不能直接存在,必须放在某个顶级容器中存在Panel Applet
* 容器可以被继承—>组件都可以被继承
* Frame 继承Window 的顶级容器
* 有标题、边框和菜单条MenuBar
* 默认的布局方式是BorderLayout 管理器
* 用setLayout()方法改变布局管理器
2.设置布局管理器
* 使用容器的setLayout(new Borderlayout())方法设置一个布局管理器
* 作用:
* 在容器中限制组件的尺寸和位置
* 调用组件的setLocation(),setSize(),setBounds()方法来规定组件的尺寸和位置
注意:有的布局管理器,组件就按照自己的方法设置大小,只能适应布局管理器的大小
* Window 类型下的容器默认的布局方式是BorderLayout
* Panel 类型下的容器默认的布局方式是FlowLayout
3 创建组件添加组件到容器
4.创建事件处理器给组件添加事件监听器
5.设置位置大小可见
例:public class AWT1 {
public static void main(String[] args) {
Frame f = new Frame("标题"); //1.选择容器
//f.setTitle("标题");
f.setLayout(new BorderLayout()); //2.设置布局管理器
Button b1 = new Button("北丐"); //3.创建组件
//b1.setLabel("北丐");
Button b2 = new Button("南帝");
Button b3 = new Button("东邪");
Button b4 = new Button("西毒");
Button b5 = new Button("中神通");
f.add(b1,BorderLayout.NORTH); //3.添加组件到容器
f.add(b2,BorderLayout.SOUTH);
f.add(b3,BorderLayout.EAST);
f.add(b4,BorderLayout.WEST);
//f.add(b5,BorderLayout.CENTER);
f.add(b5);//BorderLayout默认放Center
f.setLocation(200, 300); //5.设置位置大小可见
f.setSize(400, 300);
//f.setBounds(200, 300, 300, 300);
//f.show();//show()方法过时
f.setVisible(true);
}
}
组件可以被继承:
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Frame;
public class AWT2 extends Frame{
public AWT2(){}
public AWT2(String title){
super(title); //调用父类Frame 的构造函数
}
private Button b ;
public void init(){
//this.setTitle("标题");
//设置布局
this.setLayout(new BorderLayout());
//创建组件添加组件
b = new Button("按钮");
this.add(b,BorderLayout.SOUTH);
//事件
}
public static void main(String[] args) {
AWT2 f = new AWT2("标题");//创建一个窗体
//f.setTitle("标题");
f.init();
f.setBounds(200, 200, 300, 200);
f.setVisible(true);
}
}
public class AWT3 extends Frame{
private Button b ;
public AWT3(){ }
public AWT3(String title){
super(title);
//this.setTitle("标题");
//设置布局
this.setLayout(new BorderLayout());
//创建组件添加组件
b = new Button("按钮");
this.add(b,BorderLayout.SOUTH);
//事件
}
public static void main(String[] args) {
AWT3 f = new AWT3("标题");//创建一个窗体
f.setBounds(200, 200, 300, 200);
f.setVisible(true);
}
}
7.Panel 二级容器需要放在顶级容器中使用
* 作用:放组件
* 默认布局管理器FlowLayout
* BorderLayout
* 东西南北中五部分,每部分只能直接放一个组件,
* 如果某一个部分放多个,后放入的会覆盖先放入的组件
* 当某个部分需要放入多个组件时,我们需要使用Panel 面板包装几个组件,
* 然后将一个panel 放入到BorderLayout 的某部分
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Frame;
import java.awt.Label;
import java.awt.Panel;
public class PanelTest {
public static void main(String[] args) {
Frame f = new Frame("Panel");
f.setLayout(new BorderLayout());
//北部
Label l = new Label();
l.setText("显示信息"); //给标签设置标题
f.add(l,BorderLayout.NORTH);
//南部
Button b1 = new Button("OK 按钮");
Button b2 = new Button("NO");
Panel p = new Panel(); //也需要根据需求设置布局管理器默认FlowLayout
p.add(b1);
p.add(b2);
f.add(p,BorderLayout.SOUTH);
f.setBounds(200, 200, 300, 200);
f.setVisible(true);
}
}
容器的布局:
Flow Layout:流式布局管理器
Border Layout:边框布局管理器
Grid Layout:网格布局管理器
Card Layout:卡片布局管理器
GridBag Layout:网格包布局管理器
8.public class FlowLayoutTest {
public static void main(String[] args) {
Frame f = new Frame("FlowLayout");
/**
* 流式布局默认对其方式居中
*/
f.setLayout(new FlowLayout(FlowLayout.LEFT,20,30)); //设置对齐
Button b1 = new Button("按钮1");
Button b2 = new Button("按钮2");
Button b3 = new Button("按钮3");
Button b4 = new Button("按钮4");
f.add(b1);f.add(b2);f.add(b3);f.add(b4); //按序放置
f.setBounds(200, 200, 300, 200);
f.setVisible(true);
}
}
9.public class GridLayoutTest {
/**
* 网格式布局管理器
* 组件不会是最佳大小
* 单元格都大小相同
public static void main(String[] args) {
Frame f = new Frame("GridLayout");
f.setLayout(new GridLayout(2,2,10,20));
Button b1 = new Button("按钮1");
Button b2 = new Button("按钮2");
Button b3 = new Button("按钮3");
Button b4 = new Button("按钮4");
f.add(b1);f.add(b3); //按序放置
f.add(b4);f.add(b2);
f.setBounds(200, 200, 300, 200);
f.setVisible(true);
}
}
10.public class CardLayoutTest {
public static void main(String[] args) {
Frame f = new Frame("CardLayout 练习");
f.setLayout(new CardLayout());
Button b1 = new Button("按钮1");
Button b2 = new Button("按钮2");
Button b3 = new Button("按钮3");
Button b4 = new Button("按钮4");
f.add(b1,"b1"); //CardLayout 添加组件必须有个String 约束名,不要重复
f.add(b2,"b2");
f.add(b3,"b3");
f.add(b4,"b4");
f.setBounds(200, 200, 300, 200);
f.setVisible(true);
}
}
1.编写如下图形界面:
public class PanelTest {
public static void main(String[] args) {
Frame f=new Frame("PanelTest");
f.setLayout(new BorderLayout());
Label l=new Label();
l.setText("显示信息的标签");
f.add(l,BorderLayout.NORTH);
Panel p=new Panel();
p.setLayout(new FlowLayout());
Button b1=new Button();
b1.setLabel("OK");
Button b2=new Button("Panic");
p.add(b1,"B1");
p.add(b2, "B2");
f.add(p,BorderLayout.SOUTH);
f.setBounds(200, 300, 400, 200);
f.setResizable(false); //设置边框大小不可改变
f.setVisible(true);
}
}
4、分析模拟supervcd 主界面的布局设置
import java.awt.*;
public class StoneForest {
public static void main(String[] args) {
Frame f = new Frame("欢迎使用StoneForest应用!");
//菜单
MenuBar menu=new MenuBar();
menu.add(new Menu("文件"));
menu.add(new Menu("选项"));
menu.add(new Menu("帮助"));
f.setMenuBar(menu);
//中间的
Label l1=new Label("音乐");
Panel p2=new Panel(new FlowLayout(FlowLayout.LEFT));
Label l2=new Label("选择音乐目录");
Choice chooser = new Choice(); //下拉列表框
chooser.add("-----");
chooser.add("大陆");
chooser.add("港台");
chooser.add("新加坡");
chooser.add("欧美");
TextArea t=new TextArea(13,45); //多行文本域
p2.add(l2);
p2.add(chooser);
p2.add(t);
f.add(l1);
f.add(p2);
//底部的
Button b1=new Button("详细… ");
Button b2=new Button("清空");
Button b3=new Button("退出");
Panel p=new Panel();
p.add(b1);
p.add(b2);
p.add(b3);
f.add(p,BorderLayout.SOUTH);
f.setBounds(200, 200, 350, 350);
f.setVisible(true);
}
}
2011.8.3 周三
1.Component Methods 组件的方法
setForeground()、getForeground() 前景色(放的东西的颜色)
setBackground() 、getBackground() 背景色
setEnabled() 、getEnabled() 可见性(可以看见但不能操纵,显示灰色)
setVisible() 、getVisible() 可见性
setFont() 、getFont() 字体
setSize() 、getSize() 大小
getPreferredSize() 获取最佳大小
setLocation() 、getLocation() 位置
setBounds() 、getBounds() 大小及位置
paint() 画
repaint() 重新画
update() 更新
实例
class AWTTest extends Frame {
public AWTTest() {
super("Components Test");
this.addWindowListener(new WindowAdapter() { //匿名内部类
public void windowClosing(WindowEvent evt) {
setVisible(false);
dispose(); //Frame 窗体的关闭步骤
System.exit(0);
}
});
this.setSize(300,300);
this.setLayout(new FlowLayout());
this.add(new Button("Button")); //按钮
this.add(new Checkbox("CheckBox", true)); //复选框默认选中
Choice ch = new Choice(); //下拉列表框
ch.add("Choice1");
ch.add("Choice2");
this.add(ch);
this.add(new Label("Label")); //标签
class MyCanvas extends Canvas { //画布
public void paint(Graphics g) {
g.drawString("Canvas",10,10); //不是实心的
g.fillString("Canvas",10,10); //是实心的
}
}
Canvas c = new MyCanvas();
c.setBackground(Color.black);
c.setForeground(Color.white);
c.setSize(60, 50);
this.add(c);
List l = new List(4, false); //列表框
l.add("List item 1");
l.add("List item 2");
this.add(l);
this.add(new Scrollbar(Scrollbar.VERTICAL, 0, 1, 0, 255)); //滚动条
this.add(new TextArea("TextArea", 5, 40)); //文本编辑区域
this.add(new TextField("TextField")); //单行文本
}
public static void main (String [] args) {
new AWTTest().setVisible(true);
}
}
2.Button 按钮
是一个能够当用户产生点击时能产生一个动作的组件
构造方法:
Button()
Button(String label)
其它方法:
setActionCommand() and getActionCommand()
setLabel() and getLabel()
addActionListener() and removeActionListener()
getActionListeners()
3.Canvas 画布
用于显示图形
在画布上可以用各种颜色描绘几何图形,像素,文本
构造方法:
Canvas()
Canvas(GraphicsConfiguration conf)
其它方法:
paint() / /repaint()默认调用paint()方法
update()
requestFocus() //获得焦点
实例
public class CanvasTest extends Canvas implements KeyListener {
int index;
Color[] colors= {Color.red, Color.green, Color.blue };
public CanvasTest() {
addKeyListener(this);
}
public void paint(Graphics g) {
g.setColor(colors[index]);
g.fillRect(0,0,getSize().width,getSize().height);
g.drawRect(0,0,getSize().width,getSize().height);
if(index==colors.length-1){
index=0;
}
g.setColor(colors[index+1]);
g.fillOval(100, 100, 100, 100);
}
public static void main(String args[]) {
final Frame f = new Frame("Canvas");
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent evt) {
f.setVisible(false);
f.dispose();
System.exit(0);
}
});
CanvasTest mc = new CanvasTest();
f.add(mc,BorderLayout.CENTER);
f.setSize(150, 150);
mc.requestFocus();
f.setVisible(true);
}
public void keyTyped(KeyEvent ev) {
index++;
if (index == colors.length) {
index =0;
}
repaint(); //默认调用paint()方法
}
public void keyPressed(KeyEvent ev) {
}
public void keyReleased(KeyEvent ev) {
}
}
4.Checkbox 复选框
单独使用,显示一个复选框或者是选中,或者是没选中
也是checkboxgroup 中的一部分,显示为单选按钮
构造方法:
Checkbox()
checkbox(String label)
checkbox(String label, boolean state) //默认状态是否选中
checkbox(String label, boolean state, CheckboxGroup group) //分组
checkbox(String label,CheckboxGroup group, boolean state)
其他方法:
addItemListener() and removeItemListener()
setState() and getState()
setLabel() and getLabel()
如果变成单选按钮组,必须使用同一个CheckboxGroup 封装
CheckboxGroup 方法:
getSelectedCheckbox() and setSelectedCheckbox()
实例:
public class CheckboxTest {
public static void main(String[] args) {
Frame f = new Frame("CheckboxTest");
f.setLayout(new FlowLayout(FlowLayout.LEFT)); //居左对齐
Checkbox cb1 = new Checkbox();
cb1.setLabel("足球");
Checkbox cb2 = new Checkbox("篮球",true);
f.add(cb1);
f.add(cb2);
CheckboxGroup group = new CheckboxGroup();
Checkbox cb3 = new Checkbox();
cb3.setLabel("男");
cb3.setCheckboxGroup(group);
Checkbox cb4 = new Checkbox("女",true,group);
f.add(cb3);
f.add(cb4);
f.setBounds(300, 300, 400, 300);
f.setVisible(true);
}
}
实例
class CheckboxTest extends Frame implements ItemListener {
Label l = new Label("Record the state");
public CheckboxTest() {
super("Checkboxes and Radio buttons");
this.addWindowListener(new WindowHandler());
this.setSize(300,200);
this.setLayout(new FlowLayout());
Checkbox[] cb = new Checkbox[6];
this.add(cb[0] = new Checkbox("Watermelons", true));
this.add(cb[1] = new Checkbox("Kiwis", true));
this.add(cb[2] = new Checkbox("Apples", true));
CheckboxGroup group = new CheckboxGroup();
this.add(cb[3] = new Checkbox("Windows", group, true));
this.add(cb[4] = new Checkbox("Linux", group, false));
this.add(cb[5] = new Checkbox("Macintosh", group, false));
for(int i = 0; i < cb.length; i++)
cb[i].addItemListener(this);
l.setBackground(Color.black);
l.setForeground(Color.green);
l.setSize(300, 40);
this.add(l);
}
public static void main (String [] args) {
new CheckboxTest().setVisible(true);
}
public void itemStateChanged(java.awt.event.ItemEvent itemEvent) {
String state = "deselected";
if(itemEvent.getStateChange() == itemEvent.SELECTED)
state = "selected";
Checkbox cb = (Checkbox)itemEvent.getSource();
l.setText(cb.getLabel() + " is " + state);
}
class WindowHandler extends WindowAdapter {
public void windowClosing(java.awt.event.WindowEvent windowEvent) {
CheckboxTest.this.setVisible(false);
CheckboxTest.this.dispose();
System.exit(0);
}
}
}
5.Choice 下拉选择框
带有选择项的下拉菜单
只有当前被选中的项目能显示在屏幕上
构造方法:
Choice()
其它方法:
add() and insert()
getSelectedItem(), getSelectedIndex() and getItem()
addItemListener() and removeItemListener()
实例:
public class ChoiceTest {
public static void main(String[] args) {
Frame f = new Frame("ChoiceTest");
f.setLayout(new FlowLayout()); //默认居中对齐
final Choice ch = new Choice();
ch.add("-----------");
ch.add("大陆");
ch.add("港台");
ch.add("欧美");
ch.add("新加坡");
ch.insert(其它, 5);
f.add(ch);
f.setBounds(300, 300, 400, 300);
f.setVisible(true);
}
}
6.Label 标签
用于在屏幕上显示文本内容
Label 不能直接同用户产生交互动作,没有事件
构造方法:
Label()
Label(String text)
Label(String text, int alignment)其他方法:
setText() and getText()
实例:
public class LabelTest {
public static void main(String[] args) {
Frame f = new Frame("LabelTest");
f.setLayout(new BorderLayout());
Label l = new Label("选择音乐目录:");
f.add(l);
f.setBounds(300, 300, 400, 300);
f.setVisible(true);
}
}
7.List 列表框
在屏幕上显示字符串列表有滚动条
允许用户在列表框中选择一个或多个选项
AWT 的List 组件放的内容是String 字符串
将来使用Swing 中JList 组件放的内容是Object 对象
* List 组件清空removeAll()
* 将来使用Swing 中JList 组件时,清空使用removeAll()无效
构造方法:
List()
List(int rows)
List(int rows, boolean multipleMode) //支持多选
其它方法:
add() and remove(), removeAll() //add 是字符串
addActionListener() and removeActionListener()
getSelectedItem(), getSelectedItems(), getSelectedIndex()
getSelectedIndexes(), getItem(), getItems()
实例:
public class ListTest {
public static void main(String[] args) {
Frame f = new Frame("ListTest");
f.setLayout(new BorderLayout());
List l=new List(10,true); //支持多选
l.add("真的,用了心");
l.add("真的英雄");
l.add("你给我一片天");
l.add("明明白白我的心");
l.add("在我生命中的每一天");
l.add("问心无愧");
l.add("对不起自己");
l.add("壮志在我胸");
f.add(l,BorderLayout.CENTER);
f.setBounds(300, 300, 400, 300);
f.setVisible(true);
}
}
8.Textfield 单行文本输入框
可以输入单行文本并可以编辑
AWT 中没有单独的密码输入框,使用文本输入框,然后设置它的回显字符为*
构造方法:
Textfield()
Textfield(int columns) //显示几列
Textfield(String text) //指明文本,默认有值
Textfield(String text, int columns)
其它方法:
setText() and getText()
addActionListener() and removeActionListener()
setEditable() and isEditable() //是否可以编辑
setEchoChar() and getEchoChar() //设置回滚字符
实例:
public class TextfieldTest {
public static void main(String[] args) {
Frame f = new Frame("TextfieldTest");
f.setLayout(new BorderLayout());
Label name = new Label("账户:");
Label password = new Label("密码:");
TextField tf1 = new TextField("",10);
TextField tf2 = new TextField("",10);
tf.setEditable(false);//设置是否可编辑
tf2.setEchoChar('*');//设置回显字符
f.add(name);
f.add(tf1);
f.add(password);
f.add(tf2);
f.setBounds(300, 300, 400, 300);
f.setVisible(true);
}
}
9.TextArea 多行文本编辑区
可以进行多行文本输入和编辑
含有滚动条
构造方法:
TextArea()
TextArea(int rows 小, int cols 大)
TextArea(String text)
TextArea(String text, int rows, int cols)
TextArea(String text, int rows, int cols, int scrollbars)
其它方法:
getText() and setText(),
append(), insert(), replaceRange()
addTextListener() and removeTextListener()
实例:
public class TextAreaTest {
public static void main(String[] args) {
Frame f = new Frame("TextAreaTest");
f.setLayout(new BorderLayout());
TextArea ta = new TextArea(10,50);
f.add(ta);
f.setBounds(300, 300, 400, 300);
f.setVisible(true);
}
}
10.Dialog 对话框
是一个含有Title 和border 的顶级Window 类
默认的布局方式是BorderLayout
对话框必须要有主容器
可以是非模态和模态的
构造方法:
Dialog(Dialog owner),
Dialog(Dialog owner, String title),
Dialog(Dialog owner, String title, boolean modal),
Dialog(Dialog owner, String title, boolean modal, GraphicsConfiguration gc),
Dialog(Frame owner),
Dialog(Frame owner, boolean modal),
Dialog(Frame owner, String title),
Dialog(Frame owner, String title, boolean modal)
Dialog(Frame owner, String title, boolean modal, GraphicsConfiguration gc)
其它方法:
setModal() and isModal()
setTitle() and getTitle()
setResizable() and isResizable() //设置可拉伸性
show() and hide()
dispose() //释放对象
实例:
public class DialogTest {
public static void main(String[] args) {
Frame f = new Frame("Dialog 练习");
Dialog d = new Dialog(f,"对话框");
//model 为true 有模式的对话框打开,owner 不能操作(无法获得焦点)
//Dialog d = new Dialog(f,"对话框",true);
//d.setTitle("对话框");
d.setBounds(200, 200, 300, 250);
d.setResizable(false);
f.setBounds(300, 300, 400, 300);
f.setResizable(false); //设置大小可变
f.setVisible(true);
d.setVisible(true);
}
}
11.FileDialog 文件对话框
模态的对话框用于选择文件
构造方法:
FileDialog(Frame parent)
FileDialog(Frame parent, String title)
FileDialog(Frame parent, String title, int mode)
其他方法:
setFile() and getFile()
setMode() and getMode()
setDirectory() and getDirectory()
setFilenameFilter() and getFilenameFilter()
实例:
public class FileDialogTest {
public static void main(String[] args) {
FileDialog fd = new FileDialog(new Frame(), "Choose a file", FileDialog.LOAD);
FilenameFilter ff = new MyFilenameChooser();
fd.setFilenameFilter(ff);
fd.setVisible(true);
String name = fd.getFile();
System.out.println("You chose the file: " + name);
System.exit(0);
}
}
class MyFilenameChooser implements FilenameFilter{
public boolean accept(File dir, String name) {
return name.endsWith("java");
}
}
12.ScrollPane 可滚动区
是个容器
为单个的内部组件自动添加水平或者垂直滚动条
构造方法:
ScrollPane()
ScrollPane(int scrollbarDisplayPolicy)其他方法:
setLayout()
setScrollPosition() and getScrollPosition()、
13.菜单的层次关系
至少有三种类型的菜单菜单条、菜单、菜单项
MenuBar:紧靠着Window 顶部的一个横条
Menus:包含在MenuBar 中
MenuItems:包含在Menu 中
菜单类的方法:
getFont() and setFont()
getName() and setName()
getParent()
(1)MenuBar 菜单条
在紧靠Frame 顶部创建的一个包含Menu 的一个横条
使用Frame 类的setMenuBar()方法添加MenuBar
构造方法:
MenuBar()
其它方法:
add() and remove()
getMenu() and getMenuCount()
(2)Menu 菜单
主要功能是包含MenuItem
MenuComponent MenuContainer
MenuItem MenuBar
CheckboxMenuItem Menu
PopupMenu
继承于MenuItem 类,当然可以包含其他的Menu
构造方法:
Menu()
Menu(String label)
Menu(String label, boolean tearOff)
其他方法:
add(), insert(),
addSeparator() //添加分割符
remove(),
removeAll()
getItem(), getItemCount()
(3)MenuItem 菜单项
可以选择的一种菜单的标签
构造方法:
MenuItem()
MenuItem(String label)
MenuItem(String label, MenuShortcut s)
其他方法:
addActionListener() and removeActionListener()
setActionCommand() and getActionCommand()
setLabel() and getLabel()
setEnable() and isEnable()
(4)PopupMenu 弹出菜单
在组件的内部和相应的位置上动态弹出
构造方法:
PopupMenu()
PopupMenu(String label)
其他方法:
methods inherited from Menu
show()
实例:
public class MenuTest {
public static void main(String[] args) {
Frame f = new Frame("SuperVCD 菜单练习");
//菜单条
MenuBar bar = new MenuBar();
//三个主菜单
Menu file = new Menu("文件");
Menu option = new Menu("选项");
Menu help = new Menu("帮助");
//添加file 菜单项
Menu open = new Menu("打开");
MenuItem op1 = new MenuItem("本地...");
MenuItem op2 = new MenuItem("局域网...");
MenuItem op3 = new MenuItem("互联网...");
open.add(op1);open.add(op2);open.add(op3);
MenuItem save = new MenuItem("保存");
MenuItem exit = new MenuItem("退出");
file.add(open);
file.add(save);
file.addSeparator();//添加分割线在哪里调用,就再哪添加
file.add(exit);
//添加option 菜单项
MenuItem option1 = new MenuItem("选项1");
MenuItem option2 = new MenuItem("保存2");
MenuItem option3 = new MenuItem("保存3");
option.add(option1);option.add(option2);option.add(option3);
//添加help 菜单项
MenuItem about = new MenuItem("关于...");
help.add(about);
//将三个菜单添加到菜单条
bar.add(file);bar.add(option);bar.add(help);
//给主窗体设置菜单条
f.setMenuBar(bar);
f.setBounds(300, 300, 400, 300);
f.setResizable(false);
f.setVisible(true);
}
} 实例:
class MenuTest extends Frame {
PopupMenu pop;
public MenuTest() {
super("Golf Caddy");
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent evt) {
setVisible(false);
dispose();
System.exit(0);
}
});
this.setSize(300,300);
this.add(new Label("Choose club."), BorderLayout.NORTH);
Menu woods = new Menu("Woods");
woods.add("1 W");
woods.add("3 W");
woods.add("5 W");
Menu irons = new Menu("Irons");
irons.add("3 iron");
irons.add("4 iron");
irons.add("5 iron");
irons.add("7 iron");
irons.add("8 iron");
irons.add("9 iron");
irons.addSeparator();
irons.add("PW");
irons.insert("6 iron", 3);
MenuBar mb = new MenuBar();
mb.add(woods);
mb.add(irons);
this.setMenuBar(mb);
pop = new PopupMenu("Woods");
pop.add("1 W");
pop.add("3 W");
pop.add("5 W");
final TextArea p = new TextArea(100, 100);
p.setBackground(Color.green);
this.addMouseListener(new MouseAdapter() {
public void mouseReleased(java.awt.event.MouseEvent evt) {
if(evt.isPopupTrigger()) {
System.out.println("popup trigger");
System.out.println(evt.getComponent());
System.out.println("" + evt.getX()+ " " + evt.getY());
pop.show(evt.getComponent(), evt.getX(), evt.getY());
}
}
});
this.add(p, BorderLayout.CENTER);
}
public static void main (String [] args) {
new MenuTest().setVisible(true);
}
}
14.写个类ResumeFrame 自己分析布局设计
Choice -- 求职目标、自我技能、工作经验、教育经历、证书。
TextArea 创建5 个TextArea 对象,每个对象中对应保存上诉项目所要描述的详细信息
public class ResumeFrame {
public static void main(String[] args) {
Frame f=new Frame("简历信息");
f.setLayout(new BorderLayout());
Panel p1=new Panel();
Label l=new Label("简历信息选项");
Choice ch = new Choice();
ch.add("");
ch.add("求职目标");
ch.add("自我技能");
ch.add("工作经历");
ch.add("教育经历");
ch.add("证书");
p1.add(l);
p1.add(ch);
f.add(p1,BorderLayout.WEST);
Panel p2=new Panel();
p2.setLayout(new CardLayout());
TextArea ta1=new TextArea(30,40);
ta1.setText("寻找一份java 开发类工作,要求工作时间8 小时,周末不加班,工资
最少3000 元");
p2.add(ta1,"t1");
TextArea ta2=new TextArea(30,40);
ta2.setText("本人熟悉J2SE 和J2EE 开发,善于网络编程");
p2.add(ta2,"t2");
TextArea ta3=new TextArea(30,40);
ta3.setText("2011.7.13-2011.11.13 期间在北京亚思晟培训,培训期间参与开发过
SuperVCD 等项目");
p2.add(ta3,"t3");
TextArea ta4=new TextArea(30,40);
ta4.setText("1996-2001 年富坑小学, 2001-2004 年仙下中学,2004-2007 年于都中
学,2008-2012 年东华理工大学");
p2.add(ta4,"t4");
TextArea ta5=new TextArea(30,40);
ta5.setText("软件资格水平考试——中级电子商务设计师,计算机等级考试四级数
据库系统工程师");
p2.add(ta5,"t5");
f.add(p2,BorderLayout.EAST);
f.setBounds(200, 300, 500, 400);
f.setResizable(false);
f.setVisible(true);
}
}
15.SuperVCD 主窗体
public class StoneForest {
public static void main(String[] args) {
Frame f = new Frame("欢迎使用StoneForest 应用!");
//菜单
MenuBar bar = new MenuBar();
//三个主菜单
Menu file = new Menu("文件");
Menu option = new Menu("选项");
Menu help = new Menu("帮助");
//添加file 菜单项
Menu open = new Menu("打开");
MenuItem op1 = new MenuItem("本地...");
MenuItem op2 = new MenuItem("局域网...");
MenuItem op3 = new MenuItem("互联网...");
open.add(op1);open.add(op2);open.add(op3);
MenuItem save = new MenuItem("保存");
MenuItem exit = new MenuItem("退出");
file.add(open);
file.add(save);
file.addSeparator();
file.add(exit);
//添加option 菜单项
MenuItem option1 = new MenuItem("复制");
MenuItem option2 = new MenuItem("剪切");
MenuItem option3 = new MenuItem("粘贴");
option.add(option1);option.add(option2);option.add(option3);
//添加help 菜单项
MenuItem about = new MenuItem("关于...");
help.add(about);
//将三个菜单添加到菜单条
bar.add(file);bar.add(option);bar.add(help);
//给主窗体设置菜单条
f.setMenuBar(bar);
//上部
Panel p2=new Panel();
p2.setLayout(new FlowLayout(FlowLayout.LEFT));
Label l2=new Label("选择音乐目录");
Choice chooser = new Choice();
chooser.add("-----");
chooser.add("大陆");
chooser.add("新加坡");
chooser.add("欧美");
chooser.add("港台");
p2.add(l2);
p2.add(chooser);
f.add(p2,BorderLayout.NORTH);
//中部
List l=new List(10,true);
f.add(l,BorderLayout.CENTER);
//底部的
Button b1=new Button("详细…");
b1.setEnabled(false);
Button b2=new Button("清空");
b2.setEnabled(false);
Button b3=new Button("退出");
b3.setEnabled(true);
Panel p=new Panel();
p.add(b1);
p.add(b2);
p.add(b3);
f.add(p,BorderLayout.SOUTH);
f.setBounds(200, 200, 350, 350);
f.setResizable(false);
f.setVisible(true);
}
}
16.展示唱片窗体
public class ShowSongs {
public static void main(String[] args) {
Frame f=new Frame("展现唱片");
//北部
Panel p1=new Panel();
p1.setLayout(new GridLayout(1,2));
Panel p2=new Panel();
p2.setLayout(new BoxLayout(p2,BoxLayout.Y_AXIS));
Label l1=new Label("专辑名:真的用了心");
Label l2=new Label("歌手名:成龙");
Label l3=new Label("地区名:港台");
p2.add(l1);
p2.add(l2);
p2.add(l3);
p1.add(p2);
Panel p4=new Panel();
p4.setLayout(new BorderLayout());
//Label l4=new Label("图片");
Button b2=new Button("图片");
p4.add(b2);
p1.add(p4);
f.add(p1,BorderLayout.NORTH);
//中部
List l=new List(10);
l.add("真的,用了心");
l.add("真的英雄");
l.add("你给我一片天");
l.add("明明白白我的心");
l.add("在我生命中的每一天");
l.add("问心无愧");
l.add("对不起自己");
l.add("壮志在我胸");
f.add(l,BorderLayout.CENTER);
//南部
Panel p3=new Panel();
p3.setLayout(new FlowLayout(FlowLayout.CENTER));
Button b=new Button("确定");
p3.add(b);
f.add(p3,BorderLayout.SOUTH);
f.setBounds(100, 200, 300, 400);
f.setVisible(true);
}
}
2011.8.4 周四
1.概念
Event Sources 事件源—产生事件
Event Objects 事件对象—描述事件
Event Listeners 事件监听器—监听事件并调用相应的处理方法
2.事件对象Event Objects
一个包含与特定类型的事件相关信息的对象
一个事件对象至少要包含一个引起事件的这个对象的引用public Object getSource()
所有的事件都是Event Objects 类的子类
3.事件源Event Sources
事件源就是引发事件的组件或者对象
提供方法允许其他的方法来增加或删除事件监听器
维护事件监听器的列表
包含向所有的事件监听器创建和传递事件对象的业务逻辑代码
4.开发流程
* 《1》确定事件源
* 《2》实现对应的事件监听器XXXListener (接口)
* 《3》给事件源注册事件监听器事件源对象.addXXXListener(XXXListener l)
如果使用匿名内部类实现事件监听器,《2》《3》合二为一
ActionEvent -->监听器ActionListener-->添加监听器方法addActionListener(ActionListener a)
实例:
public class ActionEventTest {
public static void main(String[] args) {
Frame f = new Frame("Event Test !");
final Label l = new Label("显示信息");
Button b1 = new Button("OK");
Button b2 = new Button("NO");
Panel p = new Panel();
p.add(b1);p.add(b2);
f.add(p,BorderLayout.SOUTH);
//3 事件源注册(添加)事件监听器
MyActionListener listener = new MyActionListener(l);
b1.addActionListener(listener);
b2.addActionListener(listener);
/*b1.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
//System.out.println("OK 点击了");
l.setText("OK 点击了");
}
});
b2.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
//System.out.println("OK 点击了");
l.setText("NO 点击了");
}
});*/
f.add(l,BorderLayout.NORTH);
f.setBounds(400, 300, 300, 300);
f.setVisible(true);
}
}
class MyActionListener implements ActionListener{ // 开发一个事件监听器
private Label l;
public MyActionListener(Label l){
this.l = l;
}
@Override
public void actionPerformed(ActionEvent e) {
//System.out.println("OK 点击了");
//获得事件源
Button b = (Button)e.getSource();
if(b.getLabel().equals("OK"))
l.setText("OK 点击了");
else
l.setText("NO 点击了");
}
}
5.事件监听器Event Listeners
通知一个对象产生了事件
必须实现适当的事件监听器
6.事件类型
7.动作事件ActionEvent
双击List 组件中选项
选择一个按钮
选择MenuItem
在文本框组件中按回车(Enter)键
public class ActionEventTest2 {
public static void main(String[] args) {
Frame f = new Frame("Event Test !");
f.setLayout(new FlowLayout());
final Label l = new Label("显示信息");
f.add(l);
//List 双击时触击动作事件
final List list = new List(10);
list.add("aaaaaaaaaaaaa");
list.add("bbbbbbbbbbbbb");
list.add("ccccccccccccc");
list.add("ddddddddddddddd");
f.add(list);
list.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
String item = list.getSelectedItem();
l.setText(item);
}
});
//TextField 按回车(Enter)键事件
final TextField tf = new TextField(10);
f.add(tf);
tf.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
String value = tf.getText();
list.add(value);
tf.setText("");
}
});
f.setBounds(400, 300, 300, 300);
f.setVisible(true);
}
}
8.文本事件TextEvent
文本框中文本发生改变
TextArea 组件中的文本发生改变
实例:
public class TextEventTest {
public static void main(String[] args) {
Frame f = new Frame("Event Test !");
f.setLayout(new FlowLayout());
final Label l = new Label("显示信息");
f.add(l);
//文本事件
final TextField tf = new TextField(10);
f.add(tf);
tf.addTextListener(new TextListener(){
@Override
public void textValueChanged(TextEvent e) {
String value = tf.getText();
l.setText(value);
}
});
final TextArea ta = new TextArea(10,50);
f.add(ta);
ta.addTextListener(new TextListener(){
@Override
public void textValueChanged(TextEvent e) {
String value = ta.getText();
l.setText(value);
}
});
f.setBounds(400, 300, 300, 300);
f.setVisible(true);
}
}
9.选项事件ItemEvent
选择和取消选择Checkbox
选择和取消选择CheckboxMenuItem
选择Choice 中的选项
选择一个或多个List 组件中的选项
实例:
public class ItemEventTest {
public static void main(String[] args) {
Frame f = new Frame("Event Test !");
SuperVCDMenuBar bar = new SuperVCDMenuBar();
f.setMenuBar(bar);
Label l = new Label("选择音乐目录:");
final Choice ch = new Choice();
ch.add("------------");
ch.add("大陆");
ch.add("港台");
ch.add("欧美");
ch.add("新加坡");
Panel p = new Panel();
p.setLayout(new FlowLayout(FlowLayout.LEFT));
p.add(l);p.add(ch);
f.add(p,BorderLayout.NORTH);
final List list = new List();
f.add(list);
final Button b1 = new Button("详细");
final Button b2 = new Button("清空");
Button b3 = new Button("退出");
b1.setEnabled(false);
b2.setEnabled(false);
Panel p2 = new Panel();
p2.add(b1);p2.add(b2);p2.add(b3);
f.add(p2,BorderLayout.SOUTH);
ch.addItemListener(new ItemListener(){ //给ch 下拉框加事件
@Override
public void itemStateChanged(ItemEvent e) {
list.removeAll();
if(ch.getSelectedIndex()==0){//========
b1.setEnabled(false);
b2.setEnabled(false);
}else{
String item = ch.getSelectedItem();
list.add(item);
b1.setEnabled(false);
b2.setEnabled(true);
}
}
});
list.addItemListener(new ItemListener(){ //List 添加选项事件
@Override
public void itemStateChanged(ItemEvent e) {
b1.setEnabled(true);
}
});
f.setBounds(400, 300, 300, 300);
f.setVisible(true);
}
}
10.事件监听器
Category Interface Name Methods
Action ActionListener actionPerformed(ActionEvent)
Item ItemListener itemStateChanged(ItemEvent)
Mouse motion MouseMotionListener mouseDragged(MouseEvent)
mouseMoved(MouseEvent)
Mouse button MouseListener mousePressed(MouseEvent)
mouseReleased(MouseEvent)
mouseEntered(MouseEvent)
mouseExited(MouseEvent)
mouseClicked(MouseEvent)
Key KeyListener keyPressed(KeyEvent)
keyReleased(KeyEvent)
keyTyped(KeyEvent)
Focus FocusListener focusGained(FocusEvent)
focusLost(FocusEvent)
Adjustment AdjustmentListener adjustmentValueChanged
(AdjustmentEvent)
Component ComponentListener componentMoved(ComponentEvent)
componentHidden(ComponentEvent)
componentResized(ComponentEvent)
componentShown(ComponentEvent)
11.事件适配器Event Adapters
一个事件适配器实现了一个特定的事件监听器
只能够继承适配器并且重写他的方法
public class WindowEventTest {
public static void main(String[] args) {
final Frame f = new Frame("Window Event Test !");
/**
* 关闭窗口WindowListener
*/
f.addWindowListener(new WindowAdapter(){
@Override
public void windowClosing(WindowEvent e){
f.setVisible(false);
f.dispose();
System.exit(0);
}
});
f.setBounds(400, 300, 300, 300);
f.setVisible(true);
}
}
事件监听器(续)
2011.8.6 周六
1.Applets 小应用程序
一个Applet 是一个小的程序,通过嵌入到别的应用程序来运行
Applet 不能独立运行,必须放在浏览器中使用,其父类是Panel,二级容器Applet 也是二级
容器,可以放组件
使用AWT 组件必须继承Java.applet.Applet
使用Swing 组件必须继承Javax.swing.JApplet
JApplet 是Applet 的子类
Applets 嵌入到HTML 页面中
在浏览器或者Applet viewers 中运行
类的层次关系:
实例:
import java.applet.Applet;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class MyApplet extends Applet{
private Button b1;
private Button b2;
private Panel p;
private Label l;
@Override
public void destroy() {
System.out.println("--------destroy");
}
@Override
public void init() {
System.out.println("--------init 初始化");
b1 = new Button("OK");
java.lang.Object
java.awt.Component
java.awt.Container
java.awt.Panel
java.applet.Applet
javax.swing.JApplet
b2 = new Button("Panic");
p = new Panel();
l = new Label("显示信息");
}
@Override
public void start() {
System.out.println("----------start");
this.setLayout(new BorderLayout());
this.add(l,BorderLayout.NORTH);
p.add(b1);p.add(b2);
this.add(p,BorderLayout.SOUTH);
b1.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
l.setText("OK 按钮点击了");
}
});
b2.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
l.setText("Panic 按钮点击了");
}
});
}
@Override
public void stop() {
System.out.println("------------stop-----");
}
public void a(){ //不运行
System.out.println("-----------------aaaa");
}
}
2.嵌入到页面中的Applet


Applet Test



我的第一个Applet






3.Applet 没有main()方法、默认只会调用自己的4 个方法其它方法必须放到4 个方法内调用。
Applet4 个生命周期
初始化:init() 每次装在Applet 的时候都调用init()初始化方法只运行一次
运行:Start() 启动Applet 执行Applet 代码可以运行多次
停止:Stop() 停止Applet 运行可以运行多次
销毁:destroy() 在卸载之前做的最后的请理性工作只运行一次
public void init() { . . . }
public void start() { . . .}
public void stop() { . . . }
public void destroy() { . . .}
4.绘图及事件处理的方法:
public void paint(Graphics g){...}
public void update(Graphics g){…}
paint(Graphics g):绘图的基本方法
update(Graphics g):同paint 方法配合使用,提高绘图效率的重绘的方法
如果Applet 继承了Japplet,则需要在ContentPane 中添加组件
Applet 程序从Componet 类继承了一组事件处理的方法
5.安全限制
Applet 不能够导入库或者定义的本地方法
通常情况下它不能够读或写执行它的主机的文件
不能够创建其他的网络,除了Applet 所在的主机
不能够在运行它的主机上运行任何程序
不能读取特定系统信息
带有Applet 的窗口看起来和带有应用程序的窗口不一样
6.在Applet 和Browser 之间通信
getParameter(String name)
showStatus(String msg)
getCodeBase()
getDocumentBase()
在Applet 之间进行通信
Interface AppletContext
public interface AppletContext {
public Applet getApplet(String name);
public Enumeration getApplets();

}
Applet 中的方法
getAppletContext()
Applet 标签
[archive= archiveList] code= appletFile. class width= pixels height= pixels
[codebase= codebaseURL ] [alt= alternateText ]
[name= appletInstanceName ] [align= alignment ]
[vspace = pixels ] [hspace= pixels ] >
[]
[]
.......
[alternateHTML]

实例:
import java.applet.Applet;
import java.awt.Graphics;
public class SimpleApplet extends java.applet.Applet {
StringBuffer buffer;
public void init() {
buffer = new StringBuffer();
addItem("initializing... ");
}
public void start() {
addItem("starting... ");
}
public void stop() {
addItem("stopping... ");
}
public void destroy() {
addItem("preparing for unloading...");
}
void addItem(String newWord) {
System.out.println(newWord);
buffer.append(newWord);
repaint();
}
public void paint(Graphics g) {
g.drawRect(0, 0, size().width - 1, size().height - 1);
g.drawString(buffer.toString(), 5, 15);
}
}
7.输入输出流和文件系统(Stream I/O and Files)
流:字节流的源和目的地
2 种流:字节输入流和字节输出流
流的分类:
(1)输入流:InputStream 读入内存read 参照物:针对内存抽象类不能new 对象
输出流:OutputStream 写出内存write 参照物:针对内存抽象类不能new 对象
(2) 字节流:.......Stream
字符流:.....Read()、......Write
(3) 处理流:构造方法无法直接与文件对接(必须通过节点流嵌入) BufferedInputStream
节点流:构造方法可以直接与文件对接
8.字节流:以字节形式Byte(8 位-128—127)
(1)字节输入流:ObjectInputStream 、FileInputStream 、DataInputStream、
BufferedInputStream
(2)字节输出流:ObjectOutputStream、FileOutputStream、DataOutputStream、
BufferedOutputStream、PrintStream
9.(1)字节输入流:
构造方法:
int read()
int read(byte[])
int read(byte[], int, int)
其它方法:
void close()
int available()
skip(long)
boolean markSupported()
void mark(int)
void reset(int)
(2)字节输出流:
构造方法:
int write(int)
int write(byte[])
int write(byte[], int, int)
其它方法:
void close()
void flush()
缓存刷新
实例:public class FileInputStreamTest {
public static void main(String[] args) {
File f1 = new File("1.txt"); //源文件必须事先存在
File f2 = new File("2.txt"); //目的地文件一般不存在
try {
FileInputStream fis = new FileInputStream(f1); //和源文件对接的读的流对象
FileOutputStream fos = new FileOutputStream(f2);//和目的地文件对接的流对象
int b =0;
while(( b=fis.read())!=-1){ //读出文件
fos.write(b); //写入文件
}
fos.close(); //关闭
fis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
10.文件体系
一个文件对象就代表一个文件或者目录
File 处理各种磁盘操作
构造函数:
File(File parent, String child)
根据parent 抽象路径名和child 路径名字符串创建一个新File 实例
File(String pathname)
通过将给定路径名字符串转换为抽象路径名来创建一个新File 实例
File(String parent, String child)
根据parent 路径名字符串和child 路径名字符串创建一个新File 实例
File(URI uri) 通过将给定的file: URI 转换为一个抽象路径名来创建一个新的File 实例
目录分隔符:
File.separator (Window 系统\\ 、Linux 系统/)动态获取
源内存
1.txt
目的地
2.txt
input读(Read) output 写(Write)
ouououtput
File 类的方法:
boolean createNewFile() 创建新文件(只能创建文件、不能创建目录)
boolean delete() 删除文件或目录
boolean mkdir() 只能创建一层文件夹
boolean mkdirs() 可以创建多层文件夹
boolean renameTo(File destination) 重命名(参数是文件目的地)
boolean canRead() 测试应用程序是否可以读取此抽象路径名表示的文件
boolean canWrite() 测试应用程序是否可以修改此抽象路径名表示的文件
boolean exists() 测试文件或目录是否存在
String[] list() 获得文件目录、直接包含的文件名数组(只有一层)
long lastModified() 返回此抽象路径名表示的文件最后一次被修改的时间
String getPath() 将此抽象路径名转换为一个路径名字符串(相对路径)
getAbsolutePath() 返回此抽象路径名的绝对路径名字符串
String getParent() 返回此抽象路径名父目录的路径名字符串;如果此路径名没有指定父目
录,则返回null
getName() 返回由此抽象路径名表示的文件或目录的名称
实例:
import java.io.File;
import java.io.IOException;
public class FileTest {
public static void main(String[] args) {
//File 对象可以代表具体文件或目录
File f1 = new File("E:\\");
File f2 = new File("D:\\a.txt");
File f3 = new File("D:/d/a.txt");
File f4 = new File("D:"+File.separator+"a.txt");
//目录分隔符根据系统产生分隔符window \ Linux /
System.out.println(File.separator);
File f5= new File("D:/","a.txt");
File f6 = new File(f1,"a.txt");
try {
/**
* 创建新文件只能创建文件,不能创建目录
*/
f2.createNewFile();
//f3.createNewFile(); 找不到D:/d 目录但不会自动创建
/**
* 创建目录mkdir() 注意:只能创建一层文件夹
*/
File f7 = new File("D:/d");
f7.mkdir();
File f8 = new File("D:/e/e");
System.out.println(f8.mkdir());
/**
* 创建多层目录mkdirs()
*/
f8.mkdirs();
/**
* 重命名
*/
File f9 = new File("a.txt");
f9.createNewFile();
f9.renameTo(new File("b.txt"));
System.out.println(f3.exists());
/**
* 获得文件目录直接包含文件名数组list()
*/
String [] names = f1.list();
for(String name:names){
System.out.println(name);
}
/**
* 路径
*/
System.out.println(f9.getPath());
System.out.println(f9.getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
}
}
}
11.(1)文件字节输入输出流:
当创建一个文件输入流时源文件必须存在且能被读
FileInputStream(File file)
FileInputStream(String name)
当创建文件输出流时,若文件不存在则创建文件,否则覆盖文件
FileOutputStream(File file)
FileOutputStream(File file, boolean append)
FileOutputStream(String name)
FileOutputStream(String name, boolean append)
(2)文件字符输入输出流:
方便了字符文件的读/写
FileReader(File file)
FileReader(String name)
FileWriter(File file)
FileWriter(String filename)
12.带有缓冲区的字节输入输出流
对输入输出流进行缓冲,从而提高性能
BufferedInputStream(InputStream in)
BufferedInputStream(InputStream in, int size)
BufferedOutputStream(OutputStream out)
BufferedOutputStream(OutputStream out, int size)
实例:
public class BufferedStreamTest {
public static void main(String[] args) {
File f1 = new File("1.txt");
File f2 = new File("3.txt");
FileInputStream fis;
try {
fis = new FileInputStream(f1);
BufferedInputStream bis = new BufferedInputStream(fis);
FileOutputStream fos = new FileOutputStream(f2);
BufferedOutputStream bos = new BufferedOutputStream(fos);
int b =0;
while((b=bis.read())!=-1){
bos.write(b);
}
bos.flush();
bos.close();
bis.close();
fos.close();
fis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}

1.txt
目的
2.txt
FileInputstream Buffer Fileoutputstream 内存
BufferedInputStream
BufferedOutputStream
m
综合实例:
import java.io.File;
import java.io.IOException;
public class FileTest2 {
public static void printFile(File f){
System.out.println(f.getName());
if(f.isDirectory()){
String [] names = f.list();
for(String name:names){
printFile(new File(f,name));
}
}
}
public static void main(String[] args) {
if(args.length==0){
System.out.println("请在运行时输入一个文件目录");
}else{
File f = new File(args[0]);
printFile(f);
}
}
}
12.完成一个图片的拷贝
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class ImageCopy {
/**
* 图片的拷贝
* @param args
*/
public static void main(String[] args) {
File f1=new File("1.jpg");
File f2=new File("2.jpg");
try {
FileInputStream fis = new FileInputStream(f1);
FileOutputStream fos = new FileOutputStream(f2);
int b =0;
while(( b=fis.read())!=-1){
fos.write(b);
}
fos.close();
fis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
13.读取一个文件内容,读取过程中打印每个字节,如果是q,后面不再读取打印
14.尝试打印某File 目录对象下所有文件名,并尝试打印出层次关系
public class FileNavTest {
File root;
public FileNavTest(String rootName){
root = new File(rootName);
} //展













public void showFilesList(File root,int level){
if(!root.isDirectory()){//如果不是路径就不再展现,结束该方法
return;
}else{//是路径就展现
level++;//标示是根路径的第几级
String [] fileNames = root.list();
for(int i=0;i for(int j=0;j System.out.print(" ");
} //当






String fileName = fileNames[i];
System.out.println(fileName);
//还得判断并输出此文件下的文件名
File f = new File(root,fileName);
if(f.isDirectory()){
showFilesList(f,level);
}
}
}
} public static void main(String[] args) {
FileNavTest fnt = new FileNavTest("E:/a");
System.out.println(fnt.root.getPath());
fnt.showFilesList(fnt.root, 0);
}
}
2011.8.5 周五
1.JFC 概况:
由Netscape,IBM 和Lighthouse 联合开发的一组GUI 类
使组件在外观上比AWT 组件更光滑,更美观
JFC 有五种API 组成:Swing 包含一个基于各种形式应用的组件集合
Swing 的GUI 独立于平台,就是视觉展现
AWT1.1 中的widgets 和事件模型同样适用于Swing 组件
Swing 的体系:
组件体系-与AWT 相似
新的扩展后的组件
2.JPanel 容器:
一个轻量级的Panel 对象
提供双缓存机制
构造方法:
JPanel()
JPanel(boolean doublebuffering)
JPanel(LayoutManager layout)
JPanel(LayoutManager, boolean doublebuffering)
3.Icon 图标:
并不是真正的组件
可以和所有的Swing 组件一起使用
显示固定尺寸的图片
是接口
public interface Icon {
void paintIcon( Component c, Graphics g, int x, int y);
int getIconWidth();
int getIconHeight(); }
ImageIcon 类是Icon 的实现类
4.JLabel 标签:
是一个单行标签
附加功能
增加一个图标
设置文本和图标之间水平和垂直的相对位置
设置组件内部各内容之间的相对位置
构造方法:
JLabel()
JLabel(Icon image)
JLabel(Icon image, int?alignment)
JLabel(String text)
JLabel(String text, Icon image, int alignment)
JLabel(String text, int alignment)
5.JButton 按钮:
和awt 中的Button 类似
当按下按钮时产生一个触发ActionListener 事件
构造方法:
JButton()
JButton(Action a)
JButton(Icon image)
JButton(String text)
JButton(String text, Icon image)
6.JCheckBox 复选框:
JCheckBox 与一个不在AWT CheckboxGroup 中的Checkbox 类似
构造方法:
JCheckBox()
JChecBox(Action a)
JCheckBox(Icon image)
JCheckBox(Icon image, boolean selected)
JCheckBox(String text)
JCheckBox(String text, boolean selected)
JCheckBox(String text, Icon image)
JCheckBox(String text, Icon image, boolean selected)
7.JRadioButton 单选钮:
相当于AWT 中的一组在CheckBoxGroup 中的Checkbox
属于ButtonGroup
构造方法:
JRadioButton()
JRadioButton(Action a)
JRadioButton(Icon image)
JRadioButton(Icon image, boolean selected)
JRadioButton(String text)
JRadioButton(String text, boolean selected)
JRadioButton(String text, Icon image)
JRadioButton(String text, Icon image, boolean selected)
8.JToggleButton
JCheckBox 和JRadioButton 的父类
没有相同功能的AWT
构造方法:
JToggleButton()
JToggleButton(Action a)
JToggleButton(Icon image)
JToggleButton(Icon image, boolean selected)
JToggleButton(String text)
JToggleButton(String text, boolean selected)
JToggleButton(String text, Icon image)
JToggleButton(String text, Icon image, boolean selected)
9.JScrollPane 滚动区:
类似于java.awt.ScrollPane
它使用ScrollPaneLayout 布置组件
Swing 提供了一个JViewport 对象,为对象增加滚动区
构造方法:
JScrollPane()
JScrollPane(Component view)
JScrollPane(Component view, int vsbPolicy, int hsbPolicy)
JScrollPane(int vsbPolicy, int hsbPolicy)
10.Viewports 可视区域:
11.JTextComponentsm 文本组件:
JTextComponent 是一个包含所有希望在简单文本编辑器上的功能的通用的类
有五个子类:JTextField, JTextArea, JEditorPane, JPasswordField and JTextPane
通用方法:
copy()
cut()
paste()
getSelectedText()
setSelectionStart()
setSelectionEnd()
selectAll()
replaceSelection()
getText()
setText()
setEditable()
setCaretPosition()
(1)JTextField and JTextArea
类似AWT 的TextField 和TextArea
支持用setHorizontalAlignment()方法调整文本的对齐方式
JTextField 构造方法:
JTextField()
JTextField(Document doc, String text, int cols)
JTextField(int cols)
JTextField(String text)
JTextField(String text, int cols)
JTextArea 构造方法:
JTextArea()
JTextArea(Document doc)
JTextArea(int cols, int rows)
JTextArea(Document doc, String text, int cols, int rows)
JTextArea(String text)
JTextArea(String text, int cols, int rows)
(2)JTextPane 文本容器
支持格式化的文本,如显示图像等
使用一组相关的对象实现Style(风格)接口,指定文本的格式并提供了简便的操作方法
来格式化文本
构造方法:
JTextPane()
JTextPane(StyledDocument doc)
(3)JPasswordField 密码框
是一个不显示其真实内容的JTextField
构造方法:
JPasswordField()
JPasswordField(Document doc, String text, int cols)
JPasswordField(int cols)
JPasswordField(String text)
JPasswordField(String text, int cols)
其他方法:
setEchoChar()
getPassword()
(4)JEditorPane 编辑器容器
一种特殊的JTextComponent 组件,用来显示和编辑HTML 3.2 标签或一些其他的像
RTF 一样的格式(rich text format) 文本内容
可以用带有URL 参数的构造一个Pane,或者可以用setPage()方法改变页面。
构造方法:
JEditorPane()
JEditorPane(String url)
JEditorPane(String type, String text)
JEditorPane(URL page)
12.JScrollBar 滚动条:
是Java.awt.Scrollbar 的轻量级版本
构造方法:
JScrollBar()
JScrollBar(int orientation)
JScrollBar(int orientation, int value, int extent, int min, int max)
13.JSlider 滑块
类似于滚动条的功能
显示跳跃的最小数量级单位(tick)
用JSlider 可以在轴向上放置label,也可以是一系列的组件
构造方法:
JSlider()
Jslider(BoundedRangeModel brm)
JSclider(int orientation)
JSlider(int min, int max)
JSlider(int min, int max, int value)
JSlider(int orientation, int min, int max, int value)
其他方法:
addChangeListener()
14.JProgressBar 进度条
反映运行的状态
怎样使用?
Initialize the JProgressBar: //初始化
JProgressBar progressBar = new JProgressBar();
progressBar.setMinimum(0);
progressBar.setMaximum(numberSubOperations);
Repeat each time you want to perform an operation: //循环
progressBar.setValue(progressBar.getMinimum());
for (int i = 0; i < numberSubOperations; i++) {
// Perform sub-operation I
// Update bar value in event thread
// Where runner is created outside for loop
SwingUtilities.invokeAndWait(runner);
}
Outside the for-loop, create the Runnable object //创建线程
Runnable runner = new Runnable() {
public void run() {
int value = progressBar.getValue();
progressBar.setValue(value+1);
}
};
构造方法:
JProgressBar()
JProgressBar(BoundedRangeModel brm)
JProgressBar(int orientation)
JProgressBar(int min, int max)
JProgressBar(int orientation, int min, int max)
其他方法:
addChangeListener()
15.JComboBox 下拉框
类似AWT 的Choice 组件, 但重新命名了一些方法并提供了一个可编辑的选项
构造方法:
JComboBox()
JComboBox(ComboBoxModel model)
JComboBox(Object[] items)
JComboBox(Vector items)
其他方法:
addActionListener()
addItemListener()
16.JList 列表框
具有即简单(非MVC)又可以做出复杂界面的两个特点
在某些情况下,它类似于一个AWT List 组件
构造方法:
JList()
JList(ListModel dataModel)
JList(Object[] items)
JList(Vector items)
17.Borders 边框
javax.swing.border 包由一些可以描绘组件边框的一些列的类组成
它们都实现了Border 接口
public Insets getBorderInsets(Component c)
public boolean isBorderOpaque()
public void paintBorder (Component c, Graphics g, int x, int y, int width, int height)
九种Border 类:
AbstractBorder – 一个实现了Border 类的抽象类,什么都没做
BevelBorder – 一个3D 的边框可以凸出也可以凹进
CompoundBorder –一个可以嵌套多个边框的border
EmptyBorder- 一个对于没画边框的保留边框的空间的border
EtchedBorder – 一个不是凸出或凹进的一个沟状的Border
LineBorder-一个单颜色的,具有任意厚度的border
MatteBorder –一个允许由图标或者颜色编织而成的border
SoftBevelBorder- 一个带有圆滑边角的3D border
TitledBorder 一个允许在任意位置添加标题的border
18.Menus 菜单
与AWT 中的类似
所有的菜单类都是JComponent 的子类
一个新的菜单类,JRadioButtonMenuItem
可以将JMenuItem 和Icon 对象关联起来
19.JPopupMenu 弹出菜单
在任意组件中提供与上下文相关的菜单
工作原理类似于AWT PopupMenu 类
构造方法:
JPopMenu()
JPopMenu(String label)
20.框架和窗口
(1)JToolBar
以工具条的形式来排列组件的容器
可以浮动
构造方法:
JToolBar()
JToolBar(int orientation)
JToolBar(String name)
JToolBar(String name, int orientation)
(2)JTabbedPane Tab 容器
提供Tab 键来快速获取面版组件
构造方法:
JTabbedPane()
JTabbedPane(int tabPlacement)
JTabbedPane(int tabPlacement, int tabLayoutPolicy)
(3)JSplitPane 可分割容器
使用户在一个容器内对两个组件可以控制其大小
构造方法:
JSplitPane()
JSplitPane(int orientation)
JSplitPane(int orientation, boolean continuousLayout)
JSplitPane(int orientation, boolean continuousLayout, Component left, Component right)
JSplitPane(int orientation, Component left, Component right)
21.Swing Layouts--BoxLayout
允许按照任意的XY 轴排列组件
组件不能够重叠
以组件的首选宽或高来排列
构造方法:
BoxLayout(Container target, int axis)
22.Box 盒式
一种默认布局管理器是BoxLayout 的方便的容器
构造方法:
Box(int axis)
实例:
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class SwingTest {
public static void main(String[] args) {
JFrame jf = new JFrame("SwingTest");
/**
* 先获得JFrame的容器对象Container c
* 然后使用容器对象c来设置布局及添加组件
* 原因:部分组件不会默认添加到Container,如果使用JFrame添加
* 就会造成添加无效果,所有我们所有组件使用Container来添加
*/
Container c = jf.getContentPane();
c.setLayout(new FlowLayout());
JButton b1 = new JButton("按钮");
final JLabel l = new JLabel("显示信息");
c.add(b1);c.add(l);
b1.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
l.setText("按钮点击了");
}
});
//JFrame设置默认关闭方式
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setBounds(300, 400, 300, 300);
jf.setVisible(true);
}
}
综合实例:
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.*;
public class SwingComponent {
public static void main(String[] args) {
JFrame jf = new JFrame("SwingTest");
Container c = jf.getContentPane();
c.setLayout(new FlowLayout(FlowLayout.LEFT));
/**
* JLabel 可以放图片
*/
JLabel l1 = new JLabel("标签");
c.add(l1);
Icon img = new ImageIcon("阿杜.jpg");
JLabel l2 = new JLabel(img);
c.add(l2);
//复选框
JCheckBox box1 = new JCheckBox("足球");
JCheckBox box2 = new JCheckBox("篮球");
JCheckBox box3 = new JCheckBox("乒乓球");
c.add(box1);c.add(box2);c.add(box3);
// 单选按钮
JRadioButton rb1 = new JRadioButton("男",true);
JRadioButton rb2 = new JRadioButton("女",true);
ButtonGroup group = new ButtonGroup();//组
group.add(rb1);group.add(rb2);
c.add(rb1);c.add(rb2);
/**
* 文本
*/
final JTextField jtf = new JTextField(10);
c.add(jtf);
final JPasswordField jpf = new JPasswordField(10);
c.add(jpf);
JButton jb1 = new JButton("登录");
jb1.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
//用户名admin 密码1234 打印登录成功否则失败
/*String name = jtf.getText();
String pwd = jpf.getText();*/
char[] pwds = jpf.getPassword();
String pwd = new String(pwds);
if("admin".equals(jtf.getText())
&&"1234".equals(pwd)){
System.out.println("登录成功");
}else{
System.out.println("登录失败");
}
}
});
c.add(jb1);
/**
* JComboBox 下拉选择框AWT--Choice 没有JChoice
* JComboBox(Object[] items)
* JComboBox(Vector items)
*/
final JComboBox jcb = new JComboBox();
jcb.addItem("----------");
jcb.addItem("大陆");
jcb.addItem("港台");
jcb.addItem("欧美");
jcb.addItem("新加坡");
c.add(jcb);
//事件
jcb.addItemListener(new ItemListener(){
@Override
public void itemStateChanged(ItemEvent e) {
//也会执行两遍控制功能代码只执行一遍
if(e.getStateChange()==ItemEvent.SELECTED){
//获得选中项
String str = (String)jcb.getSelectedItem();
System.out.println(str);
//设置选中某一项
//jcb.setSelectedIndex(1);
}
}
});
/**
* 页签选项卡JTabbedPane
*/
JTabbedPane tab1 = new JTabbedPane();
tab1.addTab("音乐", new JLabel("选择音乐目录"));
tab1.addTab("电影", new JLabel("选择电影目录"));
c.add(tab1);//c.add(tab2);
//JFrame设置默认关闭方式
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setBounds(300, 400, 300, 300);
jf.setVisible(true);
}
}
实例2:
public class SwingComponentJList {
public static void main(String[] args) {
JFrame jf = new JFrame("SwingTest");
Container c = jf.getContentPane();
//设置菜单条
//jf.setJMenuBar(menubar);
Icon img = new ImageIcon("阿杜.jpg");
JLabel l2 = new JLabel(img);
c.add(l2,BorderLayout.NORTH);
/**
* 页签选项卡JTabbedPane
*/
JButton bt = new JButton("按钮");
bt.setName("按钮");
JTabbedPane tab1 = new JTabbedPane();
tab1.add(bt);
tab1.addTab("音乐", new JLabel("选择音乐目录"));
tab1.addTab("电影", new JLabel("选择电影目录"));
c.add(tab1,BorderLayout.NORTH);
/**
* JList
* JList(Object[] listData)
* 构造一个JList,使其显示指定数组中的元素。
* JList(Vector listData)
* 构造一个JList,使其显示指定Vector 中的元素。
* 本身没有滚动条,要想有滚动条,必须将JList放入滚动区JScrollPane
*/
String [] ls =
{"aaaaaa","bbbbbb","cccccc","ddddddd","aaaaaa","bbbbbb","ccccc
c","ddddddd"};
JList list = new JList(ls);
//选择“ 大陆” 学会清空添加数据
list.removeAll();//不起作用
Vector v = new Vector();
v.add("11111111");
v.add("11111111");
v.add("11111111");
v.add("11111111");
v.add("11111111");
v.add("11111111");
v.add("11111111");
v.add("11111111");
//添加数据setListData(Object[]) setListData(Vecot v)
list.setListData(v);
//清空
//list.setListData(new Vector());
//JList 事件
list.addListSelectionListener(new ListSelectionListener(){
@Override
public void valueChanged(ListSelectionEvent e) {
//会执行两遍我们真正执行功能代码控制执行1次
boolean flag = e.getValueIsAdjusting();
if(flag){
System.out.println("选中了。。。。。");
}
}
});
TitledBorder b = new TitledBorder("音乐列表");
//c.add(list);
/*//创建一个滚动区,
JScrollPane jsp = new JScrollPane();
//将JList组件放入,
//jsp.add(list);//错误的因为没有将组件放入滚动区的可视区
//正确先获得滚动区的可视区对象JViewport,然后添加组件到JViewport
jsp.getViewport().add(list);*/
//创建滚动区同时将组件添加到滚动区的可视区
JScrollPane jsp = new JScrollPane(list);
//然后将滚动区添加到c容器
c.add(jsp);
//给滚动区添加边框
jsp.setBorder(b);
//JFrame设置默认关闭方式
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setBounds(300, 400, 300, 300);
jf.setVisible(true);
}
}
2011.8.8 周五
1.文字也可以用字节流读写--文件存在则覆盖掉
FileOutputStream(File file, boolean append) 创建一个向指定File 对象
表示的文件中写入数据的文件输出流,如果第二个参数为true,则将字节写入文件末尾
处,而不是写入文件开始处.
2.控制写入换行fos.write(‘\n’);
3.DataInputStream and DataOutputStream 数据输入输出流- 处理流
能够应用于Java 原始类型的读写操作构造方法
DataInputStream(InputStream in)
DataOutputStream(OutputStreamout)
其他方法
readBoolean()/writeBoolean()
readByte()/writeByte() 从所包含的输入流中读取此操作需要的字节
readChar()/writeChar() 从包含的输入流中读取此操作需要的字节
ReadInt()/WriteInt(i) 返回/写入整数
怎样写入代码就要怎样输出代码。
写入1-10
实例:
import java.io.*;
/**
* 数据流专门针对原始类型
*/
public class DataStreamTest {
public static void main(String[] args) {
try {
DataOutputStream dos //写(内容看不懂)
= new DataOutputStream(new FileOutputStream("c.txt"));
for(int i=0;i<=10;i++){
dos.writeInt(i);
} dos.writeDouble(0.1);
dos.close();
DataInputStream dis //读
= new DataInputStream(new FileInputStream("c.txt"));
for(int i=0;i<=10;i++){
int b = dis.readInt();
目的
文件
C.txt
Dataoutputstream fileoutputstrea
System.out.println(b);
} System.out.println(dis.readDouble());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
} 4.PipedInputStream and PipedOutputStream 管






一个管道输入流连接一个管道输出流
是一种线程之间交换数据的通讯方法
构造方法
PipedInputstream()
PipedInputStream(PipedOutputStream src)
PipedOutputStream()
PipedOutputStream(PipedInputStream sink)
5.Reading and Writing with RandomAccessFile 随机存取文件流的读/写
实现了DataInput 和DataOutput 接口
当打开一个文件时,提供了即能读又能写的能力
通过使用文件指针可以对文件的特定位置读写
构造方法
RandomAccessFile(File file, String mode)
RandomAccessFile(String filename, String mode)
其他方法
read()/write() seek(long pointer)
6.PrintStream 字节打印输出流既是节点流又是处理流注意:内容会覆盖
构造方法
PrintStream(File file)
创建具有指定文件且不带自动行刷新的新打印流。
PrintStream(File file, String csn)
创建具有指定文件名称和字符集且不带自动行刷新的新打印流。
PrintStream(OutputStream out)
创建新的打印流。
PrintStream(OutputStream out, boolean autoFlush)
创建新的打印流。
PrintStream(OutputStream out, boolean autoFlush, String encoding)
创建新的打印流。
PrintStream(String fileName)
创建具有指定文件名称且不带自动行刷新的新打印流。
PrintStream(String fileName, String csn)
创建具有指定文件名称和字符集且不带自动行刷新的新打印流。
其它方法:
Void print()打印对象。
Void void()将指定的字节写入此流。
static PrintStream out “标准”输出流、类型是PrintStream
PrintStream(OutputStream out, boolean autoFlush, String encoding) 创建新的打印流。
实现追加用处理流在OutputStream 指明可追加
System.Out Out 是标准输出流打印数据到控制台
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
/**
* 字节打印流
* 既是节点流又是处理流
*/
public class PrintStreamTest {
public static void main(String[] args) {
try {
//PrintStream ps = new PrintStream("d.txt");
PrintStream ps = new PrintStream(new FileOutputStream("d.txt",true));
ps.println("adsfadsfsadf");
ps.println(1212);
ps.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
思考:
如何将数据输出到文件Log.txt?
//static void setOut(PrintStream out) 重新分配“标准”输出流。
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
public class OutTest {
public static void main(String[] args) {
/**
* System.out out 标准输出流
* 打印数据到控制台
*/
System.out.println("out 是标准输出流,输出到控制台");
/**
* 将System.out.println()输出内容到文件log.txt
*/
try {
System.setOut(new PrintStream(new FileOutputStream("log.txt",true)));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
System.out.println("out 输出内容内容进入log 日志文件");
}
}
如果要让整个工程起作用,写一个类:
public class Debug {
static{
try {
System.setOut(new PrintStream
(new FileOutputStream("log.txt",true)));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
} public static void debug(Class c,Object o){
System.out.println(c.getName()+"==="+new Date()+"==="+o);
}
}调用:
public class DebugTest {
public static void main(String[] args) {
System.out.println("hello");
Debug.debug(DebugTest.class, "hello");
}}
7.Unicode 编码和其他编码之间的转换
Encoding String Description
8859_1 ISO Latin-1
8859_2 ISO Latin-2
8859_3 ISO Latin-3
Cp037 USA, Canada (Bilingual, French),
Netherlands, Portugal, Brazil, Australia
Cp1046 IBM Open Edition US EBCDIC
Cp850 PC Latin-1
ISO2022CN ISO 2022 CN, Chinese
MacRoman Macintosh Roman
UTF8 Standard UTF-8
可追加
常用:GB2312:简体中文
GBK 国标码(简体+繁体)默认是GBK
UTF-8 通用码(简体+繁体+英文)
注意:解码要与编码同步
String(byte[] bytes, String charsetName)
通过使用指定的charset 解码指定的byte 数组,构造一个新的String。
public class CharacterEcodingTest {
public static void main(String[] args) {
String str = "中国";
try {
Strings tr2= new String(str.getBytes("ISO-8859-1"),"GBK");
System.out.println(str);
System.out.println(str2);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
} 8.Reader and Writer 字



/





Reader和Writer是用于读写字符流的抽象类
他们的子类必须实现:
read(char[], int, int)
write(char[], int, int)
close()
flush()
Reader:
BufferedReader, CharArrayReader, FileReader, InputStreamReader, PipedReader, StringReader
Writer:
BufferedWriter, CharArrayWriter, FilterWriter, OutputStreamWriter, PipedWriter, PrintWriter,
StringWriter
Reader构造方法:
Reader() 创建一个新的字符流reader,其重要部分将同步其自身的reader。
Reader(Object lock) 创建一个新的字符流reader,其重要部分将同步给定的对象。
Writer构造方法:
Writer() 创建一个新的字符流writer,其关键部分将同步writer 自身。
Writer(Object lock) 创建一个新的字符流writer,其关键部分将同步给定的对象。
9.FileReader and FileWriter 文件字符输入/输出流节点流
方便了字符文件的读/写
构造函数
FileReader(File file)
FileReader(String name)
FileWriter(File file)
FileWriter(String filename)
public class FileNavTestReader {
public static void main(String[] args) {
File src = new File("src/sample/FileNavTest.java");
try {
FileInputStream fis = new FileInputStream(src);
int b =0;
while((b=fis.read())!=-1){
System.out.print((char)b);
} fis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} File src =
new File("src/sample/FileNavTest.java");
try {
FileReader fr = new FileReader(src);
int b = 0;
while((b=fr.read())!=-1){
System.out.print((char)b);
} fr.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}1
10.BufferedReader and BufferedWriter带有缓冲区的字符输入/输出流处理流可以读一行
PrintWriter 向文本输出流打印对象的格式化表示形式
对字符进行缓冲从而提高读/写字符的效率
构造函数:
BufferedReader(Reader in)
BufferedReader(Reader in, int size)
BufferedWriter(Writer out)
BufferedWriter(Writer out, int size)
PrintWriter :
构造方法摘要
PrintWriter(File file) 字节流
使用指定文件创建不具有自动行刷新的新PrintWriter。
PrintWriter(File file, String csn) 字节流
创建具有指定文件和字符集且不带自动刷行新的新PrintWriter。
PrintWriter(OutputStream out)
根据现有的OutputStream 创建不带自动行刷新的新PrintWriter。
PrintWriter(OutputStream out, boolean autoFlush)
通过现有的OutputStream 创建新的PrintWriter。
PrintWriter(String fileName)
创建具有指定文件名称且不带自动行刷新的新PrintWriter。
PrintWriter(String fileName, String csn)
创建具有指定文件名称和字符集且不带自动行刷新的新PrintWriter。
PrintWriter(Writer out) 创建不带自动行刷新的新PrintWriter。
PrintWriter(Writer out, boolean autoFlush) 创建新PrintWriter。
其他方法
readLine() 读一行
newLine () 产生一个空行
Flush() 自动刷新
BufferedReader实例:
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class BufferedReaderTest {
public static void main(String[] args) {
try {
//带缓冲的字符输入流可以readLine()读一行
BufferedReader br =
new BufferedReader(new FileReader("music.db"));
String str ="";
while((str=br.readLine())!=null){
System.out.println(str);
}
br.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
PrintWriter实例:
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class PrintWriterTest {
public static void main(String[] args) {
try {
//创建字符打印流自动刷新
PrintWriter pw = new PrintWriter(new FileWriter("e.txt"),true);
pw.println("printwriter 写数据");
pw.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
11.InputStreamReader and OutputStreamWriter 字节和字符之间转换的输入输出流(桥梁流)
InputStreamReader 是字节流转换字符流的桥梁
outputStreamWriter 是字符流转换字节流的桥梁
构造方法
InputStreamReader(InputStream in, String charsetName)
OutputStreamWriter(OutputStream out, String charsetName)
读键盘输入的一行内容:
BufferedReader br =
new BufferedReader(new InputStreamReader(System.in));
String str = br.readLine();
public class PrintWriterTest2 {
public static void main(String[] args) {
try {
/**
* 通过键盘输入数据System.in InputStream
* 要读键盘输入的一行数据要使用BufferedReader
* BufferedReader(Reader r) 无法嵌套InputStream
* 考虑:桥梁流
* Reader<---InputStreamReader(InputStream in)
*/
System.out.println("等待键盘输入数据:");
BufferedReader br =
new BufferedReader(new InputStreamReader(System.in));
//键盘输入的一行数据
String str = br.readLine();
PrintWriter pw=newPrintWriter(newFileWriter("e.txt"),true);
pw.println(str);
pw.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
} 12.Serilization 序


对象持久化
只有对象的数据被持久化了
临时数据不能被序列化
对象必须实现java.io.Serializable接口
* 类要想持久化要想使用对象流传递对象类必须实现序列化
* 类实现Serializable接口没有任何抽象方法就是序列化的标志
public class Student implements Serializable{
//private transient String name; 临时数据不能被序列化
private String name;
private int age;
13.ObjectInputStream and ObjectOutputStream 对象输入/输出流
应用于对象的数据的持久化操作
用ObjectOutputStream序列化对象,然后用OjbectInputStream再逆序列化改对象。
构造方法
ObjectInputStream(InputStream in)
ObjectOutputStream(OutputStream out)
其他方法
readObject()
writeObject()
public class ObjectStreamTest {
public static void main(String[] args) {
Student st1 = new Student("zhangsan",20);
try {
ObjectOutputStream oos = new ObjectOutputStream(new
FileOutputStream("stu.txt"));
//对象的序列化
oos.writeObject(st1);
oos.flush();
oos.close();
ObjectInputStream ois = new ObjectInputStream(new
FileInputStream("stu.txt"));
//对象的反序列化
Student s = (Student) ois.readObject();
System.out.println(s.getName()+" "+s.getAge());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
2011.8.9 周三
1.网络基础知识:
IP:给我们电脑提供唯一标志地址
TCP/IP协议
OSI参考模型TCP/IP 参考模型
应用层
------
表示层应用层(app)
------
会话层
----------------------------------------------------
传输层传输层(TCP/IP)
----------------------------------------------------
网络层网络层(IP)
----------------------------------------------------
数据链路层
------- 物理层+数据链路层
物理层
--------------------------------------------------------
TCP:可靠的、端到端的字节流通信协议,它是一种面向连接的协议。例如:打电话。
UDP:向应用提供了一种发送封装的原始IP数据报的方法、并且发送时无需建立连接。是一
种不可靠的连接。例如:语音、视频。
区别: TCP:可靠,慢
UDP:不可靠,快。所谓的不可靠就是网络不好出现的丢包的现象。
2.Socket---中文:插座
(1)两个Java应用程序可以通过一个双向的网络通信连接实现数据交流,这个双向链路的
一端称为一个Socket。我们所说的Socket编程就是在两个应用端分别两个Socket端,然
后让两个端中间相连就实现了两个应用连接。Socket通常用来实现Client-server连接
即cs结构应用
(2)类:java.net包中定义的两个类Socket和ServerSocket,分别用来实现双向连
接的Client和server端。
(3)建立连接时我们需要连接计算机的ip地址和端口号(port)
端口号:区分不同的应用程序。两个字节,最多65536个。我们记住前面的1024个
已经为系统的一些应用分配了, 我们自己应用时候用1024以上的。比如80端口是http应
用的默认端口,21是ftp默认端口等。Tomcat 8080 Mysql 3306 Oracle 1521
TCP端口和UDP端口是分开的,分别有65536个端口。
TCP Socket 编程模型
两个主要类: Socket ServerSocket
3.一个套接字就是网络上两个程序的双向连接的通信端点
套接字必须绑定一个端口号,从而使TCP层能识别数据应该被传送的目的地。
网络地址
Host Name(主机名)mydomain.com
Address( 地址) 203.93.63.237
端口号:0~65535
JAVA 网络模型:
4.Socket:客户端
构造方法:
Socket() 创建未连接套接字
Socket(String host, int port) 创建一个流套接字并将其连接到指定主机上的指定端口号
Socket(InetAddress address, int port)创建一个流套接字并将其连接到指定IP 地址的指定端口号
其他方法:
getInputStream() 返回此套接字的输入流
getOutputStream() 返回此套接字的输出流。
close() 关闭此套接字
getPort() 返回此套接字连接到的远程端口。
getLocalPort() 返回此套接字绑定到的本地端口。
getInetAddress() 返回套接字连接的地址。
bind(SocketAddress bindpoint) 将套接字绑定到本地地址。
getLocalAddress() 获取套接字绑定的本地地址。
5.ServerSocket 服务器端注意:只能启动一次
构造方法:
ServerSocket() 创建非绑定服务器套接字
ServerSocket(int port) 创建绑定到特定端口的服务器套接字
ServerSocket(int port, int backlog)
其他方法:
accept() 侦听并接受到此套接字的连接。
close() 侦听并接受到此套接字的连接。
6.网络传输的步骤:
(1)建立连接
(2)通过流发送和读取消息
(3)关闭资源
7.获得IP 地址:
InetAddress ip=InetAddress.getByName("http:\\baidu.com");
输出:119.75.210.45
8.一个服务器端可以同时接收多个客户端,将Accept()放在While 循环中
实例1:简单的网络编程实例
public class Server {
public static void main(String[] args) {
try {
//创建一个服务器对象
ServerSocket server = new ServerSocket(8888);
//接收客户端连接返回接收到的客户端对象停滞等待客户端连接上
System.out.println("---服务器已经启动,等待客户端连接---");
Socket client = server.accept(); //会停滞
System.out.println("======客户端连接上了======");
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class Client{
public static void main(String[] args) {
try {
//创建客户端对象并同时建立服务器连接
Socket client = new Socket("127.0.0.1",8888);
client.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
实例2:服务器与客户端相互发消息
public class Server {
public static void main(String[] args) {
try {
//创建一个服务器对象
ServerSocket server = new ServerSocket(8888);
//接收客户端连接返回接收到的客户端对象停滞等待客户端连接上
System.out.println("---服务器已经启动,等待客户端连接---");
Socket client = server.accept();
System.out.println("======客户端连接上了======");
//向客户端写信息
PrintWriter pw =
new PrintWriter(client.getOutputStream());
pw.println("客户端你好,你已经连接上服务器");
pw.flush();
//创建流读服务器端写过来的数据
BufferedReader br =
NewBufferedReader(NewInputStreamReader(client.getInputStream()));
String str = br.readLine();
System.out.println(str);
br.close();
pw.close();
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} public class Client{
public static void main(String[] args) {
try {
//创建客户端对象并同时建立服务器连接
Socket client = new Socket("127.0.0.1",8888);
//创建流读服务器端写过来的数据
BufferedReader br =
new BufferedReader(
newInputStreamReader(client.getInputStream()));
String str = br.readLine();
System.out.println(str);
//向服务器写数据
PrintWriter pw =
new PrintWriter(client.getOutputStream());
pw.println("客户端:服务器您好");
pw.flush();
pw.close();
br.close();
client.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
实例3:服务器和客户端都从键盘读取消息并发送给对方
public class Server{
public static void main(String[] args) {
try {
ServerSocket server = new ServerSocket(10000);
System.out.println("服务器已经启动.........");
Socket client = server.accept();
//读键盘获得数据System.in br1.readLine()读键盘
BufferedReader br1 = new BufferedReader(
new InputStreamReader(System.in));
//键盘写的数据
String str = br1.readLine();
PrintWriter pw =
new PrintWriter(client.getOutputStream());
pw.println(str);
pw.flush();
//读客户的信息
BufferedReader br2 = new BufferedReader(new
InputStreamReader(client.getInputStream()));
String str2 = br2.readLine();
System.out.println(str2);
br2.close();
br1.close();
pw.close();
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} public class Client3 {
public static void main(String[] args) {
try {
Socket client = new Socket("localhost",10000);
//读服务器信息
BufferedReader br1 = new BufferedReader(new
InputStreamReader(client.getInputStream()));
String str = br1.readLine();
System.out.println(str);
//读键盘
BufferedReader br2 = new BufferedReader(new
InputStreamReader(System.in));
String str2 = br2.readLine();
//写数据给服务器
PrintWriter pw=new
PrintWriter(client.getOutputStream(),true);
pw.println(str2);
br1.close();
br2.close();
pw.close();
client.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
实例4:多个客户端同时连接服务器端
public class Server{
public static void main(String[] args) {
try {
//创建一个服务器对象
ServerSocket server = new ServerSocket(8888);
//接收客户端连接返回接收到的客户端对象停滞等待客户端连接上
System.out.println("------服务器已经启动-------");
int count = 1; //计数,判断第几个客户端
while(true){ //死循环
System.out.println("------等待客户端连接-------");
Socket client = server.accept();
System.out.println("第"+ count++ +"客户端连接上了,客户端
端口号:"+client.getPort());
client.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
} public class Client4 {
public static void main(String[] args) {
try {
//创建客户端对象并同时建立服务器连接
Socket client = new Socket("127.0.0.1",8888);
client.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
综合实例:网络聊听
public class TalkServer {
public static void main(String[] args) {
try {
ServerSocket server = new ServerSocket(8888);
System.out.println("服务器准备就绪.........");
System.out.println("等待客户端连接......");
Socket client= server.accept();
//获得客户端地址
System.out.println(client.getInetAddress());
//获得服务器的端口
System.out.println(client.getLocalPort());
//获得客户自己的端口
System.out.println(client.getPort());
System.out.println("客户端连接成功,请先输入信息聊天....");
//读键盘
BufferedReader br1 =
new BufferedReader(new InputStreamReader(System.in));
//读客户端信息流
BufferedReader br2 =
new BufferedReader(new InputStreamReader(client.getInputStream()));
//向客户端写信息的流自动刷新
PrintWriter pw=new
PrintWriter(client.getOutputStream(),true);
boolean flag = true;
while(flag){
String str1 = br1.readLine();
pw.println(str1);
if("bye".equals(str1)){//服务器向客户端bye
break;
} String str2 =
br2.readLine();
System.out.println("【客户端说】:"+str2);
if("bye".equals(str2)){//客户端bye
break;
}
} pw.close();
br1.close();
br2.close();
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} public class TalkClient {
public static void main(String[] args) {
try {
Socket client = new Socket("localhost",8888);
System.out.println("连接上服务器了,等待服务器写信息....")
//读键盘
BufferedReader br1 =
new BufferedReader(new InputStreamReader(System.in));
//读服务端信息流
BufferedReader br2 =
newBufferedReader(new InputStreamReader(client.getInputStream()));
//向服务端写信息的流自动刷新
PrintWriter pw=new
PrintWriter(client.getOutputStream(),true);
boolean flag = true;
while(flag){
String str1 =br2.readLine();
System.out.println("【服务器端说】:"+str1);
if("bye".equals(str1)){//服务器受不了
break;
} String str2 =
br1.readLine();
pw.println(str2);
if("bye".equals(str2)){//客户端向服务器bye
break;
}
}
pw.close();
br1.close();
br2.close();
client.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
2011.8.10 周三
1.URL 连接
URL 和URLConnection 类封装了复杂的从远端站点的获取数据的细节问题
支持HTTP 和FTP 资源
URL url = new URL(“http://mydomain.com”)
URL url = new URL(ftp://username:[email protected])
打开一个URL 连接
URLConnection urlconn = url.openConnection()
打开一个字节输入流
InputStream in = url.openStream()
URL 类是一个统一资源定位符,标识在万维网上的资源
URL 的格式
communiction protocol://hostname:port/file
构造方法:
URL(String spec) 根据String 表示形式创建URL 对象。
URL(String protocol, String host, int port, String file)
根据指定protocol、host、port 号和file 创建URL 对象。
URL(String protocol, String host, int port, String file, URLStreamHandler handler)
根据指定的protocol、host、port 号、file 和handler 创建URL 对象。
URL(String protocol, String host, String file)
根据指定的protocol 名称、host 名称和file 名称创建URL。
URL(URL context, String spec)
通过在指定的上下文中对给定的spec 进行解析创建URL。
URL(URL context, String spec, URLStreamHandler handler)
通过在指定的上下文中用指定的处理程序对给定的spec 进行解析来创建URL。
其他方法:
equals(Object obj) 比较此URL 是否等于另一个对象。
getContent() 获取此URL 的内容。
getDefaultPort() 获取与此URL 关联协议的默认端口号。
getFile() 获取此URL 的文件名。
getHost()获取此URL 的主机名
getPort() 获取此URL 的端口号。
getProtocol() 获取此URL 的协议名称。
openConnection()
返回一个URLConnection 对象,它表示到URL 所引用的远程对象的连接。
openStream()
打开到此URL 的连接并返回一个用于从该连接读入的InputStream。
set(String protocol, String host, int port, String file, String ref)
设置URL 的字段。
2.URLConnection 抽象类
是所有连接应用程序和URL 通讯的类的父类
构造方法:
URLConnection(URL url)
构造一个到指定URL 的URL 连接。
其他方法
connect() 打开到此URL 引用的资源的通信链接
getInputStream() 返回从此打开的连接读取的输入流。
getOutputStream() 返回写入到此连接的输出流。
实例:
public class URLConnectionTest{
public static void main(String[] args){
try{
String urlName=null;
if (args.length > 0)
urlName = args[0];
else
urlName="http://www.baidu.com/index.html";
//1. get connection object of specified URL name
URL url = new URL(urlName); // create URL object
URLConnection connection = url.openConnection();
//2. connect to the URL server
connection.connect();
//3. print header fields (optional)
int n = 1;
String key;
while ((key = connection.getHeaderFieldKey(n)) != null){
String value = connection.getHeaderField(n);
System.out.println(key + ": " + value);
n++;
} //4. print convenience functions (optional)
System.out.println("----------");
System.out.println("getContentType: "+
connection.getContentType());
System.out.println("getContentLength: "+
connection.getContentLength());
System.out.println("getContentEncoding: " +
connection.getContentEncoding());
System.out.println("getDate: "+ connection.getDate());
System.out.println("getExpiration: " +
connection.getExpiration());
System.out.println("getLastModifed: " +
connection.getLastModified());
System.out.println("----------");
//5. getInputStream from the URL connection (optional)
BufferedReader in = new BufferedReader(new
InputStreamReader(connection.getInputStream()));
//6. print first 50 lines of contents (optional)
String line=null;
n = 1;
while ((line = in.readLine()) != null && n <= 50){ // read line
from page content
System.out.println(line);
n++;
} if (
line != null) System.out.println(". .
.");
in.close();
} catch (IOException exception){
exception.printStackTrace();
}
}
} 3.UDP 套


面向无连接协议、不可靠的传输、
DatagramSocket 和DatagramPacket 支持JAVA UDP 连接
(1)DatagramPacket 类
实现了一个面向无连接的报文发送服务
从一台机器到另一台机器发送每条消息,都是独立的消息,都基于一个在这个数据
包中包含到这台机器的路由信息
构造方法:
DatagramPacket(byte[] buf, int length)
构造DatagramPacket,用来接收长度为length 的数据包。
DatagramPacket(byte[] buf, int length, InetAddress address, int port)
构造数据报包,用来将长度为length 的包发送到指定主机上的指定端口号。
DatagramPacket(byte[] buf, int offset, int length)
构造DatagramPacket,用来接收长度为length 的包,在缓冲区中指定了偏移量。
DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port)
构造数据报包,用来将长度为length 偏移量为offset 的包发送到指定主机上的
指定端口号。
DatagramPacket(byte[] buf, int offset, int length, SocketAddress address)
构造数据报包,用来将长度为length 偏移量为offset 的包发送到指定主机上的
指定端口号。
DatagramPacket(byte[] buf, int length, SocketAddress address)
构造数据报包,用来将长度为length 的包发送到指定主机上的指定端口号。
(2)DatagramSocket 类
一个数据报套接字是报文传送服务的发送或接收端
构造方法:
DatagramSocket()
DatagramSocket(int port)
DatagramSocket(int port, InetAddress address)
其他方法
connect() Data port
receive()/send()
close()
地址
public class UDPServer{
public static void main(String args[]) {
UDPServer udpServer = new UDPServer();
udpServer.go();
} //获








public byte[] getTime(){
Date d= new Date();
return d.toString().getBytes(); // String -> byte[]
}
// 主要的UDP Server运行程序方法
public void go(){
DatagramSocket datagramSocket=null;//服务器端的DatagramSocket定义
DatagramPacket inDataPacket=null; //接收客户端的DatagramPacket包
DatagramPacket outDataPacket=null; //传给客户端的DatagramPacket包
InetAddress clientAddress=null; // 地址,这里是服务器获得客户端地址,
然后发送包给客户端
int clientPort; // 端口,这里是服务器获得客户端地址对应的端口,然后发送
包给客户端
byte[] msg= new byte[1024]; // 接收消息的数组
byte[] time; //发送时间的数组给客户端
try {
//1. 创建服务器的DatagramSocket,给个端口,客户端要连接这个端口
datagramSocket = new DatagramSocket(8000);//port 8000
System.out.println("!!at UDPServer localport is: " +
datagramSocket.getLocalPort());
while(true) {
// 2.初始化接收客户端包
inDataPacket = new DatagramPacket(msg, msg.length);
// 3.获得客户端包
datagramSocket.receive(inDataPacket);
客户端
Send
服务器
Receive
Data
// 4.利用客户端包可以获得客户端地址和端口
clientAddress = inDataPacket.getAddress();
clientPort = inDataPacket.getPort();
System.out.println("client HostAddress is:
"+clientAddress.getHostAddress()+ " clientPort is : "+ clientPort );
time = getTime(); //初始化需要发送到客户端的时间数组
//5. 初始化发送到客户端的包,包括两部分:发送的包和客户端地址端口
outDataPacket = new DatagramPacket(time, time.length,
clientAddress, clientPort);
//6.服务器端最后发送数据包给客户端
datagramSocket.send(outDataPacket);
}
} catch (SocketException e) {
System.out.println ("SocketException occured with
socket.");
System.out.println (e);
System.exit(1);
} catch (IOException e) {
System.out.println ("IOException occured with socket.");
System.out.println (e);
System.exit(1);
} finally{
//7.关闭Socket
datagramSocket.close();
}
}
}
public class UDPClient {
public static void main(String args[]) {
UDPClient udpClient = new UDPClient();
try {
udpClient.go();
} catch (Exception e) {
System.out.println ("Exception occured with socket.");
System.out.println (e);
System.exit(1);
}
}
public void go() throws IOException, UnknownHostException {
DatagramSocket datagramSocket=null; //客户端DatagramSocket
DatagramPacket outDataPacket=null;/发送给服务器端的DatagramPacket包
DatagramPacket inDataPacket=null;//从服务器端接收的DatagramPacket包
InetAddress serverAddress=null; // 需要定义个服务器端地址
int serverPort=8000; // 端口,这里是服务器端地址对应的端口
byte[] msg = new byte[1024]; // 发送向服务器端消息数组
// 1. 初始化DatagramSocket
datagramSocket = new DatagramSocket();
System.out.println("!!!!at UDPClient, local port is: "
+datagramSocket.getLocalPort());
// 服务器运行在本地,调用getLocalHost返回本地地址,此方法会抛出
UnknownHostException
serverAddress = InetAddress.getLocalHost();
//2. 初始化向服务器端发送的数据包,包括“ 数据包” 和“ 服务器地址端口”
两部分
//作用是服务器端接收包后获得客户端的地址和端口
outDataPacket = new DatagramPacket(msg, 1, serverAddress,
serverPort);
//3.发送数据包
datagramSocket.send(outDataPacket);
//4.初始化从服务器端传输过来的数据包.
inDataPacket = new DatagramPacket(msg, msg.length);
//5. 接收服务器端传输来的数据包
datagramSocket.receive(inDataPacket);
//6.转换byte[]成字符串: byte[] -> String
String receivedMsg = new String(inDataPacket.getData(), 0,
inDataPacket.getLength());
System.out.println(receivedMsg); //打印消息
//7.关闭socket
datagramSocket.close();
}
}
4.Thread 线程静态
一个线程就是一个程序内部独立的流程控制序列代码
可以处理一系列指令的软件引擎
线程并发运行,相互独立
java.lang.Thread 包
线程的相关要素:
Processor 处理器
Code 代码
Data 数据
Java 多线程机制
当启动一个线程时, 执行的是在“public void run()”方法中的代码
创建java线程的两种方式:
extending the class Thread 继承Thread 类
implementing the interface Runnable 实现Runnable 接口
CPU
Code Data
A thread or
execution context
(1)通过继承Thread 类定义线程类
Dinfining 定义
public class MyThread extends Thread {
public void run() {…}
}
Instantiating 初始化
MyThread testTthread = new MyThread()
构造函数:
Thread()
Thread(Runnable target)
方法
run()
start()
(2)通过扩展Runnable 接口定义线程类
Difining 定义
public class MyRunnable implements Runnable {
public void run() {…}
}
Instantiating 实例化
MyRunnable testRunnable = new MyRunnable();
Thread testThread = new Thread(testRunnable)
执行run()方法中的代码
线程第一种实现方式继承Thread
package thread;
/**
* 重写run方法
* 类对象--线程对象调用.start()启动线程
*/
public class Thread1 extends Thread {
public Thread1(){}
public Thread1(String name){
super(name);
} @
Override
public void run() {
for(int i=0;i<500;i++){
//System.out.println(this.getName()+"====="+i);
//获得当前线程实例Thread.currentThread()
System.out.println(Thread.currentThread().getName()+"====="+i);
}
}
public static void main(String[] args) {
Thread1 t1 = new Thread1("线程1");
//t1.run();//线程对象.run() 不是多线程运行,而是普通的对象调方法
t1.start();//启动线程方法虚拟机调用该线程的run 方法。
for(int i=0;i<500;i++){
System.out.println(Thread.currentThread().getName()+"====="+i);
}
}
}
线程第二种方式实现Runnable 接口
package thread;
/**
实现run方法
* 该类的实例r 只是Runnable实例
* 需要Thread t = new Thread(r);
* t.start();启动线程start方法会调用r对象的run()方法
*/
public class Thread2 implements Runnable {
@Override
public void run() {
for(int i=0;i<500;i++){
System.out.println("Thread====="+i);
}
} public static void main(String[] args) {
//t并不是线程对象只是Runnable实例
Thread2 r = new Thread2();
//r.run();
Thread t = new Thread(r);
t.start();//启动线程start会调用run();
for(int i=0;i<500;i++){
System.out.println("main====="+i);
}
}
} 5.比



线





法 通过继承Thread 类是面向对象的编程思想
扩展Runnable 接口解决了单一继承的局限性
6.线程的状态转换图
终止一个线程
使用变量标签作为终止线程的指示符
Stop()方法已经被抛弃
静态方法Thread.currentThread()返回当前线程的一个引用
调试线程
判断线程的状态isAlive()
线程的阻塞到运行
sleep() Thread.sleep(5*1000) 休眠
中断一个线程t.interrupt()
检查线程是否处于中断状态otherThread.isInterrupted()
阻塞线程otherThread.join()
实例:Sleep()
public class SleepTestThread extends Thread{
@Override
public void run() {
while(true){
Date d = new Date(); //获得当前时间
System.out.println(d);
try {
Thread.sleep(1000);//休眠1秒
} catch (InterruptedException e) {
System.out.println("t线程sleep被打断");
break;
}
}
} public static void main(String[] args) {
SleepTestThread t = new SleepTestThread();
t.start();
try {
N e w
R u n n a b le R u n n i n g
O t h e r w i s e
B lo c k e d
D e a d
B l o c k e d i n
o b j e c t ` s
w a it ( ) p o o l
B l o c k e d i n
o b j e c t ` s
lo c k p o o l
S c h e d u l e r
c o m p l e t e s
r u n ( )
s t a r t ( ) s l e e p ( )
o r
j o in ( )
s l e e p ( ) t im e o u t
o r
t h r e a od r jo i n ( ) s
i n te r u p t ( )
i n t e r u p t ( )
n o t i f y ( )
L o c k
a v a i la b l e s y n c h r o n i z e d ( )
T h r e a d s t a te s
Thread.sleep(10000);//休眠10秒
t.interrupt();//打断线程方法
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
实例:Join()
public class JoinTestThread extends Thread {
public JoinTestThread(String name){
super(name);
} @
Override
public void run() {
for(int i=0;i<500;i++){
System.out.println(Thread.currentThread().getName()+"====="+i);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
JoinTestThread t1 = new JoinTestThread("join线程1");
t1.start();//启动线程方法虚拟机调用该线程的run 方法。
for(int i=0;i<500;i++){
System.out.println(Thread.currentThread().getName()+"====="+i);
if(i==100){
try {
// t1加入(合并)到main线程中,并且main线程等待该线程t1终止,main再继续执行。
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
实例:Yield()暂停当前正在执行的线程对象,并执行其他线程
当调用yield()方法时,当前线程将会失去运行机会Thread.yield()
public class YieldTestThread extends Thread{
public YieldTestThread(String name){
super(name);
} @
Override
public void run() {
for(int i=0;i<500;i++){
System.out.println(this.getName()+"======"+i);
if(i%10==0){
//暂停当前正在执行的线程对象,并执行其他线程
this.yield();
}
}
} public static void main(String[] args) {
YieldTestThread t1 = new YieldTestThread("线程1");
YieldTestThread t2 = new YieldTestThread("线程2");
t1.start();
t2.start();
}
}
Thread常用方法:
yield() 暂停当前正在执行的线程对象,并执行其他线程。
join() 等待该线程终止。
start() 使该线程开始执行;Java 虚拟机调用该线程的run 方法。
sleep(long millis)在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)
setPriority(int newPriority) 更改线程的优先级。
getPriority() 返回线程的优先级。
setName(String name) 改变线程名称,使之与参数name 相同
getName() 返回该线程的名称。
getId() 返回该线程的标识符。
run() 如果该线程是使用独立的Runnable 运行对象构造的,则调用该Runnable
对象的run 方法;否则,该方法不执行任何操作并返回。
currentThread() 返回对当前正在执行的线程对象的引用。
考题:
1.java 中有几种方法可以实现一个线程?
java5 以前,有如下两种:
第一种:
new Thread(){}.start();这表示调用Thread 子类对象的run 方法,new Thread(){}表示一个
Thread 的匿名子类的实例对象,子类加上run 方法后的代码如下:
new Thread(){
public void run(){
}
}.start();
第二种:
new Thread(new Runnable(){}).start();这表示调用Thread 对象接受的Runnable 对象的run
方法,new Runnable(){}表示一个Runnable 的匿名子类的实例对象,runnable 的子类加
上run 方法后的代码如下:
new Thread(new Runnable(){
public void run(){
}
}
).start();
有两种实现方法,分别使用new Thread()和new Thread(runnable)形式,第一种直接调用thread 的run
方法,所以,我们往往使用Thread 子类,即new SubThread()。第二种调用runnable 的run 方法。
有两种实现方法,分别是继承Thread 类与实现Runnable接口
2.sleep() 和wait() 有什么区别?
sleep 是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他
线程,但是监控状态依然保持,到时后会自动恢复。调用sleep 不会释放对象锁。
wait 是Object 类的方法,对此对象调用wait 方法导致本线程放弃对象锁,进入等待此
对象的等待锁定池,只有针对此对象发出notify 方法(或notifyAll)后本线程才进入对象锁
定池准备获得对象锁进入运行状态
3.启动一个线程是用run()还是start()?
启动一个线程是调用start()方法,使线程就绪状态,以后可以被调度为运行状态,一个线程必须关联一些
具体的执行代码,run()方法是该线程所关联的执行代码。
2011.8.11 周四
1.线程的优先级:
设置线程的优先级setPrioirity(int)
使用优先级和让步调度线程
Public final void setPriority(int newPriority) 更改线程的优先级(级别从1-10)。
Public static final int MAX_PRIORITY 10; 线程可以具有的最高优先级。
Public static final int MIN_PRIORITY 1; 线程可以具有的最低优先级。
Public static final int NORM_PRIORITY 5; 分配给线程的默认优先级。
2.线程同步存取问题并发操作同步就是给类类型对象加锁的过程
多个线程经常在某种程度上存在信息的共享
无法保证两行代码在处理器中一个接一个的执行
Java 使用同步机制控制同步存取问题
关键字synchronized标记一组在线程中相互之间互斥的的变量
同步方法synchronized void methodA() {…}
同步代码void methodA() {
synchronized(this) {…}}
void methodB() {
//Object obj = new Object();
synchronized(obj) {…}
synchronized(互斥锁)线程同步: 在java中,为保证共享数据操作的完整性,每个
对象都对应于一个称为互斥锁的标记,这个标记保证在任一时刻只能有一个线程访问该对
象。关键字synchronized来与对象的互斥锁联系。当某个对象synchronized修饰时,
表明该对象在任一时刻只能有一个线程访问
两种方式实现同步:
1. synchronized (this){代码} 方法内同步代码区用synchronized(this)包括
synchronized (Object共享资源对象){
只能一个线程执行
}
2.synchronized void add(String name){代码} 方法前用synchronized修饰
实例:
public class ThreadSynchronizedTest implements Runnable {
Timer t = new Timer();
public void run() {
t.add(Thread.currentThread().getName());
}
public static void main(String[] args) {
ThreadSynchronizedTest test = new ThreadSynchronizedTest();
Thread t1 = new Thread(test);
Thread t2 = new Thread(test);
t1.setName("thread1");
t2.setName("thread2");
t1.start();
t2.start();
}
} class Timer{
Object o = new Object();
private static int num =0;
//public void add(String name){ 第二种
public synchronized void add(String name){
//synchronized (o){ (互斥锁)锁定当前对象一个线程开始后,执行过程中
不会有另一个线程进入
//synchronized (this){ 第一种
num++;
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name+",你是第"+num+"个使用Timer的线程!");
//}
}
}
重点:找到共享资源
3.Wait()、Notify()、NotifyAll() 都在Object 类中
wait() 在其他线程调用此对象的notify() 方法或notifyAll() 方法前,导致当前线程等待。
notifyAll() 唤醒在此对象监视器上等待的所有线程。
notify() 唤醒在此对象监视器上等待的单个线程。
通过等待和唤醒交互
通过信号系统来保证线程之间的恰当的执行顺序
两个独立的线程使用wait() 和notify()方法
当有许多线程处于等待状态时,使用notifyAll()
实例:栈的模拟
public class MyStack {
//模拟栈指针index值指向顶端元素的上一个位置压栈索引
private int index=0;
//数组存放栈数据
private int [] s = new int[10];
//Get、Set方法
public int[] getS() {
return s;
} public void setS(int[] s) {
this.s = s;
} /**
* 压栈方法
*/
public synchronized void push(int i){
if(index==s.length){//满了
System.out.println("栈满了,请等待弹栈操作.....");
try {
wait();//线程等待等待其他线程唤醒自己
} catch (InterruptedException e) {
e.printStackTrace();
}
} s[index] =
i;//压

index++;//指针上移
System.out.println("压栈执行.......压入元素:"+i);
notify();//唤醒其他等待线程
} /**
* 弹栈方法
*/
public synchronized int pop(){
int result = 0;
if(index==0){//空了
System.out.println("栈空了,请等待压栈操作........");
try {
wait();//等待其他线程唤醒自己
} catch (InterruptedException e) {
e.printStackTrace();
}
} index--;
result = s[index];
System.out.println("弹栈执行.......弹出元素:"+result);
notify();//唤醒其他等待线程
return result;
}
}
压栈线程:
public class SynPushThread extends Thread {
MyStack stack;
public SynPushThread(MyStack stack) {
super();
this.stack = stack;
} @
Override
public void run() {
for(int i=0;i<30;i++){
stack.push(i);
}
}
}
弹栈线程:
public class SynPopThread extends Thread {
MyStack stack;
public SynPopThread(MyStack stack) {
super();
this.stack = stack;
}@
Override
public void run() {
for(int i=0;i<30;i++){
stack.pop();
}
}
}
线程测试类:
public class MyStackTest {
public static void main(String[] args) {
MyStack stack = new MyStack();
SynPushThread pushThread = new SynPushThread(stack);
SynPopThread popThread = new SynPopThread(stack);
pushThread.start();
popThread.start();
}
} 4.死


线










线程的饿死或死锁环境
实例:
public class DeadLockTest implements Runnable{
protected Resource resA, resB;
public DeadLockTest(Resource r1, Resource r2) {
resA=r1;
resB=r2;
} public void run() {
// called by t
thread
write(38,36); //call write()
}
// called by run method of t thread
public void write(int num1, int num2) {
synchronized(resA){
try {
System.out.println(" write thread");
Thread.sleep(10);
}catch(Exception e){
e.printStackTrace();
} synchronized synchronized(resB){
resA.number=num1;
resB.number=num2;
System.out.println(" Resource A, number is: " + resA.number);
System.out.println(" Resource B, number is: " +resB.number );
}
}
} public int read() {
// called by main thread
synchronized(resB){
try {
System.out.println(" read thread");
Thread.sleep(10);
}catch(Exception e){
e.printStackTrace();
} synchronized synchronized(resA){
int totalNum=resA.number+resB.number;
System.out.println(" Resource A and B, total number " + totalNum);
return totalNum;
}
}
} public static void main(String[] args) {
DeadLockTest q=new DeadLockTest(new Resource(20), new Resource(30));
Thread t=new Thread(q);
t.start(); //start t Thread, call run method
q.read(); // called by main thread
}
} class Resource{
int number;
public Resource(int num){
number=num;
}
}
5.线程分两大类: 用户线程守护线程
* 用户线程:isDaemon--->false 正常应用的大部分都是用户线程
* 守护线程:将用户线程(普通线程).setDaemon(true),线程就是守护线程
守护线程运行在后台,专门服务前台用户线程,如果前台没有任何用户
线程在运行,守护线程会自动终止。
比如垃圾回收的线程就是守护线程,当类执行完(所有的用户线程执行完),
JVM 结束,垃圾回收的守护线程也会自动结束
* 开发守护线程和用户线程没有任何区别, 只需要创建线程对象后, 执行
setDaemon(true) 就将用户线程设置为守护线程。
* 注意:守护线程的设置setDaemon(true) 一定要在线程start()之前
public class DaemonThread extends Thread {
@Override
public void run() {
for(int i=0;i<100;i++){
System.out.print(this.getName()+"===="+i);
if(this.isDaemon()){ //判断是否为守护线程
System.out.println("该线程是守护线程");
}else{
System.out.println("该线程是用户线程");
} try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} public static void main(String[] args) {
DaemonThread t = new DaemonThread();
t.setName("线程1");
t.setDaemon(true);//在线程启动前设置为守护线程
t.start();
for(int i=0;i<100;i++){
System.out.println("main====="+i);
}
}
}
考题:
一个线程的run() 方法包含以下几行:
1. try{
2. sleep(100);
3. } catch(InterruptedException e) {}
假设线程没有被打断,下面的陈述哪个正确?(D)
A.代码不会被编译,因为run()方法中的异常不能被捕获.
B.线程将会停止在第二行,最多一百毫秒后就会继续执行。
C. 线程将会停止在第二行,一百毫秒后就会继续执行
D. 线程将会停止在第二行,一百毫秒后的某个时间恢复执行
2.一个线程想使第二个当前没有执行权的线程执行,那么第一个线程可以通过对第二个线
程调用yield()方法来实现吗?(B)
A. True B. False
3.下列代码向一个文件中写入了多少个字节?(C)
1. try{
2. FileOutputStream fos = new FileOutputStream(“dest”);
3. DataOutputStream dos = new DataOutputStream(fos);
4. dos.writeInt(3); 4 个字节
5. dos.writeDouble(0.001); 8 个字节
6. dos.close();
7. fos.close();
8. } catch(IOException e) {}
A. 2 B. 8 C. 12 D. 16
4.用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用?
用synchronized关键字修饰同步方法
反对使用stop(),是因为它不安全。它会解除由线程获取的所有锁定,而且如果对
象处于一种不连贯状态,那么其他线程能在那种状态下检查和修改它们。结果很难检查出真
正的问题所在。
suspend()方法容易发生死锁。调用suspend()的时候,目标线程会停下来,但却仍然
持有在这之前获得的锁定。此时,其他任何线程都不能访问锁定的资源,除非被"挂起"的线
程恢复运行。对任何线程来说,如果它们想恢复目标线程,同时又试图使用任何一个锁定的
资源,就会造成死锁。
所以不应该使用suspend(),而应在自己的Thread 类中置入一个标志,指出线程应该
活动还是挂起。若标志指出线程应该挂起,便用wait()命其进入等待状态。若标志指出线程
应当恢复,则用一个notify()重新启动线程。
5.多线程有几种实现方法?同步有几种实现方法?
多线程有两种实现方法,分别是继承Thread 类与实现Runnable 接口
同步的实现方面有两种,分别是synchronized,wait 与notify
wait():使一个线程处于等待状态,并且释放所持有的对象的lock。
sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉
InterruptedException 异常。
notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的
唤醒某一个等待状态的线程,而是由JVM 确定唤醒哪个线程,而且不是按优先级。
Allnotity():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,
而是让它们竞争。
6.当一个线程进入一个对象的一个synchronized 方法后, 其它线程是否可进入此对象的其它方法?
分几种情况:
1.其他方法前是否加了synchronized 关键字,如果没加,则能。
2.如果这个方法内部调用了wait,则可以进入其他synchronized 方法。
3.如果其他个方法都加了synchronized 关键字,并且内部没有调用wait,则不能。
4.如果其他方法是static,它用的同步锁是当前类的字节码,与非静态的方法不能
同步,因为非静态的方法用的是this。

你可能感兴趣的:(软件开发)