顯示具有 Java 標籤的文章。 顯示所有文章
顯示具有 Java 標籤的文章。 顯示所有文章

2012年4月15日 星期日

test java extends cast 繼承 轉型


/** CastTest.java */
class A{}
class B extends A
{
    public void f()
    {
        System.out.println("f() in B");
    }
}
public class CastTest
{
    public static void main(String args[])
    {
        A a = new B();
        ((B)a).f();
        (B)a.f(); //  error: not a statement
        a.f();
        /* error: cannot find symbol
                 a.f(); // error
                 ^
           symbol:   method f()
           location: variable a of type A */
    }
   

test java


/** CastTest.java */
public class CastTest
{
    class A{}
    public static void main(String args[])
    {
        A a = new A();
    }
}

輸出結果:
CastTest.java:7: error: non-static variable this cannot be referenced from a
static context
        A a = new A();
              ^
1 error


我不懂,哪裡錯了?

若是把 class A 寫在外面,就過了

/** CastTest2.java */
class A{}
public class CastTest
{
    public static void main(String args[])
    {
        A a = new A();
    }
}

2012年4月14日 星期六

test java gc

/** MyObject.java */
public class MyObject {
    static int count;
    MyObject() {
        ++count;
    }
    public static void main(String[] args) {
        MyObject obj1 = new MyObject();
        MyObject obj2 = new MyObject();
        MyObject obj3 = new MyObject();
        System.out.println("目前有" +count+ "個物件");
        obj2 = null;
        System.out.println("請求G.C.");
        System.gc();
        System.out.println("目前剩餘" +count+ "個物件");
    }
    protected void finalize() throws Throwable {
        --count;
        String tName = Thread.currentThread().getName();
        System.out.println("執行finalize()的是:" + tName);
    }
}

輸出結果:
目前有3個物件
請求G.C.
目前剩餘3個物件
執行finalize()的是:Finalizer

2012年3月13日 星期二

Java Finalize

MEMO 123: Java筆記-Finalize 終結物件
http://jhengjyun.blogspot.com/2010/09/java-finalize.html

深入理解java的finalize - Java - ITeye论坛
http://www.iteye.com/topic/484934

深入理解ReferenceQueue GC finalize Reference - zhang_xzhi's blog - ITeye技术网站
http://zhang-xzhi-xjtu.iteye.com/blog/413159

...可以從結果看到finalize方法只運行了1次。為什麼呢,因為第一次finalize運行過後,該對象的finalizable置為false了,所以該對象即使以後被gc運行,也不會執行finalize方法了。

很明顯,對象再生是一個不好的編程實踐,打亂了正常的對象生命週期。但是如果真的需要這麼用的話,應該用當前對象為原型重新生成一個對象使用,這樣以後這個新的對象還可以被GC運行finalize方法。

[Java] final, finally, finalize的區別? - 碳烤烏龜 - 無名小站
http://www.wretch.cc/blog/forkome/9008339

2012年3月8日 星期四

在Windows下利用.bat來編譯及執行java

安裝完JDK後

新增純文字文件,修改檔名 副檔名 並編輯

如下所示

檔名: compile_java.bat

::JavaBinPath須為實際裝有javac.exe的路徑
set JavaBinPath="C:\Program Files\Java\jdk1.6.0_24\bin\"
%JavaBinPath%javac charFreq_2.java
pause

檔名: execute_java.bat

::JavaBinPath須為實際裝有java.exe的路徑
set JavaBinPath="C:\Program Files\Java\jdk1.6.0_24\bin\"
%JavaBinPath%java charFreq_2 "123 123 213"
pause

compile_java.bat execute_java.bat
與欲編譯執行的檔案(ex. charFreq_2.java)擺在同一資料夾

Java Notes : Local/Instance/Class Variables

Java Notes : Local/Instance/Class Variables
http://www.leepoint.net/notes-java/data/variables/45local-inst-class.html

2011年4月5日 星期二

Evil C

Evil C
http://www.steike.com/code/useless/evil-c/
This is a collection of strange C (and some Java) constructs. It's probably best not to use them, but you should know why they work.

2011年3月31日 星期四

程式碼排版的好工具 Artistic Style

http://jarsing.blogspot.com/2007/10/artistic-style.html

可以通吃C、C++、C#和Java

astyle -rn --style=ansi --indent=tab --indent-switches --indent-cases *.c *.h

因為Artistic Style會將舊的程式檔案備份起來,但是我覺得這樣浪費空間,所以使用參數「n」選擇不留存這些原始內容的備份檔案(這當然是有風險的,但是我選擇相信這套工具),另外參數「r」則會以遞迴的方式處理所有子目錄。換言之,這段指令會一次處理專案內的所有程式檔案,而且不會進行備份。

更多有關參數的詳細用法,可以透過執行astyle --help取得。

2011年3月5日 星期六

java String深入constant pool

聲明 來源於:http://hi.baidu.com/boywell/blog/item/a069bccbc45e7c4cf31fe758.html

Constant Pool常量池的概念:

在講到String的一些特殊情況時,總會提到String Pool或者Constant Pool,但是我想很多人都不太
明白Constant Pool到底是個怎麼樣的東西,運行的時候存儲在哪裡,所以在這裡先說一下Constant Pool的內容.
String Pool是對應於在Constant Pool中存儲String常量的區域.習慣稱為String Pool,也有人稱為
String Constant Pool.好像沒有正式的命名??

在java編譯好的class文件中,有個區域稱為Constant Pool,他是一個由數組組成的表,類型
為cp_info constant_pool[],用來存儲程序中使用的各種常量,包括Class/String/Integer等各
種基本Java數據類型,詳情參見The Java Virtual Machine Specification 4.4章節.


關於String類的說明
1.String使用private final char value[]來實現字符串的存儲,也就是說String對象創建之後,就不能
再修改此對象中存儲的字符串內容,就是因為如此,才說String類型是不可變的(immutable).

2.String類有一個特殊的創建方法,就是使用""雙引號來創建.例如new String("i am")實際創建了2個
String對象,一個是"i am"通過""雙引號創建的,另一個是通過new創建的.只不過他們創建的時期不同,
一個是編譯期,一個是運行期!

3.java對String類型重載了+操作符,可以直接使用+對兩個字符串進行連接.

4.運行期調用String類的intern()方法可以向String Pool中動態添加對象.

String的創建方法一般有如下幾種
1.直接使用""引號創建.
2.使用new String()創建.
3.使用new String("someString")創建以及其他的一些重載構造函數創建.
4.使用重載的字符串連接操作符+創建.

例1
    /*
    * "sss111"是編譯期常量,編譯時已經能確定它的值,在編譯
    * 好的class文件中它已經在String Pool中了,此語句會在
    * String Pool中查找等於"sss111"的字符串(用equals(Object)方法確定),
    * 如果存在就把引用返回,付值給s1.不存在就會創建一個"sss111"放在
    * String Pool中,然後把引用返回,付值給s1.
    *
    */
    String s1 = "sss111";

    //此語句同上
    String s2 = "sss111";

    /*
    * 由於String Pool只會維護一個值相同的String對象
    * 上面2句得到的引用是String Pool中同一個對象,所以
    * 他們引用相等
    */
    System.out.println(s1 == s2); //結果為true


例2
    /*
    * 在java中,使用new關鍵字會創建一個新對象,在本例中,不管在
    * String Pool中是否已經有值相同的對象,都會創建了一個新的
    * String對象存儲在heap中,然後把引用返回賦給s1.
    * 本例中使用了String的public String(String original)構造函數.
    */
    String s1 = new String("sss111");
 
    /*
     * 此句會按照例1中所述在String Pool中查找
     */
    String s2 = "sss111";
 
    /*
     * 由於s1是new出的新對象,存儲在heap中,s2指向的對象
     * 存儲在String Pool中,他們肯定不是同一個對象,只是
     * 存儲的字符串值相同,所以返回false.
     */
    System.out.println(s1 == s2); //結果為false


例3
    String s1 = new String("sss111");
    /*
    * 當調用intern方法時,如果String Pool中已經包含一個等於此String對象
    * 的字符串(用 equals(Object)方法確定),則返回池中的字符串.否則,將此
    * String對象添加到池中,並返回此String對象在String Pool中的引用.
    */
    s1 = s1.intern();
 
    String s2 = "sss111";
 
    /*
     * 由於執行了s1 = s1.intern(),會使s1指向String Pool中值為"sss111"
     * 的字符串對象,s2也指向了同樣的對象,所以結果為true
     */
    System.out.println(s1 == s2);


例4
    String s1 = new String("111");
    String s2 = "sss111";
 
/*
    * 由於進行連接的2個字符串都是常量,編譯期就能確定連接後的值了,
    * 編譯器會進行優化直接把他們表示成"sss111"存儲到String Pool中,
    * 由於上邊的s2="sss111"已經在String Pool中加入了"sss111",
    * 此句會把s3指向和s2相同的對象,所以他們引用相同.此時"sss"和"111"
    * 兩個常量不會再創建.
    */

    String s3 = "sss" + "111";
 
    /*
     * 由於s1是個變量,在編譯期不能確定它的值是多少,所以
     * 會在執行的時候創建一個新的String對象存儲到heap中,
     * 然後賦值給s4.
     */
    String s4 = "sss" + s1;
 
    System.out.println(s2 == s3); //true
    System.out.println(s2 == s4); //false
    System.out.println(s2 == s4.intern()); //true


例5
這個是The Java Language Specification中3.10.5節的例子,有了上面的說明,這個應該不難理解了
    package testPackage;
    class Test {
            public static void main(String[] args) {
                    String hello = "Hello", lo = "lo";
                    System.out.print((hello == "Hello") + " ");
                    System.out.print((Other.hello == hello) + " ");
                    System.out.print((other.Other.hello == hello) + " ");
                    System.out.print((hello == ("Hel"+"lo")) + " ");
                    System.out.print((hello == ("Hel"+lo)) + " "); //lo在runtime會創建一個新的對象
                    System.out.println(hello == ("Hel"+lo).intern());
            }
    }
    class Other { static String hello = "Hello"; }

    package other;
    public class Other { static String hello = "Hello"; }

輸出結果為true true true true false true,請自行分析!


結果上面分析,總結如下:
1.單獨使用""引號創建的字符串都是常量,編譯期就已經確定存儲到String Pool中.
2.使用new String("")創建的對象會存儲到heap中,是運行期新創建的.
3.使用只包含常量的字符串連接符如"aa" + "aa"創建的也是常量,編譯期就能確定,已經確定存儲到String Pool中.(編譯時會直接優化成"aaaa",如果String Pool 中沒有"aaaa",就用""號創建一個String,直接放到Pool中,比如:String t = "a"+ "b" +"c"; 會優化成"abc",然後放入Pool中;又比如String s = "x"+"y"+ref;在編譯時有部分的優化:"xy",而ref + "x" +"y"就不會有部分的優化,"+"從左到右執行,ref是變量,編譯時期無法確定)

4.使用包含變量的字符串連接符如"aa" + s1創建的對象是運行期才創建的,存儲在heap中.

(根據java api文檔中String類所講,會在內部使用stringbuffer及其append方法來實現連接,然後執行toString(),這樣就會在運行時又創建一個新對象)

還有幾個經常考的面試題:

1.
String s1 = new String("s1") ;
String s2 = new String("s1") ;
上面創建了幾個String對象?
答案:3個 ,編譯期Constant Pool中創建1個,運行期heap中創建2個.

發現有空還要看看基礎了.+.jvm