Jody

 

2006年4月20日

爱和被爱的成熟

從前有個書生,和未婚妻約好在某年某月某日結婚.

 到那一天,未婚妻卻嫁給了別人

 書生受此打擊,一病不起.

 家人用盡各種辦法都無能為力,眼看書生奄奄一息.

 這時,路過一游方僧人,得知情況,決定點化一下他.

 僧人到他床前,從懷裡摸出一面鏡子叫書生看.
 

 書生看到茫茫大海,一名遇害的女子一絲不掛地躺在海灘上..

 
 路過一人,看一眼,搖搖頭,走了....

 又路過一人,將衣服脫下,給女屍蓋上,走了....

 再路過一人,過去,挖個坑,小心翼翼把屍體掩埋了............

 
 疑惑間,畫面切換.書生看到自己的未婚妻.

 洞房花燭,被她丈夫掀起蓋頭的瞬間...

 
 書生不明所以.
 

 僧人解釋道,那具海灘上的女屍就是你未婚妻的前世.

 你是第2個路過的人,曾給過他一件衣服.

 
 她今生和你相戀,只為還你一個情.

 但是她最終要報答一生一世的人,

 是最後那個把她掩埋的人,那人就是他現在的丈夫

 
 書生大悟,唰地從床上坐起,病癒.

 
 

 : 缘这东西,是最不可思议的.

 电影"不见不散"的主題歌里这样唱道"这世界说大就大,

 说小就小.就算是我们今生的约定,也要用一生去寻找...."

 我們在熙熙攘攘的人群里,寻觅着,渴望着....
 
 等待着一个阳光灿烂的日子,
 
 抑或一个灯火阑珊的夜晚,

 一次邂逅,或者一个回眸来唤醒.


 這之前,我們都惶惑着,

 惶惑的甚至不知道自己需要的究竟是什么.

 直到你遇到一個人,
 
 才恍然間了解了自己真正想要的.

 从此改写了整个的人生.


 一次的缘起缘灭,或许会遍体鳞伤,
 
 但缘份是一种无从选择也无从回避的必然.

 眼泪与欢笑都注定了要在缘份的天空中去开放 
 
 也许选择了会终生痛苦,但是错过了肯定会终生遗憾.


 可无论任何時候,我們都不能绝望.

 不要放弃自己对真,善,美的追求.

 
 人生的价值,在某种意义上讲,就是爱和被爱的成熟.

 当真爱來临时,果实也就成熟了

posted @ 2006-11-30 13:53 zhaofei1394 阅读(227) | 评论 (0)编辑 收藏

Insert text file into MySQL

import  java.io.File;
import  java.io.FileInputStream;
import  java.sql.Connection;
import  java.sql.DriverManager;
import  java.sql.PreparedStatement;

public class  InsertTextFileToMySQL  {

   public static  Connection getConnection ()  throws  Exception  {
     String driver =  "org.gjt.mm.mysql.Driver" ;
     String url =  "jdbc:mysql://localhost/databaseName" ;
     String username =  "root" ;
     String password =  "root" ;

     Class .forName ( driver ) ;
     Connection conn = DriverManager.getConnection ( url, username, password ) ;
     return  conn;
   }

   public static  void  main ( String []  args ) throws  Exception  {
     String id =  "001" ;
     String fileName =  "fileName.txt" ;
    
     FileInputStream fis =  null ;
     PreparedStatement pstmt =  null ;
     Connection conn =  null ;
     try  {
       conn = getConnection () ;
       conn.setAutoCommit ( false ) ;
       File file =  new  File ( fileName ) ;
       fis =  new  FileInputStream ( file ) ;
       pstmt = conn.prepareStatement ( "insert into DataFiles(id, fileName, fileBody) values (?, ?, ?)" ) ;
       pstmt.setString ( 1 , id ) ;
       pstmt.setString ( 2 , fileName ) ;
       pstmt.setAsciiStream ( 3 , fis,  ( int file.length ()) ;
       pstmt.executeUpdate () ;
       conn.commit () ;
     catch  ( Exception e ) {
       System.err.println ( "Error: "  + e.getMessage ()) ;
       e.printStackTrace () ;
     finally  {
       pstmt.close () ;
       fis.close () ;
       conn.close () ;
     }
   }
}

posted @ 2006-09-13 11:33 zhaofei1394 阅读(648) | 评论 (0)编辑 收藏

java多线程

首先要理解线程首先需要了解一些基本的东西,我们现在所使用的大多数操作系统都属于多任务,分时操作系统。正是由于这种操作系统的出现才有了多线程这个概念。我们使用的windows,linux就属于此列。什么是分时操作系统呢,通俗一点与就是可以同一时间执行多个程序的操作系统,在自己的电脑上面,你是不是一边听歌,一边聊天还一边看网页呢?但实际上,并不上cpu在同时执行这些程序,cpu只是将时间切割为时间片,然后将时间片分配给这些程序,获得时间片的程序开始执行,不等执行完毕,下个程序又获得时间片开始执行,这样多个程序轮流执行一段时间,由于现在cpu的高速计算能力,给人的感觉就像是多个程序在同时执行一样。
一般可以在同一时间内执行多个程序的操作系统都有进程的概念.一个进程就是一个执行中的程序,而每一个进程都有自己独立的一块内存空间,一组系统资源.在进程概念中,每一个进程的内部数据和状态都是完全独立的.因此可以想像创建并执行一个进程的系统开像是比较大的,所以线程出现了。在java中,程序通过流控制来执行程序流,程序中单个顺序的流控制称为线程,多线程则指的是在单个程序中可以同时运行多个不同的线程,执行不同的任务.多线程意味着一个程序的多行语句可以看上去几乎在同一时间内同时运行.(你可以将前面一句话的程序换成进程,进程是程序的一次执行过程,是系统运行程序的基本单位)

线程与进程相似,是一段完成某个特定功能的代码,是程序中单个顺序的流控制;但与进程不同的是,同类的多个线程是共享一块内存空间和一组系统资源,而线程本身的数据通常只有微处理器的寄存器数据,以及一个供程序执行时使用的堆栈.所以系统在产生一个线程,或者在各个线程之间切换时,负担要比进程小的多,正因如此,线程也被称为轻负荷进程(light-weight process).一个进程中可以包含多个线程.

多任务是指在一个系统中可以同时运行多个程序,即有多个独立运行的任务,每个任务对应一个进程,同进程一样,一个线程也有从创建,运行到消亡的过程,称为线程的生命周期.用线程的状态(state)表明线程处在生命周期的哪个阶段.线程有创建,可运行,运行中,阻塞,死亡五中状态.通过线程的控制与调度可使线程在这几种状态间转化每个程序至少自动拥有一个线程,称为主线程.当程序加载到内存时,启动主线程.

[线程的运行机制以及调度模型]
java中多线程就是一个类或一个程序执行或管理多个线程执行任务的能力,每个线程可以独立于其他线程而独立运行,当然也可以和其他线程协同运行,一个类控制着它的所有线程,可以决定哪个线程得到优先级,哪个线程可以访问其他类的资源,哪个线程开始执行,哪个保持休眠状态。
下面是线程的机制图:


线程的状态表示线程正在进行的活动以及在此时间段内所能完成的任务.线程有创建,可运行,运行中,阻塞,死亡五中状态.一个具有生命的线程,总是处于这五种状态之一:
1.创建状态
使用new运算符创建一个线程后,该线程仅仅是一个空对象,系统没有分配资源,称该线程处于创建状态(new thread)
2.可运行状态
使用start()方法启动一个线程后,系统为该线程分配了除CPU外的所需资源,使该线程处于可运行状态(Runnable)
3.运行中状态
Java运行系统通过调度选中一个Runnable的线程,使其占有CPU并转为运行中状态(Running).此时,系统真正执行线程的run()方法.
4.阻塞状态
一个正在运行的线程因某种原因不能继续运行时,进入阻塞状态(Blocked)
5.死亡状态
线程结束后是死亡状态(Dead)

同一时刻如果有多个线程处于可运行状态,则他们需要排队等待CPU资源.此时每个线程自动获得一个线程的优先级(priority),优先级的高低反映线程的重要或紧急程度.可运行状态的线程按优先级排队,线程调度依据优先级基础上的"先到先服务"原则.
线程调度管理器负责线程排队和CPU在线程间的分配,并由线程调度算法进行调度.当线程调度管理器选种某个线程时,该线程获得CPU资源而进入运行状态.

线程调度是先占式调度,即如果在当前线程执行过程中一个更高优先级的线程进入可运行状态,则这个线程立即被调度执行.先占式调度分为:独占式和分时方式.
独占方式下,当前执行线程将一直执行下去,直 到执行完毕或由于某种原因主动放弃CPU,或CPU被一个更高优先级的线程抢占
分时方式下,当前运行线程获得一个时间片,时间到时,即使没有执行完也要让出CPU,进入可运行状态,等待下一个时间片的调度.系统选中其他可运行状态的线程执行
分时方式的系统使每个线程工作若干步,实现多线程同时运行

另外请注意下面的线程调度规则(如果有不理解,不急,往下看):
①如果两个或是两个以上的线程都修改一个对象,那么把执行修改的方法定义为被同步的(Synchronized),如果对象更新影响到只读方法,那么只度方法也应该定义为同步的
②如果一个线程必须等待一个对象状态发生变化,那么它应该在对象内部等待,而不是在外部等待,它可以调用一个被同步的方法,并让这个方法调用wait()
③每当一个方法改变某个对象的状态的时候,它应该调用notifyAll()方法,这给等待队列的线程提供机会来看一看执行环境是否已发生改变
④记住wait(),notify(),notifyAll()方法属于Object类,而不是Thread类,仔细检查看是否每次执行wait()方法都有相应的notify()或notifyAll()方法,且它们作用与相同的对象 在java中每个类都有一个主线程,要执行一个程序,那么这个类当中一定要有main方法,这个man方法也就是java class中的主线程。你可以自己创建线程,有两种方法,一是继承Thread类,或是实现Runnable接口。一般情况下,最好避免继承,因为java中是单根继承,如果你选用继承,那么你的类就失去了弹性,当然也不能全然否定继承Thread,该方法编写简单,可以直接操作线程,适用于单重继承情况。至于选用那一种,具体情况具体分析。


eg.继承Thread
public class MyThread_1 extends Thread
{
public void run()
{
//some code
}
}


eg.实现Runnable接口
public class MyThread_2 implements Runnable
{
public void run()
{
//some code
}
}



当使用继承创建线程,这样启动线程:
new MyThread_1().start()


当使用实现接口创建线程,这样启动线程:
new Thread(new MyThread_2()).start()


注意,其实是创建一个线程实例,并以实现了Runnable接口的类为参数传入这个实例,当执行这个线程的时候,MyThread_2中run里面的代码将被执行。
下面是完成的例子:

public class MyThread implements Runnable
{

public void run()
{
System.out.println("My Name is "+Thread.currentThread().getName());
}
public static void main(String[] args)
{
new Thread(new MyThread()).start();
}
}



执行后将打印出:
My Name is Thread-0

你也可以创建多个线程,像下面这样
new Thread(new MyThread()).start();
new Thread(new MyThread()).start();
new Thread(new MyThread()).start();



那么会打印出:
My Name is Thread-0
My Name is Thread-1
My Name is Thread-2


看了上面的结果,你可能会认为线程的执行顺序是依次执行的,但是那只是一般情况,千万不要用以为是线程的执行机制;影响线程执行顺序的因素有几点:首先看看前面提到的优先级别


public class MyThread implements Runnable
{

public void run()
{
System.out.println("My Name is "+Thread.currentThread().getName());
}
public static void main(String[] args)
{
Thread t1=new Thread(new MyThread());
Thread t2=new Thread(new MyThread());
Thread t3=new Thread(new MyThread());
t2.setPriority(Thread.MAX_PRIORITY);//赋予最高优先级
t1.start();
t2.start();
t3.start();
}
}


再看看结果:
My Name is Thread-1
My Name is Thread-0
My Name is Thread-2



线程的优先级分为10级,分别用1到10的整数代表,默认情况是5。上面的t2.setPriority(Thread.MAX_PRIORITY)等价与t2.setPriority(10)
然后是线程程序本身的设计,比如使用sleep,yield,join,wait等方法(详情请看JDKDocument)

public class MyThread implements Runnable
{
public void run()
{
try
{
int sleepTime=(int)(Math.random()*100);//产生随机数字,
Thread.currentThread().sleep(sleepTime);//让其休眠一定时间,时间又上面sleepTime决定
//public static void sleep(long millis)throw InterruptedException (API)
System.out.println(Thread.currentThread().getName()+" 睡了 "+sleepTime);
}catch(InterruptedException ie)//由于线程在休眠可能被中断,所以调用sleep方法的时候需要捕捉异常
{
ie.printStackTrace();
}
}
public static void main(String[] args)
{
Thread t1=new Thread(new MyThread());
Thread t2=new Thread(new MyThread());
Thread t3=new Thread(new MyThread());
t1.start();
t2.start();
t3.start();
}
}


执行后观察其输出:

Thread-0 睡了 11
Thread-2 睡了 48
Thread-1 睡了 69




上面的执行结果是随机的,再执行很可能出现不同的结果。由于上面我在run中添加了休眠语句,当线程休眠的时候就会让出cpu,cpu将会选择执行处于runnable状态中的其他线程,当然也可能出现这种情况,休眠的Thread立即进入了runnable状态,cpu再次执行它。
[线程组概念]
线程是可以被组织的,java中存在线程组的概念,每个线程都是一个线程组的成员,线程组把多个线程集成为一个对象,通过线程组可以同时对其中的多个线程进行操作,如启动一个线程组的所有线程等.Java的线程组由java.lang包中的Thread——Group类实现.
ThreadGroup类用来管理一组线程,包括:线程的数目,线程间的关系,线程正在执行的操作,以及线程将要启动或终止时间等.线程组还可以包含线程组.在Java的应用程序中,最高层的线程组是名位main的线程组,在main中还可以加入线程或线程组,在mian的子线程组中也可以加入线程和线程组,形成线程组和线程之间的树状继承关系。像上面创建的线程都是属于main这个线程组的。
借用上面的例子,main里面可以这样写:

public static void main(String[] args)
{
/***************************************
ThreadGroup(String name)
ThreadGroup(ThreadGroup parent, String name)
***********************************/
ThreadGroup group1=new ThreadGroup("group1");
ThreadGroup group2=new ThreadGroup(group1,"group2");
Thread t1=new Thread(group2,new MyThread());
Thread t2=new Thread(group2,new MyThread());
Thread t3=new Thread(group2,new MyThread());
t1.start();
t2.start();
t3.start();
}



线程组的嵌套,t1,t2,t3被加入group2,group2加入group1。
另外一个比较多就是关于线程同步方面的,试想这样一种情况,你有一笔存款在银行,你在一家银行为你的账户存款,而你的妻子在另一家银行从这个账户提款,现在你有1000块在你的账户里面。你存入了1000,但是由于另一方也在对这笔存款进行操作,人家开始执行的时候只看到账户里面原来的1000元,当你的妻子提款1000元后,你妻子所在的银行就认为你的账户里面没有钱了,而你所在的银行却认为你还有2000元。
看看下面的例子:

class BlankSaving //储蓄账户
{
private static int money=10000;
public void add(int i)
{
money=money+i;
System.out.println("Husband 向银行存入了 [¥"+i+"]");
}
public void get(int i)
{
money=money-i;
System.out.println("Wife 向银行取走了 [¥"+i+"]");
if(money<0)
System.out.println("余额不足!");
}
public int showMoney()
{
return money;
}
}


class Operater implements Runnable
{
String name;
BlankSaving bs;
public Operater(BlankSaving b,String s)
{
name=s;
bs=b;



}
public static void oper(String name,BlankSaving bs)
{



if(name.equals("husband"))
{
try
{
for(int i=0;i<10;i++)
{
Thread.currentThread().sleep((int)(Math.random()*300));
bs.add(1000);
}
}catch(InterruptedException e){}
}else
{
try
{



for(int i=0;i<10;i++)
{
Thread.currentThread().sleep((int)(Math.random()*300));
bs.get(1000);
}
}catch(InterruptedException e){}
}
}
public void run()
{
oper(name,bs);
}
}
public class BankTest
{
public static void main(String[] args)throws InterruptedException
{
BlankSaving bs=new BlankSaving();
Operater o1=new Operater(bs,"husband");
Operater o2=new Operater(bs,"wife");
Thread t1=new Thread(o1);
Thread t2=new Thread(o2);
t1.start();
t2.start();
Thread.currentThread().sleep(500);
}



}



下面是其中一次的执行结果:



---------first--------------
Husband 向银行存入了 [¥1000]
Wife 向银行取走了 [¥1000]
Wife 向银行取走了 [¥1000]
Husband 向银行存入了 [¥1000]
Wife 向银行取走了 [¥1000]
Husband 向银行存入了 [¥1000]
Wife 向银行取走了 [¥1000]
Husband 向银行存入了 [¥1000]
Wife 向银行取走了 [¥1000]
Husband 向银行存入了 [¥1000]
Husband 向银行存入了 [¥1000]
Wife 向银行取走了 [¥1000]
Husband 向银行存入了 [¥1000]
Husband 向银行存入了 [¥1000]
Wife 向银行取走了 [¥1000]
Wife 向银行取走了 [¥1000]
Husband 向银行存入了 [¥1000]
Wife 向银行取走了 [¥1000]
Wife 向银行取走了 [¥1000]
Husband 向银行存入了 [¥1000]


看到了吗,这可不是正确的需求,在husband还没有结束操作的时候,wife就插了进来,这样很可能导致意外的结果。解决办法很简单,就是将对数据进行操作方法声明为synchronized,当方法被该关键字声明后,也就意味着,如果这个数据被加锁,只有一个对象得到这个数据的锁的时候该对象才能对这个数据进行操作。也就是当你存款的时候,这笔账户在其他地方是不能进行操作的,只有你存款完毕,银行管理人员将账户解锁,其他人才能对这个账户进行操作。
修改public static void oper(String name,BlankSaving bs)为public static void oper(String name,BlankSaving bs),再看看结果:

Husband 向银行存入了 [¥1000]
Husband 向银行存入了 [¥1000]
Husband 向银行存入了 [¥1000]
Husband 向银行存入了 [¥1000]
Husband 向银行存入了 [¥1000]
Husband 向银行存入了 [¥1000]
Husband 向银行存入了 [¥1000]
Husband 向银行存入了 [¥1000]
Husband 向银行存入了 [¥1000]
Husband 向银行存入了 [¥1000]
Wife 向银行取走了 [¥1000]
Wife 向银行取走了 [¥1000]
Wife 向银行取走了 [¥1000]
Wife 向银行取走了 [¥1000]
Wife 向银行取走了 [¥1000]
Wife 向银行取走了 [¥1000]
Wife 向银行取走了 [¥1000]
Wife 向银行取走了 [¥1000]
Wife 向银行取走了 [¥1000]
Wife 向银行取走了 [¥1000]




当丈夫完成操作后,妻子才开始执行操作,这样的话,对共享对象的操作就不会有问题了。
[wait and notify]
你可以利用这两个方法很好的控制线程的执行流程,当线程调用wait方法后,线程将被挂起,直到被另一线程唤醒(notify)或则是如果wait方法指定有时间得话,在没有被唤醒的情况下,指定时间时间过后也将自动被唤醒。但是要注意一定,被唤醒并不是指马上执行,而是从组塞状态变为可运行状态,其是否运行还要看cpu的调度。
事例代码:

class MyThread_1 extends Thread
{
Object lock;
public MyThread_1(Object o)
{
lock=o;
}
public void run()
{
try
{
synchronized(lock)
{
System.out.println("Enter Thread_1 and wait");
lock.wait();
System.out.println("be notified");
}
}catch(InterruptedException e){}
}
}
class MyThread_2 extends Thread
{
Object lock;
public MyThread_2(Object o)
{
lock=o;
}
public void run()
{
synchronized(lock)
{
System.out.println("Enter Thread_2 and notify");
lock.notify();
}
}
}
public class MyThread
{
public static void main(String[] args)
{
int[] in=new int[0];//notice
MyThread_1 t1=new MyThread_1(in);
MyThread_2 t2=new MyThread_2(in);
t1.start();
t2.start();
}
}




执行结果如下:
Enter Thread_1 and wait
Enter Thread_2 and notify
Thread_1 be notified


可能你注意到了在使用wait and notify方法得时候我使用了synchronized块来包装这两个方法,这是由于调用这两个方法的时候线程必须获得锁,也就是上面代码中的lock[],如果你不用synchronized包装这两个方法的得话,又或则锁不一是同一把,比如在MyThread_2中synchronized(lock)改为synchronized(this),那么执行这个程序的时候将会抛出java.lang.IllegalMonitorStateException执行期异常。另外wait and notify方法是Object中的,并不在Thread这个类中。最后你可能注意到了这点:int[] in=new int[0];为什么不是创建new Object而是一个0长度的数组,那是因为在java中创建一个0长度的数组来充当锁更加高效。

Thread作为java中一重要组成部分,当然还有很多地方需要更深刻的认识,上面只是对Thread的一些常识和易错问题做了一个简要的总结,若要真正的掌握java的线程,还需要自己多做总结

posted @ 2006-08-03 17:02 zhaofei1394 阅读(235) | 评论 (0)编辑 收藏

JavaScript 实用的一些技巧

1. oncontextmenu="window.event.returnValue=false" 将彻底屏蔽鼠标右键
<table border oncontextmenu=return(false)><td>no</table> 可用于Table

2. <body onselectstart="return false"> 取消选取、防止复制

3. onpaste="return false" 不准粘贴

4. oncopy="return false;" oncut="return false;" 防止复制

5. <link rel="Shortcut Icon" href="favicon.ico"> IE地址栏前换成自己的图标

6. <link rel="Bookmark" href="favicon.ico"> 可以在收藏夹中显示出你的图标

7. <input style="ime-mode:disabled"> 关闭输入法

8. 永远都会带着框架
<script language="JavaScript"><!--
if (window == top)top.location.href = "frames.htm"; //frames.htm为框架网页
// --></script>

9. 防止被人frame
<SCRIPT LANGUAGE=JAVASCRIPT><!--
if (top.location != self.location)top.location=self.location;
// --></SCRIPT>

10. 网页将不能被另存为
<noscript><iframe src=*.html></iframe></noscript>

11. <input type=button value=查看网页源代码
onclick="window.location = "view-source:"+ "http://www.pconline.com.cn"">

12.删除时确认
<a href="javascript:if(confirm("确实要删除吗?"))location="boos.asp?&areyou=删除&page=1"">删除</a>

13. 取得控件的绝对位置
//Javascript
<script language="Javascript">
function getIE(e){
var t=e.offsetTop;
var l=e.offsetLeft;
while(e=e.offsetParent){
t+=e.offsetTop;
l+=e.offsetLeft;
}
alert("top="+t+"/nleft="+l);
}
</script>

//VBScript
<script language="VBScript"><!--
function getIE()
dim t,l,a,b
set a=document.all.img1
t=document.all.img1.offsetTop
l=document.all.img1.offsetLeft
while a.tagName<>"BODY"
set a = a.offsetParent
t=t+a.offsetTop
l=l+a.offsetLeft
wend
msgbox "top="&t&chr(13)&"left="&l,64,"得到控件的位置"
end function
--></script>

14. 光标是停在文本框文字的最后
<script language="javascript">
function cc()
{
var e = event.srcElement;
var r =e.createTextRange();
r.moveStart("character",e.value.length);
r.collapse(true);
r.select();
}
</script>
<input type=text name=text1 value="123" onfocus="cc()">

15. 判断上一页的来源
javascript:
document.referrer

16. 最小化、最大化、关闭窗口
<object id=hh1 classid="clsid:ADB880A6-D8FF-11CF-9377-00AA003B7A11">
<param name="Command" value="Minimize"></object>
<object id=hh2 classid="clsid:ADB880A6-D8FF-11CF-9377-00AA003B7A11">
<param name="Command" value="Maximize"></object>
<OBJECT id=hh3 classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11">
<PARAM NAME="Command" VALUE="Close"></OBJECT>
<input type=button value=最小化 onclick=hh1.Click()>
<input type=button value=最大化 onclick=hh2.Click()>
<input type=button value=关闭 onclick=hh3.Click()>
本例适用于IE

17.屏蔽功能键Shift,Alt,Ctrl
<script>
function look(){
if(event.shiftKey)
alert("禁止按Shift键!"); //可以换成ALT CTRL
}
document.onkeydown=look;
</script>

18. 网页不会被缓存
<META HTTP-EQUIV="pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Cache-Control" CONTENT="no-cache, must-revalidate">
<META HTTP-EQUIV="expires" CONTENT="Wed, 26 Feb 1997 08:21:57 GMT">
或者<META HTTP-EQUIV="expires" CONTENT="0">

19.怎样让表单没有凹凸感?
<input type=text style="border:1 solid #000000">

<input type=text style="border-left:none; border-right:none; border-top:none; border-bottom:
1 solid #000000"></textarea>

20.<div><span>&<layer>的区别?
<div>(division)用来定义大段的页面元素,会产生转行
<span>用来定义同一行内的元素,跟<div>的唯一区别是不产生转行
<layer>是ns的标记,ie不支持,相当于<div>

21.让弹出窗口总是在最上面:
<body onblur="this.focus();">

22.不要滚动条?
让竖条没有:
<body style="overflow:scroll;overflow-y:hidden">
</body>
让横条没有:
<body style="overflow:scroll;overflow-x:hidden">
</body>
两个都去掉?更简单了
<body scroll="no">
</body>

23.怎样去掉图片链接点击后,图片周围的虚线?
<a href="#" onFocus="this.blur()"><img src="logo.jpg" border=0></a>

24.电子邮件处理提交表单
<form name="form1" method="post" action="mailto:****@***.com" enctype="text/plain">
<input type=submit>
</form>

25.在打开的子窗口刷新父窗口的代码里如何写?
window.opener.location.reload()

26.如何设定打开页面的大小
<body onload="top.resizeTo(300,200);">
打开页面的位置<body onload="top.moveBy(300,200);">

27.在页面中如何加入不是满铺的背景图片,拉动页面时背景图不动
<STYLE>
body
{background-image:url(logo.gif); background-repeat:no-repeat;
background-position:center;background-attachment: fixed}
</STYLE>

28. 检查一段字符串是否全由数字组成
<script language="Javascript"><!--
function checkNum(str){return str.match(//D/)==null}
alert(checkNum("1232142141"))
alert(checkNum("123214214a1"))
// --></script>

29. 获得一个窗口的大小
document.body.clientWidth; document.body.clientHeight

30. 怎么判断是否是字符
if (/[^/x00-/xff]/g.test(s)) alert("含有汉字");
else alert("全是字符");

31.TEXTAREA自适应文字行数的多少
<textarea rows=1 name=s1 cols=27 onpropertychange="this.style.posHeight=this.scrollHeight">
</textarea>

32. 日期减去天数等于第二个日期
<script language=Javascript>
function cc(dd,dadd)
{
//可以加上错误处理
var a = new Date(dd)
a = a.valueOf()
a = a - dadd * 24 * 60 * 60 * 1000
a = new Date(a)
alert(a.getFullYear() + "年" + (a.getMonth() + 1) + "月" + a.getDate() + "日")
}
cc("12/23/2002",2)
</script>

33. 选择了哪一个Radio
<HTML><script language="vbscript">
function checkme()
for each ob in radio1
if ob.checked then window.alert ob.value
next
end function
</script><BODY>
<INPUT name="radio1" type="radio" value="style" checked>Style
<INPUT name="radio1" type="radio" value="barcode">Barcode
<INPUT type="button" value="check" onclick="checkme()">
</BODY></HTML>

34.脚本永不出错
<SCRIPT LANGUAGE="JavaScript">
<!-- Hide
function killErrors() {
return true;
}
window.onerror = killErrors;
// -->
</SCRIPT>

35.ENTER键可以让光标移到下一个输入框
<input onkeydown="if(event.keyCode==13)event.keyCode=9">

36. 检测某个网站的链接速度:
把如下代码加入<body>区域中:
<script language=Javascript>
tim=1
setInterval("tim++",100)
b=1
var autourl=new Array()
autourl[1]="www.njcatv.net"
autourl[2]="javacool.3322.net"
autourl[3]="www.sina.com.cn"
autourl[4]="www.nuaa.edu.cn"
autourl[5]="www.cctv.com"
function butt(){
document.write("<form name=autof>")
for(var i=1;i<autourl.length;i++)
document.write("<input type=text name=txt"+i+" size=10 value=测试中……> =》<input type=text
name=url"+i+" size=40> =》<input type=button value=GO

onclick=window.open(this.form.url"+i+".value)><br>")
document.write("<input type=submit value=刷新></form>")
}
butt()
function auto(url){
document.forms[0]["url"+b].value=url
if(tim>200)
{document.forms[0]["txt"+b].value="链接超时"}
else
{document.forms[0]["txt"+b].value="时间"+tim/10+"秒"}
b++
}
function run(){for(var i=1;i<autourl.length;i++)document.write("<img src=http://"+autourl+"/"+Math.random()+" width=1 height=1

onerror=auto("http://"+autourl+"")>")}
run()</script>

37. 各种样式的光标
auto :标准光标
default :标准箭头
hand :手形光标
wait :等待光标
text :I形光标
vertical-text :水平I形光标
no-drop :不可拖动光标
not-allowed :无效光标
help :?帮助光标
all-scroll :三角方向标
move :移动标
crosshair :十字标
e-resize
n-resize
nw-resize
w-resize
s-resize
se-resize
sw-resize

38.页面进入和退出的特效
进入页面<meta http-equiv="Page-Enter" content="revealTrans(duration=x, transition=y)">
推出页面<meta http-equiv="Page-Exit" content="revealTrans(duration=x, transition=y)">
这个是页面被载入和调出时的一些特效。duration表示特效的持续时间,以秒为单位。transition表示使用哪种特效,取值为1-23:
  0 矩形缩小
  1 矩形扩大
  2 圆形缩小
  3 圆形扩大
  4 下到上刷新
  5 上到下刷新
  6 左到右刷新
  7 右到左刷新
  8 竖百叶窗
  9 横百叶窗
  10 错位横百叶窗
  11 错位竖百叶窗
  12 点扩散
  13 左右到中间刷新
  14 中间到左右刷新
  15 中间到上下
  16 上下到中间
  17 右下到左上
  18 右上到左下
  19 左上到右下
  20 左下到右上
  21 横条
  22 竖条
  23 以上22种随机选择一种

39.在规定时间内跳转
<META http-equiv=V="REFRESH" content="5;URL=http://www.51js.com">

40.网页是否被检索
<meta name="ROBOTS" content="属性值">
  其中属性值有以下一些:
  属性值为"all": 文件将被检索,且页上链接可被查询;
  属性值为"none": 文件不被检索,而且不查询页上的链接;
  属性值为"index": 文件将被检索;
  属性值为"follow": 查询页上的链接;
  属性值为"noindex": 文件不检索,但可被查询链接;
  属性值为"nofollow": 文件不被检索,但可查询页上的链接。

posted @ 2006-07-25 12:53 zhaofei1394 阅读(290) | 评论 (0)编辑 收藏

Linux系统任务定时执行

经常有应用写好后,要由服务器自动定时运行。所以这是一个很常用的东西,其中都是我自己亲自使用的过程。以此作为例子,为以后重复使用时留下资料。

1、认识Cron

cron是一个linux下的定时执行工具,可以在无需人工干预的情况下运行作业。由于Cron 是Linux的内置服务,但它不自动起来,可以用以下的方法启动、关闭这个服务:

/sbin/service crond start //启动服务
/sbin/service crond stop //关闭服务
/sbin/service crond restart //重启服务
/sbin/service crond reload //重新载入配置


你也可以将这个服务在系统启动的时候自动启动:

在/etc/rc.d/rc.local这个脚本的末尾加上:
/sbin/service crond start

2、Cron服务

1)直接用crontab命令编辑

cron服务提供crontab命令来设定cron服务的,以下是这个命令的一些参数与说明:

crontab -u //设定某个用户的cron服务,一般root用户在执行这个命令的时候需要此参数

crontab -l //列出某个用户cron服务的详细内容

crontab -r //删除没个用户的cron服务

crontab -e //编辑某个用户的cron服务

比如说root查看自己的cron设置:crontab -u root -l

再例如,root想删除fred的cron设置:crontab -u fred -r

在编辑cron服务时,编辑的内容有一些格式和约定,输入:crontab -u root -e

(注:大哥大姐,看文章时别忘记关注我哟,嘿嘿)

进入vi编辑模式,编辑的内容一定要符合下面的格式:*/1 * * * * ls >> /tmp/ls.txt

这个格式的前一部分是对时间的设定,后面一部分是要执行的命令,如果要执行的命令太多,可以把这些命令写到一个脚本里面,然后在这里直接调用这个脚本就可以了,调用的时候记得写出命令的完整路径。时间的设定我们有一定的约定,前面五个*号代表五个数字,数字的取值范围和含义如下:

分钟 (0-59)

小時 (0-23)

日期 (1-31)

月份 (1-12)

星期 (0-6)//0代表星期天

除了数字还有几个个特殊的符号就是"*"、"/"和"-"、",",*代表所有的取值范围内的数字,"/"代表每的意思,"*/5"表示每5个单位,"-"代表从某个数字到某个数字,","分开几个离散的数字。以下举几个例子说明问题:

每天早上6点

0 6 * * * echo "Good morning." >> /tmp/test.txt //注意单纯echo,从屏幕上看不到任何输出,因为cron把任何输出都email到root的信箱了。

每两个小时

0 */2 * * * echo "Have a break now." >> /tmp/test.txt

晚上11点到早上8点之间每两个小时,早上八点

0 23-7/2,8 * * * echo "Have a good dream:)" >> /tmp/test.txt

每个月的4号和每个礼拜的礼拜一到礼拜三的早上11点

0 11 4 * 1-3 command line

1月1日早上4点

0 4 1 1 * command line

每次编辑完某个用户的cron设置后,cron自动在/var/spool/cron下生成一个与此用户同名的文件,此用户的cron信息都记录在这个文件中,这个文件是不可以直接编辑的,只可以用crontab -e 来编辑。cron启动后每过一份钟读一次这个文件,检查是否要执行里面的命令。因此此文件修改后不需要重新启动cron服务。

(有了你们的关注,才有我继续写下去的动力!)请点下面的广告吧!


2)编辑/etc/crontab 文件配置cron

cron服务每分钟不仅要读一次/var/spool/cron内的所有文件,还需要读一次/etc/crontab,因此我们配置这个文件也能运用cron服务做一些事情。用crontab配置是针对某个用户的,而编辑/etc/crontab是针对系统的任务。此文件的文件格式是:

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root //如果出现错误,或者有数据输出,数据作为邮件发给这个帐号
HOME=/ //使用者运行的路径,这里是根目录
# run-parts
01 * * * * root run-parts /etc/cron.hourly //每小时执行/etc/cron.hourly内的脚本
02 4 * * * root run-parts /etc/cron.daily //每天执行/etc/cron.daily内的脚本
22 4 * * 0 root run-parts /etc/cron.weekly //每星期执行/etc/cron.weekly内的脚本
42 4 1 * * root run-parts /etc/cron.monthly //每月去执行/etc/cron.monthly内的脚本

3、实例

我在/etc/crontab 文件中配置cron;

#product price trend picture
0 1 * * * root sh /home1/picture/myconfig.sh    (每天1点钟时执行root用户中的/home1/picture/myconfig.sh )

我的myconfig.sh:

JAVA_HOME=/home1/jdk1.5.0_03;export JAVA_HOME

JAVA_OPTS="-server -Djava.awt.headless=true";export JAVA_OPTS 

(由于我的应用是一个绘图应用,所以要以上两段,指定JDK等)

cd /home1/picture/lib  (指定我的JAR文件所在位)
/home1/jdk1.5.0_03/bin/java -cp /home1/picture/lib/PriceTrendPicture.jar:/home1/picture/lib/classes12.jar:/home1/picture/lib/ibatis-common-2.jar:/home1/picture/lib/ibatis-dao-2.jar:/home1/picture/lib/ibatis-sqlmap-2.jar:log4j-1.2.8.jar:/home1/picture/lib/xmlparserv2.jar:/home1/picture/lib/commons-logging.jar com.yesky.run.PriceTrendPicture

/home1/jdk1.5.0_03/bin/java -cp 这是我的JDK位置  随后加上所有使用的JAR文件 最后是有main()的执行类

posted @ 2006-07-14 11:40 zhaofei1394 阅读(290) | 评论 (0)编辑 收藏

JSP和JavaScirpt数据交互

对于WEB程序来说,前端(JavaScript)和后端(JSP/Servlet)是没法共用数据的,只能是后端程序(JSP)把数据输出,生成页面到前端,这时候生成的页面中的JavaScript代码才有可能得到所谓jsp的数据。同样的,只有把JavaScript里的数据提交给后端JSP代码,JSP程序中才能得到JavaScript的数据。

    那如何实现在页面的JavaScript中使用jsp中的数据或是在jsp中使用页面的JavaScript数据呢?

一、页面中的JavaScript的数据如何提交给后台的jsp程序
    ① 可以将JavaScript的数据以xxx.JSP?var1=aaa&var2=bbb的形式作为URL的参数传给JSP程序,此时在jsp中用
<%String strVar1=request.getParameter("var1");%>就可以获取到JavaScript脚本传递过来的数据;

    ② 使用JavaScript通过在表单里加入隐藏域信息,然后用表单提交的方式把数据传递给JSP程序。


 
 

二、页面中的JavaScript的数据如何使用后台的JSP程序的数据
    这个比较简单,直接在JavaScript脚本中用<%=strVar1%>就可以把jsp程序中的数据传递给JavaScript脚本使用了。

三、参考下面例子:

1、test.jsp

<%@ page contentType="text/html; charset=gb2312" %>

<%
  String s1="Hello ";
  String s2="World!!";
%>

<script language="JavaScript">
<!--
/***************************************************************
* JavaScript脚本,放置在页面中的任何位置都可以
* insertclick()函数获取JSP传递到页面中的变量s1,
* 然后就可以在JavaScript中修改这个变量的值,再通过
* post的方式提交给JSP程序来使用。
***************************************************************/
function insertclick(){
  var1 ="<%=s1 %>";
  document.forms["insertForm"].mc.value = var1 + document.forms["insertForm"].mc.value ;
  document.insertForm.submit();
}
//-->
</script>

<!-- html页面form表单,放置在html页面中的位置不限 -->
<form name="insertForm" method="post" action="get.jsp">
<!-- 下面这一句是获取JSP程序中传递过来的变量值 -->
<input type="hidden" name="mc" value="<%=s2 %>">
<input type="button" value="提交" onclick="insertclick()">
</form>

2、get.jsp

<%
  String strVar1=request.getParameter("mc");
  out.print(strVar1);
%>

posted @ 2006-07-13 16:17 zhaofei1394 阅读(248) | 评论 (0)编辑 收藏

一个简单的存储过程!

create procedure wap_data_content_zf as
declare @data_0 varchar(100)
declare @date_1 varchar(100)
declare @date_2 varchar(100)
declare @yvisit integer
declare @yadd integer
declare @mvisit integer
declare @madd integer


set @data_0=convert(char(8),getdate(),112)
set @data_1=convert(char(8),dateadd(day,-1,getdate()),112)
set @date_2=left(convert(char(30),dateadd(day,-1,getdate()),121),10)

print @temp_0
print @temp_1
print @temp_2

select @yvisit=count(distinct(mid)) from dbo.wap_log_access_2006_6 where uri='/wap/pd/yysl_yk/index.jsp'
and mid != ''
and create_time >= '2006-06-06 00:00:00'
and create_time <= '2006-06-06 23:59:59'

select @mvisit=count(distinct(mid)) from dbo.wap_log_access_2006_6 where uri='/wap/pd/mlmhc_yk/index.jsp'
and mid != ''
and create_time >= '2006-06-06 00:00:00'
and create_time <= '2006-06-06 23:59:59'

select @yadd=count(distinct(mid)) from dbo.wap_log_fee_2006_6 as a
where a.uri='/wap/pd/yysl_yk/get.jsp'
and a.mid != ''
and a.portal_id=0
and a.create_time >= '2006-06-06 00:00:00'
and a.create_time <= '2006-06-06 23:59:59'
and exists(select * from dbo.wapuser as b where a.mid = b.mid and b.serviceid='30050631'
and b.firsttime >= '2006-06-06 00:00:00'
and b.firsttime <= '2006-06-06 23:59:59')

select @madd=count(distinct(mid)) from dbo.wap_log_fee_2006_6 as a
where a.uri='/wap/pd/mlmhc_yk/get.jsp'
and a.mid != ''
and a.portal_id=0
and a.create_time >= '2006-06-06 00:00:00'
and a.create_time <= '2006-06-06 23:59:59'
and exists(select * from dbo.wapuser as b where a.mid = b.mid and b.serviceid='02011095'
and b.firsttime >= '2006-06-06 00:00:00'
and b.firsttime <= '2006-06-06 23:59:59')

insert into wap_data_content_zf wap(date,mvisit,madd,yvisit,yadd)
       values(@temp_2,@mvisit,@madd,@yvisit,@yadd)

posted @ 2006-06-26 14:23 zhaofei1394 阅读(273) | 评论 (0)编辑 收藏

CREATE PROCEDURE

CREATE PROCEDURE birdincome_zf
AS
declare @actionid integer
declare @mid varchar(100)
declare @service_id varchar(100)

declare  case1    cursor for 
    SELECT mid,service_id from bird_user_2006_03 where type=0 
declare  case2    cursor for 
    SELECT mid,service_id from bird_user_2006_03 where type=1
 
open case1
  fetch next from case1 into @mid,@service_id
  while (@@fetch_status=0)
    begin
        select top 1  @actionid=bb.actionid from  operation_temp_0526 as bb
               where bb.serviceid=@service_id and bb.mid=@mid
        order by bb.id desc

     if (@actionid=1)        
        insert into bird_user_2006_04(mid,service_id,type,portal_id) values(@mid,@service_id,'1','10000')
     else
         print 'ooooooo'     
        fetch next from case1 into @mid,@service_id
   end
deallocate case1

open case2
  fetch next from case2 into @mid,@service_id
  while (@@fetch_status=0)
    begin
        select  top 1 @actionid=bb.actionid from  operation_temp_0526 as bb
               where bb.serviceid=@service_id and bb.mid=@mid
        order by bb.id desc

     if (@actionid != 2)          
        insert into bird_user_2006_04(mid,service_id,type,portal_id) values(@mid,@service_id,'2','10000')
        fetch next from case2 into @mid,@service_id
   end
deallocate case2
GO

posted @ 2006-05-29 13:24 zhaofei1394 阅读(628) | 评论 (0)编辑 收藏

Java的“异常”

Java的“异常”

                    

“ 异 常” 指 的 是 程 序 运 行 时 出 现 的 非 正 常 情 况。 在 用 传统 的 语 言 编 程 时, 程 序 员 只 能 通 过 函 数 的 返 回 值 来 发 出错 误 信 息。 这 易 于 导 致 很 多 错 误, 因 为 在 很 多 情 况 下 需 要知 道 错 误 产 生 的 内 部 细 节。 通 常, 用 全 局 变 量errno来 存 储“ 异 常” 的 类 型。 这 容 易 导 致 误 用, 因 为 一 个errno的 值 有 可 能在 被 处 理 ?reg; 前 被 另 外 的 错 误 覆 盖 掉。 即 使 最 优 美 的C语言 程 序, 为 了 处 理“ 异 常” 情 况, 也 常 求 助 于goto语 句。 Java对“ 异 常” 的 处 理 是 面 向 对 象 的。 一 个Java的Exception是 一 个 描 述“ 异 常” 情 况 的 对 象。 当 出 现“ 异 常” 情 况 时, 一 个Exception对象 就 产 生 了, 并 放 到 产 生 这 个“ 异 常” 的 成 员 函 数 里。

8.1 基础

Java的“ 异 常” 处 理 是 通 过5个 关 键 词 来 实 现 的:try, catch, throw, throws和finally。 用try 来 执 行 一 段 程 序, 如 果 出 现“ 异常”, 系 统 抛 出(throws?copy; 一 个“ 异 常”, 你 可 以 通 过 它 的类 型 来 捕 捉(catch?copy; 它, 或 最 后(finally?copy; 由 缺 省 处理 器 来 处 理。 下 面 是“ 异 常” 处 理 程 序 的 基 本 形 式:

try { //程 序 块 } catch (ExceptionType1 e) { // 对ExceptionType1的处 理 } catch (ExceptionType2 e) { // 对ExceptionType2的 处 理 throw(e); //再 抛 出 这 个“ 异 常” } finally { }

8.2 "异 常” 的 类 型

在“ 异 常” 类 层 次 的 最 上 层 有 一 个 单 独 的 类 叫 做Throwable。这 个 类 用 来 表 示 所 有 的“ 异 常” 情 况。 每 个“ 异 常” 类 型 都是Throwable的 子 类。Throwable有 两 个 直 接 的 子 类。 一 类 是Exception,是 用 户 程 序 能 够 捕 捉 到 的“ 异 常” 情 况。 我 们 将 通 过 产 生它 的 子 类 来 创 建 自 己 的“ 异 常”。 另 一 类 是Error, 它 定 义 了那 ?copy; 通 常 无 法 捕 捉 到 的“ 异 常”。 要 谨 慎 使 用Error子 类,因 为 它 们 通 常 会 导 致 灾 难 性 的 失 败。 在Exception中 有 一 个 子类RuntimeException, 它 是 程 序 运 行 时 自 动 地 对 某 ?copy; 错 误作 出 反 应 而 产 生 的。

8.3 不 捕 捉“ 异 常”

“ 异 常” 对 象 是Java在 运 行 时 对 某 ?copy;“ 异 常” 情 况 作出 反 应 而 产 生 的。 例 如, 下 面 这 个 小 程 序 包 含 一 个 整 数 被0除的“ 异 常”。

class Exc0 { public static void main(String args[]) { int d = 0; int a = 42/d; } }

当Java执 行 这 个 除 法 时, 由 于 分 母 是0, 就 会 构 造 一 个“ 异常” 对 象 来 使 程 序 停 下 来 并 处 理 这 个 错 误 情 况, 在 运 行 时“ 抛 出”(throw?copy; 这 个“ 异 常”。 说“ 抛 出” 是 因 为 它 象 一个 滚 烫 的 马 铃 薯, 你 必 须 把 它 抓 住 并 立 即 处 理。 程 序 流 将会 在 除 号 操 作 符 处 被 打 断, 然 后 检 查 当 前 的 调 用 堆 栈 来查 找“ 异 常”。 一 个“ 异 常” 处 理 器 是 用 来 立 即 处 理“ 异 常” 情 况 的。 在 这 个 例 子 里, 我 们 没 有 编 一 个“ 异 常” 处 理 器,所 以 缺 省 的 处 理 器 就 发 挥 作 用 了。 缺 省 的 处 理 器 打 印Exception的字 符 ?reg; 值 和 发 生 “ 异 常” 的 地 点。 下 面 是 我 们 的 小 例子 的 输 出。

C:\>java Exc0 java.lang.arithmeticException: / by zero at Exc0.main(Exc0.java:4)

8.4 try与catch

通 常 我 们 希 望 自 己 来 处 理“ 异 常” 并 继 续 运 行。 可 以 用try来指 定 一 块 预 防 所 有“ 异 常” 的 的 程 序。 紧 跟 在try程 序 后 面,应 包 含 一 个catch子 句 来 指 定 你 想 要 捕 捉 的“ 异 常” 的 类 型。例 如, 下 面 的 例 子 是 在 前 面 的 例 子 的 基础上 构 造 的, 但 它包 含 一 个try程 序 块 和 一 个catch子 句。

class exc1 { public static void main(string args[]) { try { int d = 0; int a = 42 / d; } catch (arithmeticexception e) { system.out.println("division by zero"); } } }

catch子 句 的 目 标 是 解 决“ 异 常” 情 况, 把 一 ?copy; 变 量 设到 合 理 的 状 态, 并 象 没 有 出 错 一 样 继 续 运 行。 如 果 一 个 子程 序 不 处 理 某 个“ 异 常”, 则 返 到 上 一 级 处 理, 直 到 最 外一 级。

8.5 多 个catch子 句

在 某 ?copy; 情 况 下, 同 一 段 程 序 可 能 产 生 不 止 一 种“ 异常” 情 况。 你 可 以 放 置 多 个catch子 句, 其 中 每 一 种“ 异 常” 类 型 都 将 被 检 查, 第 一 个 与 ?reg; 匹 配 的 就 会 被 执 行。 如果 一 个 类 和 其 子 类 都 有 的 话, 应 把 子 类 放 在 前 面, 否 则 将永 远 不 会 到 达 子 类。 下 面 是 一 个 有 两 个catch子 句 的 程 序 的例 子。

class MultiCatch { public static void main(String args[]) { try { int a = args.length; System.out.println("a = " + a); int b = 42/a; int c[] = {1}; c[42] = 99; } catch(ArithmeticException e) { System.out.println("div by 0: " + e); } catch(ArrayIndexOutOfBoundsException e) { system.out.println("array index oob: " + e); } } }

如 果 在 程 序 运 行 时 不 跟 参 数, 将 会 引 起 一 个0做 除 数 的“ 异 常”, 因 为a的 值 为0。 如 果 我 们 提 ?copy; 一 个 命 令 行 参 数,将 不 会 产 生 这 个“ 异 常”, 因 为a的 值 大 于0。 但 会 引 起 一 个 ArrayIndexOutOfBoundexception的“ 异 常”, 因 为 整 型 数 组c的 长 度是1, 却 给c[42]赋 值。 下 面 是 以 上 两 种 情 况 的 运 行 结 果。

C:\>java MultiCatch a = 0 div by 0: java.lang.arithmeticexception: / by zero C:\>java MutiCatch 1 a = 1 array index oob: java.lang.ArrayIndexOutOfBoundsException:42

8.6 try语 句 的 嵌 套

你 可 以 在 一 个 成 员 函 数 调 用 的 外 面 写 一 个try语 句, 在 这个 成 员 函 数 内 部, 写 另 一 个try语 句 保 护 其 他 代 码。 每 当 遇到 一 个try语 句,“ 异 常” 的 框 架 就 放 到 堆 栈 上 面, 直 到 所 有的try语 句 都 完 成。 如 果 下 一 级 的try语 句 没 有 对 某 种“ 异 常” 进 行 处 理, 堆 栈 就 会 展 开, 直 到 遇 到 有 处 理 这 种“ 异 常” 的try语 句。 下 面 是 一 个try语 句 嵌 套 的 例 子。

class MultiNest { static void procedure() { try { int c[] = { 1 }: c[42] = 99; } catch(ArrayIndexOutOfBoundsexception e) { System.out.println("array index oob: " + e); } } public static void main(String args[]) { try { int a = args.length; system.out.println("a = " + a); int b = 42/a; procedure(); } catch(arithmeticException e) { System.out.println("div by 0: " + e); } } }

成 员 函 数procedure里 有 自 己 的try/catch控 制, 所 以main不 用 去处 理 ArrayIndexOutOfBoundsException。

8.7 throw语 句

throw语 句 用 来 明 确 地 抛 出 一 个“ 异 常”。 首 先, 你 必 须 得到 一 个Throwable的 实 例 的 控 制 柄, 通 过 参 数 传 到catch子 句, 或者 用new操 作 符 来 创 建 一 个。 下 面 是throw语 句 的 通 常 形 式。

throw ThrowableInstance;

程 序 会 在throw语 句 后 立 即 终 止, 它 后 面 的 语 句 执 行 不 到,然 后 在 包 含 它 的 所 有try块 中 从 里 向 外 寻 找 含 有 与 其 匹 配的catch子 句 的try块。 下 面 是 一 个 含 有throw语 句 的 例 子。

class ThrowDemo { static void demoproc() { try { throw new NullPointerException("de3mo"); } catch(NullPointerException e) { System.out.println("caught inside demoproc"); throw e; } } public static void main(String args[]) { try { demoproc(); } catch(NullPointerException e) { system.out.println("recaught: " + e); } } }

8.8 throws语 句

throws用 来 标 明 一 个 成 员 函 数 可 能 抛 出 的 各 种“ 异 常”。对 大 多 数Exception子 类 来 说,Java 编 译 器 会 强 迫 你 声 明 在 一个 成 员 函 数 中 抛 出 的“ 异 常” 的 类 型。 如 果“ 异 常” 的 类 型是Error或 RuntimeException, 或 它 们 的 子 类, 这 个 规 则 不 起 作 用,因 为 这 ?copy; 在 程 序 的 正 常 部 分 中 是 不 期 待 出 现 的。 如 果你 想 明 确 地 抛 出 一 个RuntimeException, 你 必 须 用throws语 句 来声 明 它 的 类 型。 这 就 重 新 定 义 了 成 员 函 数 的 定 义 语 法:

type method-name(arg-list) throws exception-list { }

下 面 是 一 段 程 序, 它 抛 出 了 一 个“ 异 常”, 但 既 没 有 捕捉 它, 也 没 有 用throws来 声 明。 这 在 编 译 时 将 不 会 通 过。

class ThrowsDemo1 { static void procedure( ) [ System.out.println("inside procedure"); throw new IllegalAccessException("demo"); } public static void main(String args[]) { procedure( ); } }

为 了 让 这 个 例 子 编 译 过 去, 我 们 需 要 声 明 成 员 函 数procedure抛出 了IllegalAccessException, 并 且 在 调 用 它 的 成 员 函 数main里 捕捉 它。 下 面 是 正 确 的 例 子:

class ThrowsDemo { static void procedure( ) throws IllegalAccessException { System.out.println("inside procedure"); throw new IllegalAccessException("demo"); } public static void main(String args[]) { try { procedure( ); } catch (IllegalAccessException e) { System.out.println("caught " + e); } } }

下 面 是 输 出 结 果:

C:\>java ThrowsDemo inside procedure caught java.lang.IllegalAccessException: demo

8.9 finally

当 一 个“ 异 常” 被 抛 出 时, 程 序 的 执 行 就 不 再 是 线 性 的,跳 过 某 ?copy; 行, 甚 至 会 由 于 没 有 与 ?reg; 匹 配 的catch子 句而 过 早 地 返 回。 有 时 确 保 一 段 代 码 不 管 发 生 什 么“ 异 常” 都 被 执 行 到 是 必 要 的, 关 键 词finally就 是 用 来 标 识 这 样 一段 代 码 的。 即 使 你 没 有catch子 句,finally程 序 块 也 会 在 执 行 try程 序 块 后 的 程 序 ?reg; 前 执 行。 每 个try语 句 都 需 要 至 少一 个 与 ?reg; 相 配 的catch子 句 或finally子 句。 一 个 成 员 函 数 返回 到 调 用 它 的 成 员 函 数, 或 者 通 过 一 个 没 捕 捉 到 的“ 异 常”,或 者 通 过 一 个 明 确 的return语 句,finally子 句 总 是 恰 好 在 成 员函 数 返 回 前 执 行。 下 面 是 一 个 例 子, 它 有 几 个 成 员 函 数,每 个 成 员 函 数 用 不 同 的 途 径 退 出, 但 执 行 了finally子 句。

class FinallyDemo { static void procA( ) { try { System.out.println("inside procA"); throw new RuntimeException("demo"); } finally { System.out.println("procA's finally"); } } static void procB( ) { try { System.out.println("inside procB"); return; } finally { System.out.println("procB's finally"); } } public static void main(String args[]) { try { procA( ); } catch (Exception e); procB( ); } }

下 面 是 这 个 例 子 的 运 行 结 果:

C:\>java FinallyDemo inside procA procA's finally inside procB procB's finally

本 章 小 结

1. “ 异 常” 指 的 是 程 序 运 行 时 出 现 的 非 正 常 情 况。 2. 在“ 异 常” 类 ?次 的 最 上 层 的 类 叫Throwable, 它 有 两 个 直 接 的 子类:Exception和Error。 3. Java的“ 异 常” 处 理 通 过5个 关 键 词 来 实现:try,catch,throw,throws和finally。

posted @ 2006-04-20 16:41 zhaofei1394 阅读(270) | 评论 (0)编辑 收藏

导航

统计

常用链接

留言簿(1)

随笔分类

随笔档案

文章分类

文章档案

友情链接

搜索

最新评论

阅读排行榜

评论排行榜