Java编程与实例
例3.1 实例分析变量、常量、字符串和数组的声明、创建及初始化
/变量、常量、字符串和数组的声明、创建及初始化实例分析
public class L3_1{
public static void main(String args[]){ //程序入口
final int CONST_NUM=5; //定义一个常量
byte b=3; //定义原始数据类型的变量
short s=5;
int i=12;
long l=35L;
float f=1.50f;
double d=5.68d;
boolean bool=true;
char ch='a'; //定义字符型变量
int c=ch; //char型变量值可以赋给int型变量
//无需强制类型转换,实际上是把char型变量的ASCII码值赋给int型变量
String s1="Hello World!"; //定义一个字符串
int s1_length=s1.length(); //获得s1字符串的长度
String[] str={"Shanghai","Beijing","Wuhan","Guangzhou","Shenzhen"};
//在同一行中定义一个字符串数组,并初始化数组元素
//无需说明数组的长度,系统会自动计算并分配数组所需要的内存空间
System.out.println("CONST_NUM="+CONST_NUM+"\t"+
"b="+b+"\t"+"s="+s+"\t"+
"i="+i+"\t"+"l="+l+"\t"+
"f="+f+"\t"+"d="+d);
//在显示器上输出各个变量的值
System.out.println("bool="+bool);
System.out.println("ch="+ch+"\t"+"c="+c);
//输出char型变量的值,以及它对应的ASCII码
System.out.println("s1="+s1+"\t"+"s1_length="+s1_length);
//输出字符串的内容及其长度
for(int j=0;j<str.length;j++){
System.out.println("str["+j+"]="+str[j]);
}
//使用for循环语句输出字符串数组的元素,length方法能够获得数组的长度
}
}
运行结果:
CONST_NUM=5 b=3 s=5 i=12 l=35 f=1.5 d=5.68
bool=true
ch=a c=97
s1=Hello World! s1_length=12
str[0]=Shanghai
str[1]=Beijing
str[2]=Wuhan
str[3]=Guangzhou
str[4]=Shenzhen
程序分析:
该程序定义了一个名为L3_1的公共类,因此该源程序的文件名必须与公共类的名称相同,即为L3_1.java,而且要注意大小写一定要完全一致。编辑好该源程序后,就可以在DOS环境下编译了,在DOS提示符后输入编译命令javac L3_1.java,如果源程序没有错误并被编译通过,在文件夹中会生成一个编译好的字节码文件L3_1.class,DOS提示符会重新显示出来,这时就可以运行该字节码文件了。输入运行命令java L3_1,这时会在屏幕上显示上面的运行结果。
例3.2 综合实例分析:在表达式中正确使用运算符
//表达式综合实例,在表达式中正确使用运算符
public class L3_2{
public static void main(String args[]){
int i=1;
//一元运算符中的自加和自减运算
System.out.println("i++="+(i++)+"\t"+"++i="+(++i));
System.out.println("i--="+(i--)+"\t"+"--i="+(--i));
int j=5/3; //两个整数相除,结果是整数
double k=5.0/3.0;//两个浮点数相除,结果是浮点数
System.out.println("5/3="+j+"\t"+"5.0/3.0="+k);
int p=5%3; //两个整数相除取余数,余数为整数
double q=5.5%3.2;//两个浮点数相除取余数,余数为浮点数
System.out.println("5%3="+p+"\t"+"5.5%3.2="+q);
String s1="I am ";
String s2="a student.";
String s3=s1+s2; //+运算符可以用在字符串连接运算中
System.out.println("s3=s1+s2="+s3);
if(s1 instanceof String){ //判断s1是否是String类的实例
System.out.println("s1 is an instance of String class");
}
else{
System.out.println("si is not an instance of String calss");
}
//短路运算符的使用
if(!(5<0&&5/0>0)){//5<0为假,&&后面的条件将不再判断,因此也不抛出列外
System.out.println("&& is a short-circuit operator");
}
if(5>0||5/0>0){ //5>0为真,||后面的条件将不再判断,因此也不抛出例外
System.out.println("|| is a short-circuit operator");
}
boolean bool=true;
int a=bool?5:3; //三元运算符,bool为真,则a=5;否则,a=3
System.out.println("a=bool?5:3"+"\t"+"a="+a);
for(int x=0;x<5;x++){
x+=2; //赋值运算符的使用,等价于x=x+2
System.out.print("x="+x+"\t");
}
}
}
运行结果:
i++=1 ++i=3
i--=3 --i=1
5/3=1 5.0/3.0=1.6666666666666667
5%3=2 5.5%3.2=2.3
s3=s1+s2=I am a student.
s1 is an instance of String class
&& is a short-circuit operator
|| is a short-circuit operator
a=bool?5:3 a=5
x=2 x=5
例3.3 判断某一年是否为闰年闰年的条件是符合二者之一:① 能被4整除,但不能被100整除;② 能被4整除,又能被100整除。源程序如下:
//判断某一年是否为闰年
import java.io.*;
public class L3_3{
public static void main(String args[])throws IOException{
//从键盘读入一个整型数据
int year=0;
System.out.print("please enter an integer number as the year number:");
BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
String s=in.readLine();
year=Integer.parseInt(s);
//方法一:用逻辑表达式判断闰年的所有成立条件
//使用了一个if-else语句
if((year%4==0&&year%100!=0)||(year%400==0)){
System.out.println(year+" is a leap year.");
}
else{
System.out.println(year+" is not a leap year.");
}
//方法二:使用了if-else语句的特殊形式,对多个条件分支进行选择
//leap是一个标志,某一年是闰年,就标志为true,否则为false
boolean leap;
if(year%4!=0)
leap=false;
else if(year%100!=0)
leap=true;
else if(year%400!=0)
leap=false;
else
leap=true;
if(leap==true){
System.out.println(year+" is a leap year.");
}
else{
System.out.println(year+" is not a leap year.");
}
//方法三:if-else语句的嵌套使用
//else语句不能单独使用,只能和最近的if语句配套使用
//使用{}对if-else进行匹配
if(year%4==0){
if(year%100==0){
if(year%400==0)
leap=true;
else
leap=false;
}
else
leap=false;
}
else
leap=false;
if(leap==true){
System.out.println(year+" is a leap year.");
}
else{
System.out.println(year+" is not a leap year.");
}
}
}
运行结果:
please enter an integer number as the year number:2000
2000 is a leap year.
2000 is a leap year.
2000 is a leap year.
程序分析:
本例中使用了if-else语句的三种不同形式实现了同一功能,即判断某一年是否为闰年。程序前面的几行是从键盘读取一个年份的数字,其中用到了数据流的概念,在这里读者可以不必深究。
例3.4 根据输入的考试成绩等级打印出百分制分数段,A为85~100,B为70~84,C为60~69,D为60分以下。
//根据考试成绩的等级打印百分制分数段
import java.io.*;
public class L3_4{
public static void main(String args[]) throws IOException{
//从键盘读取考试成绩的等级grade
char grade;
System.out.print("please enter the grade level(A~D):");
grade=(char)System.in.read();//从键盘读入一个字符
//第一种情况
System.out.println("\n****first situation****");
switch(grade){
case 'A':System.out.println(grade+" is 85~100.");
break;
case 'B':System.out.println(grade+" is 70~85.");
break;
case 'C':System.out.println(grade+" is 60~69.");
break;
case 'D':System.out.println(grade+" is <60.");
break;
default: System.out.println("input error!");
}
//第二种情况
System.out.println("\n****second situation****");
switch(grade){
case 'A':System.out.println(grade+" is 85~100.");
case 'B':System.out.println(grade+" is 70~85.");
case 'C':System.out.println(grade+" is 60~69.");
case 'D':System.out.println(grade+" is <60.");
default: System.out.println("input error!");
}
//第三种情况
System.out.println("\n****third situation****");
switch(grade){
case 'A':
case 'B':
case 'C':System.out.println(grade+" is >=60.");
break;
case 'D':System.out.println(grade+" is <60.");
break;
default:System.out.println("input error!");
}
}
}
运行结果:
please enter the grade level(A~D):C
****first situation****
C is 60~69.
****second situation****
C is 60~69.
C is <60.
input error!
****third situation****
C is >=60.
程序分析:
本例是对switch多分支条件语句的使用,该语句根据表达式的值执行多个操作中的一个。其中switch后面表达式的值一定要是一个常量,而且只能是char型和除long以外的整数数据。Switch语句把表达式返回的值与每一个case子句中的值相比,如果匹配成功,则执行该case子句后面的操作。
3.5 用三种循环语句实现从1到100的求和运算。
//分别用三种循环语句求1~100的和
public class L3_5{
public static void main(String args[]){
//while循环
System.out.println("\n****while循环****");
int n=100,sum=0; //初始化
while(n>0){ //执行循环体的条件
sum+=n; //循环体
n--; //迭代部分
}
System.out.println("sum is "+sum);
//do-while循环
System.out.println("\n****do-while循环****");
n=0; sum=0; //初始化
do{
sum+=n; //循环体
n++; //迭代部分
}while(n<=100); //执行循环体的条件
System.out.println("sum is "+sum);
//for循环
System.out.println("\n****for循环****");
sum=0; //初始化
for(int i=1;i<=100;i++){//初始化、执行循环体的条件、迭代部分
sum+=i; //循环体
}
System.out.println("sum is "+sum);
}
}
运行结果:
****while循环****
sum is 5050
****do-while循环****
sum is 5050
****for循环****
sum is 5050
程序分析:
本例分别用三种方法实现了从1到100的求和运算。从程序的源代码注释中,可以明确的看出每种循环语句包含的四部分内容。
例3.6 用循环的嵌套求出1~100内的所有素数,并以每行10个的格式显示出来。素数就是只能被1和它本身整除的数。
//求1~100之间的所有素数
public class L3_6{
public static void main(String args[]){
System.out.println("1到100之间所有的素数");
int n=0;
outer_loop:for(int i=3;i<100;i+=2){ //外层循环
for(int j=2;j<i;j++){ //内层循环
if(i%j==0)
//当条件不成立时,退出内层循环,执行外层循环
continue outer_loop;
}
//一行输出10个数字,大于10个换行输出
System.out.print(" "+i);
n++;
if(n<10)
continue; //当一行不满10个时,继续执行外层循环
//后面的语句并不执行
System.out.println();//换行
n=0;
}
System.out.println();
}
}
运行结果:
1到100之间所有的素数
3 5 7 11 13 17 19 23 29 31
37 41 43 47 53 59 61 67 71 73
79 83 89 97
程序分析:
在源程序中,外层循环用来选取要进行检测的数字,由于偶数肯定不是素数,所以增量为2。在内层循环中用2到该数-1的整数去整除这个数字,如果能被其中的某个数字整除,则该数不是素数,此时用continue语句跳出内层循环,另外选一个数字来判定。程序用outer_loop标志出了外层循环的位置,因此continue语句后面直接跟上outer_loop,表示回到外层循环。
在后面的格式化输出中,也用到了一个continue语句,由于这条语句本身就在外层循环中,因此无需明确指定要继续的是哪层循环,只写一个continue就能实现功能了,如果明确写出,会更加清晰明了。
例3.7 举例说明对象、类和方法的使用。
//对象、类和方法的使用
//定义一个Point类
class Point{
int x,y; //x,y是Point类的两个int型实例变量,作用域为整个类
String name="a point";//name是Point类的一个字符串变量
Point(){ //Point类的构造方法,与类同名,没有返回类型
x=0;
y=0;
}
Point(int x,int y,String name){//Point类带参数的构造方法,重载了无参的Point方法
this.x=x;//this是一个特殊的实例值,在实例方法内指向当前的对象
this.y=y;//点操作符(.)用来引用一个对象的实例变量或实例方法
this.name=name;
}
int getX(){//实例方法的定义,返回类型int型的值
return x;//实例方法可以直接访问实例变量
}
int getY(){
return y;
}
void move(int newX,int newY){//实例方法,返回类型为空,给原始点一个新的坐标
x=newX;
y=newY;
}
Point newPoint(String name){//实例方法,返回类型为Point型
//用new操作符创建一个Point类的对象
Point newP=new Point(-x,-y,name); //newP即为Point类的一个对象
//在实例方法中可以直接访问同一个类中的实例变量和实例方法
return newP;//返回原始点的对称点
}
boolean equal(int x,int y){//实例方法,返回一个布尔值
if(this.x==x&&this.y==y)
return true;
else
return false;
}
void print(){//实例方法,实现屏幕输出,输出点的坐标
System.out.println(name+": x="+x+" y="+y);
}
}
//创建程序的公共类和main方法
public class L3_7{
public static void main(String args[]){
//创建Point类的对象p,并调用无参构造方法给对象初始化
Point p=new Point();
p.print();//用点操作符调用对象的方法,输出点的坐标
p.move(50,50);//将原始点移动到一个新的坐标
System.out.println("****after moving****");
System.out.println("Gex x and y directly");
System.out.println("x="+p.x+" y="+p.y);//输出移动后的坐标
System.out.println("or Get x and y by calling method");
System.out.println("x="+p.getY()+" y="+p.getY());//调用对象的方法返回点的坐标
if(p.equal(50,50))
System.out.println("I like this point!");
else
System.out.println("I hate it!");
//调用newPoint方法创建新对象,并输出点的坐标
p.newPoint("a new point").print();
//用new操作符生成了一个无名对象,并用带参构造方法进行初始化
//用点操作符调用该无名对象的print方法,输出点的坐标
new Point(10,15,"another new point").print();
}
}
运行结果:
a point: x=0 y=0
****after moving****
Gex x and y directly
x=50 y=50
or Get x and y by calling method
x=50 y=50
I like this point!
a new point: x=-50 y=-50
another new point: x=10 y=15
程序分析:
本例是对类、对象和方法的定义和使用。源程序首先定义了一个名为Point的类,该类中包含三个变量和八个方法。其中两个int型的变量描述了点的坐标,一个字符串变量保存点的信息。接着定义了两个与类名同名的方法,它们都是Point类的构造方法,没有任何返回类型,用于对类的对象进行初始化。当创建类的对象时,系统会根据创建对象所给的信息判断应该调用哪个构造方法。
例3.8 一个继承机制的实例
//继承机制的实例
class superClass{//超类
int x; //超类的实例变量
superClass(){//超类的构造方法
x=3;
System.out.println("In superClass:x="+x);
}
void doSomething(){//超类的实例方法
System.out.println("In superClass,I want to do something.");
}
}
class subClass extends superClass{//子类,继承了superClass
int x; //子类的实例变量
subClass(){ //子类的构造方法
super();//用super调用超类的构造方法
x=5;
System.out.println("In subClass: x="+x);
}
void doSomething(){//子类的实例方法,重写了超类中的实例方法
super.doSomething();//调用超类中被重写了的实例方法
System.out.println("In subClass,I want to do another thing.");
System.out.println("super.x="+super.x+" sub.x="+x);//super.x引用超类中的实例变量
}
}
public class L3_8{
public static void main(String args[]){
subClass subC=new subClass();//创建子类的对象
subC.doSomething();//调用子类对象的方法
}
}
运行结果:
In superClass:x=3
In subClass: x=5
In superClass,I want to do something.
In subClass,I want to do another thing.
super.x=3 sub.x=5
程序分析:
本例描述了Java中的继承机制。源程序首先定义了一个superClass类,其中包含一个实例变量、一个构造方法以及一个实例方法。
例3.9 一个抽象类和最终类的实例。
/抽象类和最终类的实例
//定义一个抽象类
abstract class abstractClass{
abstract void callme(); //抽象类中可以有抽象方法
void metoo(){ //抽象类中的一般实例方法
System.out.println("Inside metoo() method of abstractClass");
}
}
//定义一个最终类
final class finalClass{
//abstract void abstractMethod();//最终类中不能有抽象方法
//因为最终类不能被继承,因此抽象方法也就无从实现了
void print(){
System.out.println("In final class,there can't be abstract method!");
System.out.println("Final class can't be inherited!");
}
}
//在normalClass中继承了抽象类,并实现了抽象类中的抽象方法
//只要继承了一个抽象类,则抽象类中的所有抽象方法都必须被实现
class normalClass extends abstractClass{
void callme(){//重写父类中的抽象方法
System.out.println("Inside callme() method of normalClass");
}
}
public class L3_9{
public static void main(String args[]){
abstractClass absC=new normalClass();//生成一个normalClass类的对象
//返回到abstractClass的变量absC中
absC.callme();
absC.metoo();
finalClass finC=new finalClass();
finC.print();
}
}
运行结果:
Inside callme() method of normalClass
Inside metoo() method of abstractClass
In final class,there can't be abstract method!
Final class can't be inherited!
程序分析:
本例是对final类和abstract类的功能描述。final类不能被继承,因此final类中也不能包含抽象方法;abstract类必须被继承,可以包含也可以不包含抽象方法,但是如果某一个类中包含了抽象方法,则该类必须声明为抽象类。抽象方法在抽象类中不必实现,而是在子类中得到实现。
例3.10 举例说明方法重载
//方法重载实例
class MethodOverloading{
//原方法,只有一个int型参数
void receive(int i){
System.out.println("Receive one int data");
System.out.println("i="+i);
}
//重载方法1,两个参数,一个是int型,一个是double型
void receive(int x,double y){
System.out.println("Receive an int data and a double data");
System.out.println("x="+x+" y="+y);
}
//重载方法2,同样是两个参数,但是与重载方法1中的参数列表顺序不同
void receive(double d,int i){
System.out.println("Receive a double data and an int data");
System.out.println("d="+d+" i="+i);
}
//重载方法3,参数类型为字符串型
void receive(String s){
System.out.println("Receive a string");
System.out.println("s="+s);
}
}
public class L3_10{
public static void main(String args[]){
MethodOverloading mo=new MethodOverloading();
//根据所给的参数不同,系统会自动确定使用哪种方法
mo.receive(1);
mo.receive(5,3.14);
mo.receive(3.1415926,9);
mo.receive("This is a string!");
}
}
运行结果:
Receive one int data
i=1
Receive an int data and a double data
x=5 y=3.14
Receive a double data and an int data
d=3.1415926 i=9
Receive a string
s=This is a string!
程序分析:
本例是对方法重载的说明,重在对方法重载条件的理解和把握。本例程序的源代码中对方法重载的几个条件都有详细示例,请读者仔细体会。
例3.11 举例说明接口定义和实现。
//接口定义和实现实例
interface myInterface{ //定义一个接口
int add(int x,int y);//接口中的方法
}
class myClass implements myInterface{//定义myClass类实现myInterface接口
int sum;
public int add(int x,int y){//重写接口中的方法
sum=x+y;
return sum;
}
}
class yourClass implements myInterface{//定义yourClass类实现myInterface接口
int sub;
public int add(int x,int y){//重写接口中的方法
sub=x-y;
return sub;
}
}
public class L3_11{
public static void main(String args[]){
//myClass和yourClass分别实现了myInterface接口
//重写了接口中的add方法,但是实现的功能并不一样
myClass mc=new myClass();
mc.add(5,3);
System.out.println("In myClass sum="+mc.sum);
yourClass yc=new yourClass();
yc.add(5,3);
System.out.println("In yourClass sub="+yc.sub);
}
}
运行结果:
In myClass sum=8
In yourClass sub=2
例3.12 举例说明使用try-catch-finally语句捕获例外并处理例外。
//使用try-catch-finally语句捕获例外并处理例外
public class L3_12{
static void ExceptionTest(int i){
System.out.println("***In Situation "+i+"***");
try{
if(i==0){
System.out.println("no Exception caught");
return;
}else if(i==1){
int a=0;
int b=4/a;//可能发生被0除的例外
}else if(i==2){
int iArray[]=new int[4];
iArray[4]=3;//可能发生数组越界例外
}
}catch(ArithmeticException e){//捕获被0除的例外并处理
System.out.println("Catch "+e);
}catch(ArrayIndexOutOfBoundsException e){//捕获数组越界例外并处理
System.out.println("Catch "+e);
}catch(Exception e){//捕获任何一种例外并处理
System.out.println("Will not be executed");
}finally{//无论发生例外与否,finally子句都要被执行
System.out.println("in ExceptionTest finally");
}
}
public static void main(String args[]){
ExceptionTest(0);
ExceptionTest(1);
ExceptionTest(2);
}
}
运行结果:
***In Situation 0***
no Exception caught
in ExceptionTest finally
***In Situation 1***
Catch java.lang.ArithmeticException: / by zero
in ExceptionTest finally
***In Situation 2***
Catch java.lang.ArrayIndexOutOfBoundsException: 4
in ExceptionTest finally
程序分析:
本例是使用try-catch-finally语句捕获并处理例外的实例。在ExceptionTest方法中,可能会出现被0除、数组越界等例外事件,因此在后面的catch语句中就对这两种例外类进行捕获,并编写相应的例外处理代码。Finally语句提供了程序的统一出口,无论是否在try语句中发生了例外,finally语句都要被执行。在编写程序时,重要的是判断程序可能会生成什么类型的例外,再有针对性的捕获该例外并进行处理。这种判断能力来源于实际经验,因此多练习是最好的学习方法。
例3.13 举例说明使用throws子句声明并抛弃例外。
//使用throws子句声明并抛弃例外
public class L3_13{
static void ExceptionTest(int i)
throws ArithmeticException,ArrayIndexOutOfBoundsException{
//声明两个例外,如果发生其中任何一个例外,都会抛弃到调用该方法的方法中进行处理
//声明多个例外时,要用逗号隔开
System.out.println("***In Situation "+i+"***");
if(i==0){
System.out.println("no Exception caught");
return;
}else if(i==1){
int a=0;
int b=4/a;//可能发生被0除的例外
}else if(i==2){
int iArray[]=new int[4];
iArray[4]=3;//可能发生数组越界例外
}
}
public static void main(String args[]){
try{
ExceptionTest(0);
ExceptionTest(2);
ExceptionTest(1);
}catch(ArithmeticException e){//捕获被0除的例外并处理
System.out.println("Catch "+e);
}catch(ArrayIndexOutOfBoundsException e){//捕获数组越界例外并处理
System.out.println("Catch "+e);
}catch(Exception e){//捕获任何一种例外并处理
System.out.println("Will not be executed");
}finally{//无论发生例外与否,finally子句都要被执行
System.out.println("in ExceptionTest finally");
}
}
}
运行结果:
***In Situation 0***
no Exception caught
***In Situation 2***
Catch java.lang.ArrayIndexOutOfBoundsException: 4
in ExceptionTest finally
程序分析:
本例是使用throws子句声明并抛弃例外的实例。在定义方法的时候就要确定该方法可能会产生例外的类型,然后用throws子句声明例外。当该方法在运行过程中生成例外时,这些例外就会被抛弃到调用它的方法中进行处理。
例3.14 定义自己的例外类
class MyException extends Exception{//继承Exception类
private String detail;
MyException(String s){//定义构造方法
detail=s;
}
public String getMyException(){//获得例外事件的信息
return "MyException:"+detail;
}
}
public class L3_14{
static void test(String s) throws MyException{
System.out.println("called test("+s+")");
if(s!="")
throw new MyException(s);//抛弃自定义的例外
System.out.println("normal exit");
}
public static void main(String args[]){
try{//使用try-catch语句捕获例外
test("");
test("No server currently available");
}catch(MyException e){
System.out.println("Caught "+e.getMyException());
}
}
}
运行结果:
called test()
normal exit
called test(No server currently available)
Caught MyException:No server currently available
例3.15 举例说明通过继承Thread类构造线程体
//通过继承Thread类构造线程体
public class L3_15{
public static void main(String args[]){
//用start()方法启动线程,线程进入准备状态
new MyThread("first").start();
new MyThread("second").start();
}
}
//创建MyThread类作为Thread类的子类
class MyThread extends Thread{
public MyThread(String s){
super(s);//调用父类的构造方法
}
//重写Thread类的run()方法
public void run(){
for(int i=0;i<10;i++){
System.out.println(i+" "+getName());//getName()用来获得线程的名字
try{
sleep((int)(Math.random()*1000));
//线程睡眠一个随机的时间段
}catch(InterruptedException e){}
}
System.out.println("Finished!"+getName());
}
}
运行结果:
0 first
0 second
1 second
1 first
2 second
2 first
3 second
3 first
4 first
4 second
5 second
5 first
6 second
6 first
7 second
7 first
8 second
8 first
9 first
Finished!first
9 second
Finished!second
程序分析:
本例是通过继承Thread类来构造线程体的实例。在本例的main()方法中,构造了两个线程,分别是first和second,并调用了start()方法来启动这两个线程。此时线程并没有马上运行,而是等待CPU的资源,获得CPU的线程就可以进入运行状态了。在这个程序中,线程获得CPU的顺序是随机的。
例3.16 举例说明通过实现Runnable接口构造线程体。
//通过实现Runnable接口构造线程体
class MyThread implements Runnable{
Thread t;
MyThread(String s){//构造方法
t=new Thread(s);
}
public void run(){//重写Runnable接口的run()方法
for(int i=0;i<10;i++){
System.out.println(i+" "+t.getName());//getName()用来获得线程的名字
try{
t.sleep((int)(Math.random()*1000));
//线程睡眠一个随机的时间段
}catch(InterruptedException e){}
}
System.out.println("Finished!"+t.getName());
}
}
public class L3_16{
public static void main(String args[]){
MyThread mt1=new MyThread("first");
Thread t1=new Thread(mt1);
t1.start();
MyThread mt2=new MyThread("second");
Thread t2=new Thread(mt2);
t2.start();
}
}
运行结果:
0 first
0 second
1 first
1 second
2 first
2 second
3 first
4 first
5 first
3 second
4 second
6 first
7 first
5 second
8 first
6 second
7 second
9 first
8 second
Finished!first
9 second
Finished!second
程序分析:
本例是使用实现Runnable接口的方法构造线程体的实例。从程序运行结果可以看出,本例与例3.15的功能是相同的,但是它们构造run()方法的实现方法是不同的。本例通过建立一个实现了Runnable接口的对象,并以它作为线程的目标对象构造线程体。MyThread类的构造方法实际上初始化了一个线程,把此线程作为MyThread类的类变量。在重写的run()方法中使用该类变量调用线程的类方法。
例3.17 从标准输入中读取字符串数据。
import java.io.*;
public class L3_17{
public static void main(String args[]){
String s;
InputStreamReader ir;
BufferedReader in;
ir=new InputStreamReader(System.in);
//建立与系统标准输入之间的输入流联系
in=new BufferedReader(ir);
try{
do{
s=in.readLine();
if(s!=null){
System.out.println("Read:"+s);//将读取的数据输出
}
}while(s!=null);//判断是否读完数据
}catch(Exception e){};
}
}
运行结果:
abc
Read:abc
Hello World!
Read:Hello World!
123456
Read:123456