Java/Web

1、Map的get和containsKey方法。对于get,API中说“如果此映射包含满足 (key==null ? k==null : key.equals(k)) 的键 k 到值 v 的映射关系,则此方法返回 v;否则返回 null。”实际上不止如此,还要比较hashCode。所以要实现以对象查对象,必须同时重写key类的equals和hashCode。containsKey也是如此,《Java编程思想》对此有详细解释,这里写的也很好http://blog.csdn.net/RichardSundusky/archive/2007/02/12/1508028.aspx

2、Statement compensationSt = derbyConn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);这个大家都知道,意思是结果集可前后滚动,对修改不敏感,而且是一个可更新的结果集,即支持结果集的UPDATE/DELETE。但是如果Sql带有Order By子句,那么结果集就不再可更新了,即使用updateRow或deleteRow就会出错。

3、关于String:http://zangweiren.javaeye.com/blog/209895http://topic.csdn.net/u/20081222/15/e77deb11-11a2-4a31-a478-f7331270230a.html

4、static块是在类装载时运行的,所以块里面即使有常量初始化赋值,也不能在编译期确定:
1 final int A = 1;
2 final int B;
3 static {
4     B = 2;
5 }
6 int C = A; //编译期确定C的值,即此句等同于int C = 1;
7 int D = B; //虽然B为常量,但编译期尚不确定其值,所以不等同于int D = 2;

5、HttpSession持久化
http://blog.csdn.net/djsl6071/archive/2007/01/19/1487937.aspx文章中已经写得很明白了,要在server.xml中配置:

<Context path="/helloapp" docBase="helloapp" debug="0" reloadable="true">
    
<Manager className="org.apache.catalina.session.PersistentManager" debug="0" saveOnRestart="true" maxActiveSessions="-1" minIdleSwap="-1" maxIdleSwap="-1" maxIdleBackup="-1" >
    
<Store className="org.apache.catalina.session.FileStore" directory="session"/>
    
</Manager>
</Context>

若是Eclipse WTP,默认保存地址大约在<Workspace>\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\work\Catalina\honstname\applicatonname\下。
这样Tomcat会把Session存储为文件,即使Tomcat关闭重启,服务器依然可以读取上次的Session,代码不需要什么更改,比如:

String nickname = (String)session.getAttribute("nickname");
System.out.println(nickname);
if(nickname==null){
    nickname 
= "kissrat";
    session.setAttribute(
"nickname", nickname);
}

再次启动时就会自动读取以保存的Session。但是,持久化Session也是有限制条件的,比如只能存储已实现Serializable的对象:

class NewClass implements java.io.Serializable{
    
private static final long serialVersionUID = 1448912554730655971L;        
}

NewClass nc 
= (NewClass)session.getAttribute("nc");
if(nc==null){
    System.out.println(
"若NewClass没有实现Serializable,则每次都会执行到这里。");
    nc 
= new NewClass();
    session.setAttribute(
"nc", nc);
}

 当然,这个NewClass如果有其他对象成员,则所有成员对象的类都必须实现过Serializable。

6、必然导致的死锁(Guaranteed Deadlock)

 1public class DeadLock {
 2    static final Object lock1 = new Object(), o2 = new Object();
 3    
 4    class Thread2 extends Thread{
 5        public void run(){
 6            synchronized(lock1){
 7                lock1.notifyAll();
 8                synchronized(o2){
 9                }

10            }

11        }

12    }

13
14    class Thread1 extends Thread{
15        public void run(){
16            synchronized(lock1){
17                synchronized(o2){
18                    Thread2 t2 = new Thread2();
19                    t2.start();
20                    try {
21                        lock1.wait();
22                    }
 catch (InterruptedException e) {
23                    }

24                }

25            }

26        }

27    }

28    
29    public void deadlock(){
30        Thread1 t1 = new Thread1();
31        t1.start();
32    }

33    
34    public static void main(String[] args) {
35        new DeadLock().deadlock();
36    }

37
38}

如果用时序上的特殊调度来导致死锁是不能达到要求的,不能指望调度器来产生必然的死锁。比如:

 1public class DeadLock {
 2    static void noop(){}
 3    private static Thread t;
 4    public synchronized static void main(final String[] args) throws InterruptedException {
 5        (t = new Thread() {
 6            public synchronized void run() {
 7                synchronized (DeadLock.class{
 8                }

 9            }

10        }
).start();
11        //noop(); //参考二:t一定先获得自身锁吗?
12        synchronized (t) {
13            t.wait(100); //参考一:看起来可靠,有本事不要这句
14        }

15    }

16}

参考精简版(http://www.jroller.com/skavish/entry/how_to_create_a_guaranteed):

 1static final Object lock1 = new Object();   
 2static final Object lock2 = new Object();   
 3  
 4public static void main( String[] args ) {   
 5    new Thread(new Runnable() {   
 6        public void run() {   
 7            synchronized(lock1) {   
 8                synchronized(lock2) {   
 9                    new Thread(new Runnable() {   
10                        public void run() {   
11                            synchronized(lock1) {   
12                                lock1.notifyAll();   
13                                synchronized(lock2) {   
14                                    System.out.println("never get here");   
15                                }
   
16                            }
   
17                        }
   
18                    }
).start();   
19                    try {   
20                        lock1.wait();   
21                    }
 catch( InterruptedException e ) {   
22                    }
   
23                }
   
24            }
   
25        }
   
26    }
).start();   
27}
 

 

 1public class DeadLock {
 2    private static Thread thread = null;
 3    public static void main(final String[] args) throws Exception {
 4        Runnable r = new Runnable() {
 5            public synchronized void run() {
 6            }

 7        }
;
 8        synchronized (r) {
 9            (thread = new Thread(r)).start();
10            thread.join();
11        }

12    }

13}

 7、强制类型转换赋值在编译期不会出错,但在运行时可能会抛出ClassCastException异常。

Code
 1 package lahvey;
 2 
 3 class Super{
 4 }
 5 
 6 public class Sub extends Super{
 7     static Super getSub(){
 8         return new Sub();
 9     }
10     
11     public static void main(String args[]){
12         Super sup= getSub();
13         Sub sub = new Sub();
14         sub = (Sub)sup;
15     }
16 }

  若是把第8行改成return new Super();虽然编译能够通过,但运行时会出错。原因是sup对象可能不能被Cast到Sub类型。

8. finally有权覆盖try{}catch{}块中所有的Exception和return值:

1 public int getInt(){
2     try{
3         throw new RuntimeException();
4     } finally {
5         return 0;
6     }
7 }

由于被finally的return语句块覆盖,RuntimeException是不会被抛出的。

1 public static int getInt(){
2     try{
3         return 1;          
4     } finally {
5         return 0;
6     }
7 }

第3句的return会被finally覆盖,因此第5句return会执行,函数返回0;

1 public static int getInt(){
2     int i = 1;
3     try{
4         return i;          
5     } finally {
6         i = 0;
7     }
8 }

当然这次的返回值不会被finally改变,虽然finally一定会执行,但是reutrn语句的执行已经将返回值写入了栈中,再对变量i赋值已经没意义了,除非像上面一样再来一次return重新将i的值写回栈。

 8. 编译时如果能确定变量未初始化就被使用,则会出现编译错误。

String s;
System.out.println(s); 
//Compile Error: The local variable s may not have been initialized

String s = null//初始化
System.out.println(s); //输出为null

9. 处理简单的XML就用W3C DOM:字符串直接转为XML Document对象:

 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

try {
   DocumentBuilder builder = factory.newDocumentBuilder();
    Document doc = builder.parse(new InputSource(new StringReader(xml)));
    ...
catch (SAXException e) {
    e.printStackTrace();
catch (IOException e) {
    e.printStackTrace();
catch (ParserConfigurationException e) {
    e.printStackTrace();
}

参考:http://www.yesky.com/394/1757894_2.shtmlhttp://www.blogjava.net/hopeshared/archive/2006/07/06/56919.aspx

10. Base64编码, DES加解密参考:

http://yidinghe.cnblogs.com/articles/449212.html

http://blog.csdn.net/cmj198799/article/details/6866705 

注意:如果发现同样的代码加密的结果却不同,请检查Java源文件的编码! 

11. JSON的处理使用GSON,http://code.google.com/p/google-gson/

Json字符串格式为{...},不带变量名var json={...};

posted @ 2009-07-13 20:06  千年  阅读(347)  评论(0编辑  收藏  举报