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

星期二, 9月 01, 2009

指定Java Application使用的語言

開發Java程式時, 可以利用resource的方式, 將程式的訊息以及ui等設計成支援多國語言, 然後執行時加上-Duser.language=locale_name或-Duser.country=country_name就可以切換不同的語言介面.

完整的指令為

顯示英文介面:
java -Duser.language=en -jar test.jar或
java -Duser.country=us -jar test.jar

顯示中文介面:
java -Duser.language=zh -jar test.jar或
java -Duser.country=TW -jar test.jar

星期五, 3月 06, 2009

Static initialization block and initializer block

Static initialization block在類別載入時會執行該區塊中的程式碼, 而且整個程式的執行過程中只會執行一次.

Initializer block則是在每個物件被建立時執行該區塊中的程式碼, 接著才執行contructor中的程式碼.

class ClassA {
    // static initialization block
    static {
        System.out.println("This is static initialization blocks");
    }

    // initializer block
    {
        System.out.println("This is initializer block");
    }

    public ClassA()
    {
        System.out.println("Constructor A");
    }

    public void print()
    {
        System.out.println("I am A");
    }

    public static void staticPrint()
    {
        System.out.println("Static print");
    }
}

public class Test01 {
    public static void main(String[] args) {
        System.out.println("Start testing...");
        ClassA.staticPrint();
        ClassA a = new ClassA();
        a.print();
    }
}

星期日, 3月 01, 2009

Java的String pool

Java執行時會維護一個String pool, 對於一些可以共享的字串物件, 會先在String pool中尋找, 有相同的字串內容就直接傳回, 減少記憶體的耗用.

public class test02 {
    public static void main(String args[])
    {
        String a = new String("abc");
        String b = new String("abc");
        String c = "abc";
        String d = "abc";
        String e = "def";
        String f = "abcdef";
        String g = c+e;
        String h = (c+e).intern(); 
        String i = new String("abc").intern();

        System.out.println(a == b);    // false
        System.out.println(c == d);    // true
        System.out.println(f == g);    // false
        System.out.println(f == h);    // true
    }
}

星期四, 2月 05, 2009

Java中的foreach

J2SE 5.0之後新增了foreach的語法, 可用於存取陣列元素. 以下為一些簡單的範例:

一維陣列

public class test02 {
    public static void main(String args[])
    {
        int[] a = new int[] {1, 2, 3, 4, 5};

        for(int v : a)
            System.out.println(v);
    }
}

二維陣列

public class test02 {
    public static void main(String args[])
    {
        int[][] a = new int[][] {
            {1, 2, 3, 4, 5},
            {10, 11, 12}
        };

        for(int[] row : a) {
            for(int element : row)
                System.out.print(element + " ");
            System.out.println();
        }
    }
}

Autoboxing in Java

自動boxing/unboxing是J2SE 5.0之後提供的新功能, 可以由compiler視程式需要自動在primitive data type以及object之間進行轉換. Boxing就是將primitive data type轉成object, 而unboxing則是把object轉成對應的primitive data type. 如下範例所示:

public class test02 {
    public static void main(String args[])
    {
        Integer i1;
        int a = 100;

        i1 = new Integer(a); // boxing
        i1 = a/2; // auto boxing

        a = i1.intValue()/5; // unboxing
        a = i1/2; // auto unboxing
    }
}

雖然這功能非常方便, 但是有幾點是必須要注意的. 首先, 因為這動作是compiler time的動作, 所以有可能會發生程式可以成功編譯但是執行時卻發生執行錯誤的現象. 例如:

public class test02 {
    public static void main(String args[])
    {
        Integer i = null;
        int a;

        a = i / 2; // null pointer exception
    }
}

另外, 數值大小不同也會使boxing的行為有些不同, 例如:

public class test02 {
    public static void main(String args[])
    {
        Integer i = 100;
        Integer j = 100;

        if(i == j)
            System.out.println("equal");
        else
            System.out.println("not equal");
    }
}

此程式會得到equal. 但是下一個範例則會得到not equal.

public class test02 {
    public static void main(String args[])
    {
        Integer i = 200;
        Integer j = 200;

        if(i == j)
            System.out.println("equal");
        else
            System.out.println("not equal");
    }
}

這兩個範例唯一的差別在於程式中所指定的數值, 一個為100, 另一個為200, 但是結果卻也不同. 這是因為auto boxing 在數值介於-128到127之間時, 記憶體會重複使用, 所以第一個範例的i與j會是相同的物件. 反之, 第二個範例則會是兩個不同的物件, 所以兩支程式的執行結果也就不一樣.