Thinking in Java notes (1~10)
一,資料類型測試
class A{ public int i; public double d; public float f; public long l; public boolean b; public char c; public short s; public byte by; }public class ClassTest { public static void main(String args[]){ A a = new A(); System.out.println("a.i="+a.i); System.out.println("a.d="+a.d); System.out.println("a.b="+a.b); System.out.println("a.by="+a.by); System.out.println("a.c="+a.c); System.out.println("a.s="+a.s); System.out.println("a.f="+a.f); } } 輸出的結果為: a.i = 0 a.d = 0.0 a.c = a a.s = 0 a.f = 0.0 a.b = false a.by = 0;
解釋:
因為類地成員變數預設初始化,一個字元的預設初始化為ASCII值為000的字元
ASCII值為000的字元變為字元在dos下顯示為a (jdk 1.6.0.8)
假若在ClassTest類裡面加上 int m ;則必須初始化 不然報錯
二,一個類能夠被public ,static,friendly 修飾
三,static測試
class A{ public A(){ System.out.println("hello I am A "); } static{ System.out.println("hello I am A static"); } } class ClassTest{ static{ System.out.println("hello I am ClassTest "); } public static void main(String args[]){ A a = new A(); } }
輸出結果:
hello I am ClassTest
hello I am A static
hello I am A
解釋:static 塊先於建構函式,屬於靜態繫結。而類對象的產生屬於動態綁定。
四,自動成長測試
public class AutoInc {public static void main(String[] args){int i = 1;System.out.println("i : " + i);System.out.println("++i : " + ++i); // Pre-incrementSystem.out.println("i++ : " + i++); // Post-increment//System.out.println("i : " + i);System.out.println("--i : " + --i); // Pre-decrementSystem.out.println("i-- : " + i--); // Post-decrementSystem.out.println("i : " + i);}}
輸出結果:
"i : 1",
"++i : 2",
"i++ : 2",
"i : 3",
"--i : 2",
"i-- : 2",
"i : 1"
五 測試equals
class Value { int i;}public class EqualsMethod { public static void main(String[] args) { Integer n1 = new Integer(47);Integer n2 = new Integer(47);System.out.println(n1.equals(n2)); Value v1 = new Value();Value v2 = new Value(); v1.i = v2.i = 100; //表示指向同一個資料System.out.println(new Integer(v1.i).equals(v2.i));System.out.println(v1.equals(v2)); }}
輸出結果:
true
true
false
六 小數轉換
public class CastingNumbers { public static void main(String[] args){ double above = 0.7, below = 0.4;System.out.println("above: " + above);System.out.println("below: " + below);System.out.println("(int)above: " + (int)above);System.out.println("(int)below: " + (int)below);System.out.println("(char)('a' + above): " + (char)('a' + above));System.out.println("(char)('a' + below): " + (char)('a' + below));}}
結果:
above: 0.7
below: 0.4
(int)above: 0
(int)below: 0
(char)('a' + above): a
(char)('a' + below): a
解釋: 將一個 float 或double 值轉型成整數值後,總是將小數部分“砍掉”
(而不是四捨五入)。
,方法重載
//import java.util.*;class Tree {int height;Tree() {System.out.println("Planting a seedling");height = 0;}Tree(int i) {System.out.println("Creating new Tree that is "+ i + " feet tall");height = i;}void info() {System.out.println("Tree is " + height + " feet tall");}void info(String s) {System.out.println(s + ": Tree is "+ height + " feet tall");}}public class Overload { public static void main(String[] args) {for(int i = 0; i < 5; i++) {Tree t = new Tree(i);t.info();t.info("overloaded method");}// Overloaded constructor:new Tree();}}
解釋:
方法重載一定要方法名相同,參數不同(類型,順序,個數)
** 構造方法和普通方法都可以重載。
附加: 基本類型的重載
基本類型能從一個“較小”的類型自動提升至一個“較大”的類型,此過程一旦牽涉到重載,可能會造成一些混淆。以下例子說明了將基本類型傳遞給重載方法時發生的情況:
public class PrimitiveOverloading{ void f1(char x) { System.out.println("f1(char)"); }void f1(byte x) { System.out.println("f1(byte)"); }void f1(short x) { System.out.println("f1(short)");}void f1(int x) { System.out.println("f1(int)"); }void f1(long x) { System.out.println("f1(long)"); }void f1(float x) { System.out.println("f1(float)"); }void f1(double x) { System.out.println("f1(double)"); } void f2(byte x) { System.out.println("f2(byte)"); }void f2(short x) { System.out.println("f2(short)"); }void f2(int x) { System.out.println("f2(int)"); }void f2(long x) { System.out.println("f2(long)"); }void f2(float x) { System.out.println("f2(float)"); }void f2(double x) { System.out.println("f2(double)"); }void f3(short x) { System.out.println("f3(short)"); }void f3(int x) { System.out.println("f3(int)"); }void f3(long x) { System.out.println("f3(long)"); }void f3(float x) { System.out.println("f3(float)"); }void f3(double x) { System.out.println("f3(double)"); } void f4(int x) { System.out.println("f4(int)"); }void f4(long x) { System.out.println("f4(long)"); }void f4(float x) { System.out.println("f4(float)"); }void f4(double x) { System.out.println("f4(double)"); } void f5(long x) { System.out.println("f5(long)"); }void f5(float x) { System.out.println("f5(float)"); }void f5(double x) { System.out.println("f5(double)"); } void f6(float x) { System.out.println("f6(float)"); }void f6(double x) { System.out.println("f6(double)"); } void f7(double x) { System.out.println("f7(double)"); } void testConstVal() {System.out.println("Testing with 5");f1(5);f2(5);f3(5);f4(5);f5(5);f6(5);f7(5); }void testChar() {char x = 'x';System.out.println("char argument:");f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);} void testByte() {byte x = 0;System.out.println("byte argument:");f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);} void testShort() {short x = 0;System.out.println("short argument:");f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);}void testInt() {int x = 0;System.out.println("int argument:");f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);} void testLong() {long x = 0;System.out.println("long argument:");f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);} void testFloat() {float x = 0;System.out.println("float argument:");f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);} void testDouble() {double x = 0;System.out.println("double argument:");f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);} public static void main(String[] args) {PrimitiveOverloading p = new PrimitiveOverloading();p.testConstVal();p.testChar();p.testByte();p.testShort();p.testInt();p.testLong();p.testFloat();p.testDouble();}}
結果:
"Testing with 5",
"f1(int)",
"f2(int)",
"f3(int)",
"f4(int)",
"f5(long)",
"f6(float)",
"f7(double)",
"char argument:",
"f1(char)",
"f2(int)",
"f3(int)",
"f4(int)",
"f5(long)",
"f6(float)",
"f7(double)",
"byte argument:",
"f1(byte)",
"f2(byte)",
"f3(short)",
"f4(int)",
"f5(long)",
"f6(float)",
"f7(double)",
"short argument:",
"f1(short)",
"f2(short)",
"f3(short)",
"f4(int)",
"f5(long)",
"f6(float)",
"f7(double)",
"int argument:",
"f1(int)",
"f2(int)",
"f3(int)",
"f4(int)",
"f5(long)",
"f6(float)",
"f7(double)",
"long argument:",
"f1(long)",
"f2(long)",
"f3(long)",
"f4(long)",
"f5(long)",
"f6(float)",
"f7(double)",
float argument:
f1(float)
f2(float)
f3(float)
f4(float)
f5(float)
f6(float)
f7(double)
double argument:
f1(double)
f2(double)
f3(double)
f4(double)
f5(double)
f6(double)
f7(double)
解釋:
一個常數預設為int型
按照大小來自動提升的
float比long大,比double小
八 , this 關鍵字
public class Leaf {int i = 0;Leaf increment() {i++;return this;} void print(){System.out.println("i = " + i);}public static void main(String[] args){Leaf x = new Leaf();x.increment().increment().increment().print(); }}
結果: i = 3;
解釋:
由於increment( )通過this 關鍵字返回了對當前對象的引用,所以很容易在一條語句裡對同
一個對象執行多次操作。
在構造器調用構造器
public class Flower { int petalCount = 0;String s = new String("null");Flower(int petals) {petalCount = petals;System.out.println("Constructor w/ int arg only, petalCount= " + petalCount);} Flower(String ss) {System.out.println("Constructor w/String arg only, s=" + ss);s = ss;}Flower(String s, int petals) {this(petals);//! this(s); // Can't call two!this.s = s; // Another use of "this"System.out.println("String & int args");}Flower(){this("hi", 47);System.out.println("default constructor(no args)");}void print() {//! this(11); // Not inside non-constructor!System.out.println("petalCount = " + petalCount + " s = "+ s);}public static void main(String[] arg){Flower x = new Flower();x.print();}}結果:
"Constructor w/ int arg only, petalCount= 47",
"String & int args",
"default constructor (no args)",
"petalCount = 47 s = hi"
解釋: 構造器可以用this關鍵字調用 區別super(繼承調用父類構造器)
九: 清除:終結與回收
1. 對象可能不被回收。
2. 記憶體回收並不等於“析構”。
3. 記憶體回收只與記憶體有關。
所以finalize()不能作為通用的清除方法。
**之所以要有finalize( ),是由於你可能在分配記憶體時,
採用了類似C語言中的做法而非Java中的通常做法。
class Book { boolean checkedOut = false; Book(boolean checkOut) { checkedOut = checkOut; } void checkIn() {checkedOut = false;} public void finalize(){if(checkedOut)System.out.println("Error: checked out");}} public class TerminationCondition{ public static void main(String[] args){ Book novel = new Book(true); // Proper cleanup: novel.checkIn(); // Drop the reference, forget to clean up: new Book(true);// Force garbage collection & finalization: System.gc();}}
結果:Error: checked out
解釋:系統強制清除記憶體中的對象
附加:記憶體回收行程如何工作的
在某些JAVA 虛擬機器中,堆的實現截然
不同:它更象一個傳送帶,你每分配一個新對象,它就往前移動一格。這意味著Object Storage Service空
間的分配速度非常快。Java 的“堆積指標”只是簡單地移動到尚未分配的地區,其效率比得上C++在堆棧上分配空間的效率。
十,初始化
public class InitialValues {boolean t;char c;byte b;short s;int i;long l;float f;double d;void print(String s) { System.out.println(s);}void printInitialValues(){print("Data type Initial value");print("boolean " + t);print("char [" + c + "]");print("byte " + b);print("short " + s);print("int " + i);print("long " + l);print("float " + f);print("double " + d);}public static void main(String[] args){InitialValues iv = new InitialValues();iv.printInitialValues();}}
結果:
Data type Initial value",
"boolean false",
"char [" + (char)0 + "]", //dos下顯示a 本人jdk 1.6驗證
"byte 0",
"short 0",
"int 0",
"long 0",
"float 0.0",
"double 0.0"
10.1初始化順序:
在類的內部,變數定義的先後順序決定了初始化的順序。即使變數定義散佈於方法定義之間,它們仍舊會在任何方法(包括構造器)被調用之前得到初始化。如下;
class Tag {Tag(int marker) {System.out.println("Tag(" + marker + ")");}}class Card{ Tag t1 = new Tag(1); // Before constructor static { System.out.println("static .."); } Card(){// Indicate we're in the constructor: System.out.println("Card()"); t3 = new Tag(33); // Reinitialize t3}Tag t2 = new Tag(2); // After constructorvoid f(){System.out.println("f()");}Tag t3 = new Tag(3); // At end}public class OrderOfInitialization {public static void main(String[] args) {Card t = new Card();t.f(); // Shows that construction is done}}
結果:
static..
"Tag(1)",
"Tag(2)",
"Tag(3)",
"Card()",
"Tag(33)",
"f()"
解釋:靜態塊(靜態繫結)先於變數定義,
變數定義先於方法(如構造器)(動態綁定)初始化。
10.2靜態執行個體初始化
class Cup {Cup(int marker) {System.out.println("Cup(" + marker + ")");}void f(int marker) {System.out.println("f(" + marker + ")");}}class Cups {static Cup c1;static Cup c2; static{c1 = new Cup(1);System.out.println("inside static");c2 = new Cup(2);}Cup c3 = new Cup(3);Cups(){System.out.println("Cups()");}}public class ExplicitStatic {public static void main(String[] args) {System.out.println("Inside main()");Cups.c1.f(99); Cups.c2.f(100);new Cups();}}
結果:
Inside main()
Cup(1)
inside static
Cup(2)
f(99)
f(100)
Cup(3)
Cups();
解釋:
靜態變數只初始化一次
資料成員初始化在建構函式前 。
10.3 非靜態執行個體初始化
class Mug {Mug(int marker) {System.out.println("Mug(" + marker + ")");}void f(int marker) {System.out.println("f(" + marker + ")");}} public class Mugs {Mug c1;Mug c2;{c1 = new Mug(1);c2 = new Mug(2);System.out.println("c1 & c2 initialized");}Mugs(){System.out.println("Mugs()");}public static void main(String[] args) {System.out.println("Inside main()");Mugs x = new Mugs();}}
結果:
"Inside main()",
"Mug(1)",
"Mug(2)",
"c1 & c2 initialized",
"Mugs()"
解釋: 看起來它與靜態初始化子句一模一樣,只不過少了static 關鍵字。這種文法對於支援“匿名”內部類的初始化是必須的。
多謝瀏覽 ,敬請斧正!