| 
| SCJP 5.0 (CX-310-055) (details) - Prerequisites: NoneThe Sun Certified Programmer for Java 2 Platform 5.0 certification exam is for programmers experienced using the Java programming language. Achieving this certification provides clear evidence that a programmer understands the basic syntax and structure of the Java programming language and can create Java technology applications that run on server and desktop systems using J2SE 5.0.
 - Exam type: Choice + drag & drop
 - Pass score: 59% (43of72 ques.)
 - Time limit: 175 minutes
 เอกสารประกอบการเตรียมสอบ
 * เอกสารเตรียมสอบ 1.4 + ใบเซ็นชื่อเข้าติว
 * PDF: 310-055 Demo (180Q&A?)
 * PDF: Introduction to JAVA #1 2 3
 * แนวข้อสอบ (Objectives) (CX-310-055)
 + API Docs ของ Sun
 + Java Glossary
 + ตัวอย่างข้อสอบ
 + Joshua Bloch & Neal Gafter (PDF)
 + Incheon Paik (PDF)
 + IBM Education (Video)
 + Fred Swartz's Java
 + Andrea Tartaro's Java
 + Top 10 Tips for Java's OO char.
 + กระทู้น่าอ่านเกี่ยวกับ testking
 ? กระดาษคำตอบ 74 ข้อ
 |  | ระยะทางหมื่นลี้ เริ่มที่ก้าวแรก ถ้าพบอะไรผิดพลาด .. ช่วยชี้แนะด้วย
 อยากให้ที่นี่เป็นก้าวแรกที่ดีสำหรับคุณ .. รวมทั้งตัวผมในการเตรียมสอบ SCJP 5.0
 | 
คำแนะนำ
- 
 การเตรียมตัวสอบ ควรมีตัวอย่างข้อสอบ พร้อมเฉลยที่สมบูรณ์ และน่าเชื่อถือ อย่างน้อย 150 ข้อ 
ต้องฝึกทำตามตัวอย่าง และจำเฉลยจากตัวอย่างเหล่านั้นให้ได้
 การเข้า course ติวสอบ Certification
จะช่วยให้สอบผ่านได้ค่อนข้างแน่นอน และประหยัดเวลาไปศึกษาด้วยตนเอง
อย่างมหาศาล แต่ที่สำคัญหลังเข้า course แล้วควรกลับไปอ่านทบทวน
และทดสอบกับเครื่อง เพราะข้อสอบอาจไม่เป็นไปดังคาด แต่ถ้าความเข้าใจชัดเจน ก็จะพบปัญหาน้อยลง
 ? กรณีผม : สอบ 10Aug Cert ถึงบ้าน 24Aug
+ ใบ้ให้ว่า .. testking ช่วยได้เยอะ .. มากมาก + Free SCJP Mock Exams + ลองทำแบบ Online 60 Questions ปรับปรุง : 2550-08-10
 | เอกสารเตรียมสอบจาวา .. มีเพื่อขาย+ Whizlabs.com : ลองดู 310-055 ($44.95) ($69.99)
 + Testking.com  : Click 310-055 Questions & Answers have 180 Q&A
 With the complete collection of 180 questions and answers Testking has assembled to take you through your 310-055 Exam preparation, you will cover every field and category helping to ready you for your successful Sun Certification. Each Q & A set will test your existing knowledge of Sun fundamentals, and is complemented by our Testing Engine. 
 + UCertify.com : ลองดู 310-055 ($49.99)
 | 
 
 แนะนำเว็บ (Web Guides)
 JavaTM 2 Platform Standard Edition 5.0 API Specification
 ตัวอย่างข้อสอบ SCJP 5.0 : javabeat.net
 อ่านจาก http://java.sun.com/j2se/1.5.0/docs/api/
 + http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Thread.html
 + http://yn1.yonok.ac.th/burin/javadocs/api/java/lang/Thread.html
 + http://cs.fit.edu/man/java/api/java/lang/Thread.html
 + http://www-128.ibm.com/developerworks/java/library/j-forin.html ***
 + http://www.thaiitcertify.com
 |  
| 
1. Declarations, Initialization and Scoping
 Package
 ตัวอย่าง .java ที่กำหนดให้อยู่ใน package ชื่อ v1
package v1;
 public class x { public static void main(String [] args) {}}
ถ้าไม่กำหนด public ให้กับ class จะเรียกได้เฉพาะใน package เดียวกัน
javac -d . x.java จะสร้างห้อง v1 เป็นชื่อ package และส่ง x.class เข้าไปในห้อง v1
javac -d .. x.java จะสร้างห้อง v1 นอกห้องปัจจุบัน 1 ระดับ และเก็บแฟ้ม x.class ในห้องนั้น
คำสั่ง compile package ใน package folder คือ ..\javac x.java จะได้ .class เก็บในห้องที่เก็บ .java
ถ้าเขียน y.java เพื่อเรียกใช้ x.class ใน package ทำได้ 2 วิธี
วิธีที่ 1 คือ v1.x myobj = new v1.x();
 วิธีที่ 2 คือ import v1.*; แล้วใช้ x a = new x();
โดยปกติจะ import java.lang.* เข้ามาอัตโนมัติ จึงเรียกใช้ String, System, Wrapper, Object .. ได้ทันที
การ import package จะไม่นำ sub-package เข้ามาด้วย ต้องทำ 2 รอบ
import java.awt.*; และ import java.awt.event.*;
กำหนด classpath ขณะประมวลผลด้วย java -cp c:\;.;d:\ x
Data Types
byte a = 5; หรือ byte a = 5 + 5; จะไม่ error 
แต่ a = a + 5; จะ compile error : posible loss of precision
Compile error on (Integer)(12.6f) but will ok on (Integer)(int)(12.6f) // 12
Compile ok on Byte a = 5 or Integer a = 5; but error on Double a = 5; ต้องใช้ new Double(5); 
casting กับการหารที่มีเศษ จะปัดเศษทิ้ง เช่น System.out.print(5/3); จะได้ผลเป็น int 1
System.out.print(5/(double)3); ได้ผลเป็น 1.6666666666666667 มีตำแหน่งทศนิยมถึง 16 หลัก
 System.out.print((float)5/3); ได้ผลเป็น 1.6666666 มีตำแหน่งทศนิยมถึง 7 หลัก
 Static Member
static จะถูก load หลัง load class ทันที และมีเพียงค่าเดียวในหน่วยความจำ ไม่ขึ้นกับจำนวน object ที่ถูกสร้าง
static initializer หรือ static block ถูกเรียกมาใช้หลังโหลด static member เข้าสู่หน่วยความจำ
static block กับ System.exit(0) ทำให้ main ไม่ถูกเรียกมาทำงาน
class y {
 static { System.out.println(1);
 System.exit(0); }
 public static void main(String [] args) { System.out.println(2); } // not work
 }
กำหนด System Property ให้ static เรียกใช้ได้ ด้วย java -Dtax=10 caltax
ใน caltax.java เขียนว่า String tax = System.getProperty("tax");
ตัวอย่างการใช้ static import ผลลัพธ์คือ 3.141592653589793
import java.lang.Math;
 class x{
 public static void main(String[] args) { System.out.println(Math.PI);}
 }
 // import static java.lang.Math.*; ok
 import static java.lang.Math.PI;
 class x{ public static void main(String[] args) {
 System.out.println(PI);
 System.out.println(Math.PI);
 // System.out.println(lang.Math.PI); package lang does not exist
 } }
ตัวแปรที่เป็น static instance จะมีเพียงค่าเดียวในการถูกอ้างอิง ทำให้ค่าของ i ต่างกับ j
class y { static int i = 0; int j = 0; }
 class x{
 public static void main(String a[]){
 y y1 = new y(); y1.i++; y1.j++;
 System.out.println("" + y1.i + y1.j); // 11
 y y2 = new y(); y2.i++; y2.j++;
 System.out.println("" + y2.i + y2.j); // 21
 } }
กำหนด import static ให้กับ System.out เพราะ out เป็น members ที่เป็น static
//http://java.sun.com/j2se/1.5.0/docs/api/java/lang/System.html พบว่า out เป็น static
 import static java.lang.System.*; // import static java.lang.System.out; ok
 class x {
 public static void main(String[] args) { out.println(5); }
 }
local variable เป็น static ไม่ได้ เป็นได้เฉพาะ instance หรือ global variable
static int a(){
 // static int b = 1;  // compile error : illegal start of expression
 return 5; }
 Var Args
method ที่กำหนดการรับค่าแบบ Var Args จะรับค่าได้ไม่จำกัด หรือไม่รับก็ได้
กำหนดหลายตัวแปรใน Arguments ได้ แต่ต้องกำหนด Var Args เป็นตัวสุดท้าย และมี ... 3 จุด
method หนึ่งมี Var Args ได้เพียง 1 ตัว เช่น void a(int b, int c, String... d) { }
2. Flow Control
 try {} catch() {} finally {}
finally จะทำงานทุกครั้ง แม้เข้าไปใน catch แต่จะไม่ทำถ้าพบ System.exit(0)
แม้มี return ใน catch หรือ try ก็ยังต้องทำ finally ก่อนอยู่ดี
ถ้าเขียน finally ก็จะต้องเขียนเป็นลำดับสุดท้าย
finally {} หรือ catch() { } ต้องใช้คู่กับ try {}
try {} ต้องคู่กับ finally {} หรือ catch() {} อย่างใดอย่างหนึ่ง
ถ้าจับหลาย Exception ตัว Super ต้องอยู่ล่างสุด มิเช่นนั้น Compile ไม่ผ่าน
Override โยน Exception ในตัว father ต้องแคบ แล้ว child กว้างกว่าได้ เช่นของ child โยน Exception
try ต้องอยู่คู่กับ catch หรือ finally อย่างน้อย 1 ตัว
ตัวอย่างการเกิด Exception ขณะ Runtime
java.lang.ArrayIndexOutOfBounds ถ้า String a[] = new String[2]; System.out.println(a[3]);
 java.lang.NumberFormat ถ้า Integer a = new Integer("a"); System.out.println(a);
 java.lang.ArithmeticException: / by zero ถ้า System.out.println(5/0);
 java.lang.IllegalThreadState ถ้า start() เทรดไปแล้ว สั่ง Start อีกครั้งติดต่อกัน แต่ไม่มีปัญหาเรื่อง run() ซ้ำ
class x { } compile ผ่าน แต่จะพบ Exception in thread "main" java.lang.NoSuchMethodError: main เมื่อ run
เมื่อพบ java.lang.NullPointerException จะส่งกลับทันที ถ้า class ใด catch ไว้ ก็จะแสดงรายงานออกมา (แสดงเฉพาะ error1)
class x3{ public void x3() { String x = null; System.out.println(x.length()); System.out.print("x3");} }
 class x2{ public void x2() { x3 a = new x3(); a.x3(); System.out.print("x2"); } }
 class x1{ public void x1() { x2 a = new x2(); a.x2(); System.out.print("x1"); } }
 class x{
 public static void main(String[] args) {
 try{
 x1 a = new x1();
 a.x1();
 System.out.print("x");
 }catch (Exception e){ System.out.print("error1"); }
 }
 }
ถ้าคิดว่ามี error ใน method ก็ให้ throws Exception ไว้ เพื่อบังคับให้ตัวที่ไปเรียกเขา ต้อง catch exception ไว้ ถ้าไม่ catch จะ compile ไม่ผ่าน
class x3{ public void x3() throws NullPointerException { String x = null; System.out.println(x.length()); System.out.print("x3");} }
 class x2{ public void x2() throws Exception { x3 a = new x3(); a.x3(); System.out.print("x2"); } }
 class x1{ public void x1() throws Exception { x2 a = new x2(); a.x2(); System.out.print("x1"); } }
 class x{
 public static void main(String[] args){
 try{ x1 a = new x1(); a.x1(); }
 catch (NullPointerException e){ System.out.print("error1"); } // บรรทัดนี้ทำงาน
 catch (Exception e){ System.out.print("error2"); }
 }
 }
ถ้าคิดว่ามี error แต่ไม่เกิด ก็จะทำงานตามปกติ ผลลัพธ์คือ x3x2x1
class x3{ public void x3() throws Exception { System.out.print("x3");} }
 class x2{ public void x2() throws Exception { x3 a = new x3(); a.x3(); System.out.print("x2"); } }
 class x1{ public void x1() throws Exception { x2 a = new x2(); a.x2(); System.out.print("x1"); } }
 class x{
 public static void main(String[] args){
 try{ x1 a = new x1(); a.x1(); }
 catch (NullPointerException e){ System.out.print("error1"); }
 catch (Exception e){ System.out.print("error2"); }
 }
 }
การสั่งให้เกิด exception ใน constructor
class x2{ x2() { throw new IllegalArgumentException("test"); } }
 class x1{ public void x1() throws Exception { x2 a = new x2(); } }
 class x{
 public static void main(String[] args){
 try{ x1 a = new x1(); a.x1(); }
 catch (NullPointerException e){ System.out.print("error1"); }
 catch (Exception e){ System.out.print("error2"); } // บรรทัดนี้ทำงาน
 }
 }
 3. API Contents
 String
การใช้ String.format() แปลงแบบของข้อมูล มักมีปัญหาในส่วน runtime exception มิใช่ compile error
System.out.printf("%,.2f",35000.5);
 System.out.format("%,.2f",35000.5);
 System.out.format("%,10.2f",35000.5); // _35,000.50
 System.out.format("%.2f",(double)3);
 // System.out.format("%10,.2f",35000.5); // java.util.UnknownFormatConversionException
 // System.out.format("%.2f",3); // java.util.IllegalFormatConversionException
 // System.out.format("%d",2.1); //java.util.IllegalFormatConversionException
 System.out.print( String.format("%,.2f",35000.5) ); // 35,000.50
ค่าเหมือนกัน แต่ type ไม่เหมือนกัน เทียบกันไม่ได้
String x = null; Integer y = null;
 // System.out.println(x==y); // compile error : incomparable types
 // System.out.println(x.equals(y)); // runtime error : java.lang.NullPointerException
 // System.out.println(x.equals(null)); // runtime error : java.lang.NullPointerException
 String a = "5"; Integer b = new Integer(a);
 System.out.println(a.equals(b)); // false
 System.out.println((new Integer(a)).equals(b)); // true
 // System.out.println(a==b); incomparable type
การเปรียบเทียบวัตถุที่มีค่าเป็น null แสดงค่าจากวัตถุเป็น null ได้ แต่แสดงคำว่า null จะ compile error
String x = null;
 if (x == null) { System.out.println(x); } // null
 if (null == null) { System.out.println(x); } // null
 // System.out.println(x.hashCode()); // runtime error : java.lang.NullPointerException
 // System.out.println(x.equals(null)); // runtime error : java.lang.NullPointerException
 // System.out.println(x.length()); // runtime error : java.lang.NullPointerException
 // System.out.println(null); // Compile error
primitive กับ null ใช้ร่วมกันไม่ได้
//char a = null;  compile error
 //int x = null; compile error
การใช้ charAt กับ String นอกขอบเขต จะพบ StringIndexOutOfBoundsException ใน runtime
String x = "abcd";
 System.out.println(x.charAt(0)); // a
 System.out.println(x.charAt(1)); // b
 // System.out.println(x.charAt(4)); // java.lang.StringIndexOutOfBoundsException
พิมพ์อักษร \n ก็ใช้ \ ตัวเดียว และการปรับรูปแบบการแสดงผลด้วย format
System.out.println("1\n2\n3");
 System.out.format("1\n2\n3\n%2$d%1$.2f",5.2,4); ได้ตัวเลขละบรรทัด 4 บรรทัด (45.20)
 System.out.printf("1\n2\n3\n%d",4); ได้ตัวเลขละบรรทัด 4 บรรทัด
ถ้าใช้ \ ให้ใช้ \\ เช่นการใช้ split มิเช่นนั้น compile ไม่ผ่านถ้าใช้ \s แทน \\s
http://yn1.yonok.ac.th/burin/javadocs/api/java/util/regex/Pattern.html
 String[] y = "a b c d".split("\\s");
 System.out.println(y.length); // 4
Predefined character
| \t The tab character ('\u0009') \n The newline (line feed) character ('\u000A')
 \r The carriage-return character ('\u000D')
 \f The form-feed character ('\u000C')
 \a The alert (bell) character ('\u0007')
 \e The escape character ('\u001B')
 | \d A digit: [0-9] \D A non-digit: [^0-9]
 \s A whitespace character: [ \t\n\x0B\f\r]
 \S A non-whitespace character: [^\s]
 \w A word character: [a-zA-Z_0-9]
 \W A non-word character: [^\w]
 |  super & this
constructor ต้องไม่เป็น private ถ้ามีการเรียกผ่าน subclass เพราะจะ compile error
การใช้ constructor จะสร้าง super() บรรทัดแรกของ constructor อัตโนมัติ ทำให้เรียก constructor ของ super ก่อน
class y{ public y(){ System.out.println("y"); } }
 class x extends y {
 static public void main(String[] args) { new x(); } // y
 }
ถ้า super มี constructor ที่มี argument แต่ไม่มี default constructor ทำให้ subclass compile error เพราะเรียกหา default constructor ไม่พบ
this() หรือ super() ต้องอยู่ใน constructor ที่ถูก overload ได้ และต้องเป็นบรรทัดแรก และต้องไม่อยู่คู่กัน 2 ตัว
ถ้าเรียกใช้ super ที่ถูก overload แล้ว super() ก็จะไม่ทำงาน
class y{
 public y(){ System.out.print("y"); }
 public y(int a){ System.out.print(a); }
 }
 class x extends y {
 x(){ this(6); System.out.print("x"); }
 x(int a){ super(7); System.out.print(a); }
 static public void main(String[] args) {
 new x(); new x(); new y(9);
 } // 76x 76x 9
 }
ถ้าไม่มี super() หรือ this() ใน constructor ใดก็ตาม จะมีการเพิ่ม super() ให้อัตโนมัติ
class y{ public y(){ System.out.print("y"); } }
 class x extends y {
 x(){ this(6); System.out.print("x"); }
 x(int a){ System.out.print(a); }
 static public void main(String[] args) { new x(); }
 } // y 6 x
การเรียกใช้ this. และ super. ใน constructor ไม่จำเป็นต้องอยู่ในบรรทัดแรก และใช้ทั้งคู่พร้อมกันได้
class father { static int x = 5; }
 class y extends father{
 static int x = 6;
 y() {
 super(); // ผลการเรียก constructor ในบรรทัดนี้ไม่ส่งผลใด ๆ
 System.out.println(super.x); // 5
 System.out.println(this.x); // 6
 }
 public static void main(String [] args) { new y(); }
 }
การเรียกใช้ this. และ super. นอก constructor ต้องคำนึงเรื่อง static ให้มาก
class y { int a = 6; }
 class x extends y {
 int a = 5;
 int b(){ return this.a + super.a; };
 void c() { System.out.println(b()); }
 static public void main(String[] args) { new x().c(); } // 11
 }
การใช้ this กับ encapsulation
class y{
 private int a;
 private String b;
 y(int a,String b){ this.a = a; this.b = b;}
 int id(){ return this.a;}
 String name(){ return this.b;}
 }
 public class x{
 int c = 2000;
 int salary(){ return this.c; }
 public static void main(String[] args) throws Exception{
 y o = new y(101,"thaiall");
 System.out.println(o.id() + o.name() + (new x().salary()));
 } }
 4. Concurrency
 
 thread
wait()/notify()/notifyAll(): ต้องถูกเรียกจากใน synchronized context
notify(): ปลุกให้เทรดเดียวที่คอยวัตถุอยู่ตื่น
notifyAll(): ปลุกให้ทุกเทรดที่คอยวัตถุอยู่ตื่น
yield(): ทำให้เทรดปัจจุบันหยุดชั่วคราว และอนุญาตให้เทรดอื่นประมวลผล ถ้าไม่มีตัวเองก็จะทำงานต่อตามปกติ
wait(): บอกให้เทรดหยุดรอจนกว่าจะมีเทรดอื่นมาปลุกด้วย notify() หรือ notifyAll() ในอีกเทรดหนึ่ง
wait(long timeout): บอกให้เทรดหยุดรอจนกว่าจะมีเทรดอื่นมาปลุก หรือครบตามเวลา 
sleep(): หลับอย่างน้อยเท่าช่วงเวลาหนึ่งที่กำหนด (least the time specified in the argument)
join(): เทรดหนึ่งเข้าขัดบอกว่าขอทำก่อน และให้รอจนกว่าตนจะทำเสร็จ 
interrupt(): ขัดจังหวะไม่ให้ thread ทำงานต่อ คล้าย stop() suspend()
sleep() ต้องส่ง milisecond เข้าไปมิเช่นนั้น compile error ต้องมี exception จับ หรือ throws ระดับ method
wait() หรือ notify() หรือ join() ต้องมี exception จับ มิเช่นนั้น compile error
yield() หรือ interrupt() ไม่ต้องมี exception จับก็ได้
ถ้า start() ถ้าสั่ง process ใน run() อาจไม่ประมวลผลในทันที
ถ้า run() เทรดจะทำงานจนจบ ไม่เหมือน start() ที่ทำให้เทรดทำงานหลายเทรดพร้อมกันได้
Runner r = new Runner(); // และมี run() ใน Runner Class ที่ implements Runnable
 Thread t1 = new Thread(r); t1.start();
 Thread t2 = new Thread(r); t2.start();
 Thread t3 = new Thread(r); t3.start();
ถ้า start() เทรดเดิมซ้ำ จะพบ java.lang.IllegalThreadStateException และยังคงมีเพียง Thread เดียวที่ประมวลผล
การใช้ Thread.sleep() ต้องใช้ throw exception อาจใช้ตอนประกาศ method หรือใน method ก็ได้
การ catch ต้องจับให้ตรง ถ้าใช้ sleep แล้วไปจับ IOException จะ compile ไม่ผ่าน
เช่น try{ Thread.sleep(1000); } catch(Exception e) { }
 เช่น try{ Thread.sleep(1000); } catch(InterruptedException e) { }
การสั่งให้ Thread ประมวลผลผ่าน runnable และหยุดการทำงานเมื่อพบ interrupt()
class Runner implements Runnable {
 public void run(){
 byte b=0;
 try{ while(true) { System.out.print(b++); Thread.sleep(100); } }
 catch(Exception e){}
 }
 }
 class x{
 public static void main(String[] args) {
 Runner r = new Runner();
 Thread t = new Thread(r);
 t.start();
 try{ Thread.sleep(1000); }catch(Exception e){}
 // ก่อนเข้า interrupt Thread จะหยุดที่นี่ เมื่อพิมพ์เลข 10 ตัวแล้ว
 // 0123456789 แล้วเลิกการทำงาน
 t.interrupt();
 }
 }
การสั่งให้ Thread ประมวลผลผ่าน Thread โดยตรง
class x extends Thread{
 public void run(){ while(true) System.out.print("."); }
 public static void main(String[] args) {
 x t = new x();
 t.start();
 }
 }
การสั่งให้ Thread ประมวลผลผ่าน Runnable แบบ Anonymous Inner Class
class x{
 public static void main(String[] args) {
 x.go();
 //new x().go(); this line ok
 }
 static void go(){
 Runnable r = new Runnable() {
 public void run(){ while(true) System.out.print("."); }
 };
 Thread t = new Thread(r);
 t.start();
 }
 }
การสั่งให้ Thread ประมวลผลผ่าน Thread แบบ Anonymous Inner Class
class x{
 public static void main(String[] args) {
 new Thread() {
 public void run(){ while(true) System.out.print("."); }
 }.start();
 }
 }
ถ้าสั่ง start() แล้วสั่งพิมพ์ข้อความ โดยปกติพิมพ์ข้อความจะถูกกระทำก่อนการทำงานใน run()
แสดงการใช้ join ขัดจังหวะขอทำก่อนอย่างชัดเจน
class Runner implements Runnable {
 public void run(){System.out.print("x");}
 }
 class x{
 public static void main(String[] args) throws Exception {
 Thread t = new Thread(new Runner());
 t.start();
 System.out.print("1");System.out.print("2");System.out.print("3");
 t.join(); // thread ขอทำก่อน จึงพิมพ์ x ก่อน 4 แน่ แต่อาจพิพม์ x ก่อนหรือหลัง 3 ก็ได้
 System.out.print("4");System.out.print("5");System.out.print("6");
 }
 }
 5. OO Concepts
 Overload & Override
แสดงการ Overload และ Override ทั้ง method และ variable ที่เป็น static
class y {
 static int a=5;
 static int b(){ return 0;} }
 class x extends y{
 static int a=6;
 // private static int b(){ return 1;} // can not assign weaker access privileges
 public static int b(){ return 1;} // override
 static int b(int a){ return a;} // overload
 protected static int b(int a, int b){ return a + b;} // overload
 // static String b(int a){ return "a";} // ผิดกฎ overload เพราะมี b(int a) แล้ว
 public static void main(String[] args) {
 System.out.println(b() + b(2) + b(3,4) + a); // 16
 } }
ความสัมพันธ์ของ Override ที่กว้างกว่าด้วยลูก เช่น ประกาศพ่อแล้ว return ลูกได้
class father { } // hide
 class child extends father { } //hide
 class boy { father money(){ return new father();} }
 class x extends boy {
 child money(){ return new child();}
 father money2(){ return new child();}
 }
 Polymorphism
Overriding + Polymorphism จะเรียกว่า Virtual Method Invocation ซึ่งมีช่วง Compile Time และ Run time (Dynamic Binding)
class father { public int work() { return 1; } }
 class child extends father { public int work() { return 2; } }
 father x = new child();
 System.out.println(x.work()); // 2 แต่ตอน compile เช็คจาก father
Overriding + Polymorphism + variable จะมาจากแม่อย่างเดียว ไม่มาจากลูก
class father { int a=1; }
 class child extends father { int a=2; }
 father xx = new child();
 System.out.println(xx.a); // 1
กำหนดรับ Argument เป็น super จะรับของ subclass ได้เช่นกัน
class father { int a(){return 1;} }
 class child extends father { int a(){return 2;} }
 xx(new father());
 xx(new child());
 static void xx (father f){ System.out.print(f.a()); } // 1 2
 Interface
ใน interface มีได้เฉพาะ abstract method ที่เป็นแบบ public หรือ default เท่านั้น
interface กำหนดค่าให้กับ instance variable ได้
interface สามารถ extends interface ได้พร้อมกันหลาย interface
interface สามารถถูก implements จาก class ได้พร้อมกันหลาย interface
interface ไม่สามารถมี constructor หรือสร้าง object 
ถ้า class มี extends และ implements ต้องทำการ extends ก่อน
6. Collections /Generics
 Generic (type safe)
Generic ตรวจ Type Safe ในส่วนของ Compile ไม่ทำงานในส่วนของ Runtime
ถ้า define หรือ new object มี <Object> กำหนดไม่ครบคู่ จะเป็น warning compile
เช่น  Set<Object> vals = new TreeSet<Object> ();
When we use wildcard(?) to catch the collection , then modifications(add) are not allowed in that collection
Can not compiled : Basket <?> b = new Basket <Apple>(); เพราะใช้ Wildcard ที่นี่ไม่ได้
warning Compile เพราะไม่แน่ใจว่าส่ง Apple เข้าไปแล้ว จะไม่มีปัญหา
Basket b = new Basket();
 b.addbasket(new Apple());
Generic เป็น object เมื่อส่งค่าให้ method จึงส่งตำแหน่งของ Object ทำให้อ้างอิงถึง Object ที่ตำแหน่งเดิม
import java.util.*;
 class x {
 public static void main(String [] args) {
 List<Object> samples = new ArrayList<Object>();
 samples.add(new Integer("1"));
 int y = 5;
 addList(samples,y);
 System.out.print(samples +""+ y); // 1 2 5
 }
 static void addList(List <Object> o, int n) {
 n = 6;
 o.add(new Integer("2"));
 }
 }
method เมื่อรับ สามารถรับได้หลายแบบด้วย ? wildcard
import java.util.*;
 class x {
 public static void main(String [] args) {
 List<Integer> l = new ArrayList<Integer>();
 l.add(new Integer("1"));
 l.add(new Integer("2"));
 prtList(l);
 }
 // ok static void prtList(List<? extends Object> o) {
 // ok static void prtList(List<? extends Integer> o) {
 // ok static void prtList(List<? super Integer> o) {
 // error static void prtList(List<? super Object> o) {
 // error static void prtList(List<Object> o) {
 static void prtList(List<Integer> o) { for(Object x:o)System.out.print(x); }
 }
Generic ชี้ไป Generic ที่ type ต่างกันไม่ได้จะเกิด incompatible types เมื่อ Compile
HashSet<String> hs1 = new HashSet<String>();
 hs1.add("test");
 HashSet hs2 = hs1; // no problem
 // HashSet<Object> hs3 = hs1; compile error
ถ้าไม่ใช้ Generic จะพบ Compile warning 
ArrayList<String> l = new ArrayList<String>();
 l.add("123");
 for(Iterator i = l.iterator();i.hasNext();){ System.out.println(i.next()); }
 Collection
List : sorted, can same (ArrayList, LinkedList, Vector:Thread-Safe)
Set : unsorted, not same (HashSet, LinkedHashSet, TreeSet)
Map : key sorted, key not same (HashMap, HashTable:Thread-Safe, LinkedHashMap, TreeMap)
Collection ที่ควรรู้จักมี 10 Classes
List: ArrayList: Fast iteration and fast random access
 List: Vector: Like a somewhat slower ArrayList, mainly due to its synchronized methods
 List: LinkedList: Good for adding elements to the ends, i.e., stacks and queues
 Set: HashSet: Assures no duplicates, provides no ordering
 Set: LinkedHashSet: No duplicates; iterates by insertion order or last accessed (new with 1.4)
 Set: TreeSet: No duplicates; iterates in natural sorted order
 Map: HashMap: Fastest updates (key/value pairs); allows one null key, many null values
 Map: HashTable: Like a slower HashMap (as with Vector, due to its synchronized methods). No null values or null keys allowed
 Map: LinkedHashMap: Faster iterations; iterates by insertion order or last accessed, allows one null key, many null values (new with 1.4)
 Map: TreeMap: A sorted map, in natural order
การสร้าง และใช้ ArrayList ถ้า add จะพบ warning compile : unchecked or unsafe operations.
ถ้าไม่ add จะไม่พบ error และถ้าเติม Generic Object จะรับแบบใดก็ได้
 ArrayList a = new ArrayList();
 a.add("a");
 a.add(new String("a"));
ต้องกำหนดทั้ง ประกาศ และสร้างวัตถุ จึงจะไม่มี warning
ArrayList<Object> a = new ArrayList<Object>();
 a.add(new String("aa"));
 a.add("bb");
 for(Object o:a) System.out.println(o.toString()); // aa bb
Generic ของ Collection ต้องมี type แบบเดียวกัน ยกเว้นไม่กำหนด type
ArrayList<Object> a = new ArrayList<Object>();
 ArrayList<String> b = a; // compile error : incompatible types
 ArrayList<String> c = new ArrayList<String>();
 ArrayList<Object> d = c; // compile error : incompatible types
 ArrayList<String> e = new ArrayList<String>();
 ArrayList<?> f = e;
 ArrayList<? extends String> g = e;
 ArrayList h = e;
 // ArrayList<? extends Integer> r = e; // compile error : incompatible types
 e.add("abc");
 System.out.println(g.get(0)); // abc
 ArrayList h = e;
HashSet เป็นแม่ของ LinkedHashSet
HashSet x = new LinkedHashSet(); x.add(new String("def")); x.add(new String("abc"));
 System.out.println(x); // [def, abc]
Set เป็นแม่ของ TreeSet และจัดเรียงอัตโนมัติ
Set x = new TreeSet(); x.add(new String("def")); x.add(new String("abc"));
 System.out.println(x); // [abc, def]
 enum
ถ้ากำหนด enum นอก class จะกำหนด modifier ไม่ได้
มี constructor ใน enum ได้ แต่มี modifier หน้า enum ที่เป็น constructor ไม่ได้
enum นอก class กำหนด static ไม่ได้ แต่ใน class สามารถมี static หรือ public ได้
การเขียน enum นอก class เมื่อ compile จะได้ .class สำหรับ enum ชื่อ enum จึงซ้ำชื่อ class ไม่ได้
enum y{a,b,c}
 class x {
 static{
 System.out.println(y.a); // a
 System.exit(0);
 }}
enum กำหนดนอก class หรือใน class หรือเป็น inner class ได้ แต่กำหนดใน method ไม่ได้
class Outer {
 static enum OuterEnum { OUT, OUTTER; }
 static class Inner { enum InnerEnum { IN, INNER;} }
 }
enum กับเครื่องหมาย ; If an enum declares only values in it, then semi-colon is optional. If an enum declares anyother thing with values then semi-colon at the end of declared values is mandatory (ผู้ได้รับมอบอำนาจ).
ค่าที่เป็นไปได้ใน switch ต้องเป็นค่าตาม enum มิเช่นนั้นจะเกิด unqualified enumeration constant name เมื่อ compile
enum a{a,b,c} ไว้นอก class
 a b= a.a;
 switch(b){ case d:; }
enum + constructor + toString เพราะ enum ใน Class ก็เสมือน inner class จะได้ x$Shape.class
public class x {
 enum Shape { CIRCLE("zero"), RECTANGLE("four") ,SQUARE("four") ,TRIANGLE("three");
 String sides;
 private Shape(String s) { sides = s; }
 public String toString() { return sides; }
 }
 public static void main(String[] args) { System.out.println(Shape.RECTANGLE); } // four
 }
 I/O
ชุด 1 : FileReader, BufferedReader, .readLine
ชุด 2 : FileWriter, BufferedWriter, .write, .close
ชุด 3 : FileInputStream, ObjectInputStream, .readObject
ชุด 4 : FileOutputStream, ObjectOuputStream, .writeObject, .close
ถ้าไม่ import java.io.* ก็ต้องกำหนดเต็มหน้า Class เช่น IOException FileBuffer BufferedReader
ใช้ Exception แทน IOException ได้ แต่ใช้ java.io.Exception ไมได้เพราะ Exception อยู่ใน java.lang
การใช้ FileReader อ่านแฟ้ม
import java.io.*;
 class x {
 public static void main(String[] args) throws IOException{
 FileReader f = new FileReader("x.java");
 BufferedReader b = new BufferedReader(f);
 String r = null;
 while ((r=b.readLine()) != null){ System.out.print(r); }
 }
 }
การใช้ FileWriter เขียนลงแฟ้ม
class x {
 public static void main(String[] args) throws java.io.IOException{
 java.io.FileWriter f = new java.io.FileWriter("xx.java");
 java.io.BufferedWriter b = new java.io.BufferedWriter(f);
 b.write("aa"+"\n"); b.write("aa"+"\n");
 b.close();
 }}
การใช้ Scanner ต้อง import java.util.*;
ถ้าไม่กำหนด s.useDelimiter(","); จะมองหา Space เช่น "a b c d"
String m = "a b c d";
 Scanner s = new Scanner(m);
 s.useDelimiter(",");
 while(s.hasNext()) System.out.println(s.next());
instance ที่เขียนลง Storage ต้องกำหนดเป็น Serializable โดย Class ต้อง implements Serializable 
primitive เป็น Serializable โดยอัตโนมัติ
Object ที่ไม่สามารถกำหนดเป็น Serializable เช่น Thread, InputStream ให้เติม transient หน้าแบบของ Object
private transient Thread t;
primitive หรือ Object ใดที่กำหนด transient หมายถึงไม่เขียนลง Storage
เขียนข้อมูลแบบ FileOutputStream + ObjectOutputStream 
import java.io.*;
 public class x{
 public static void main(String[] args) throws Exception{
 FileOutputStream fo = new FileOutputStream("f.txt");
 ObjectOutputStream out = new ObjectOutputStream(fo);
 out.writeObject(101);
 out.writeObject("boy");
 }
 }
อ่านข้อมูลแบบ FileInputStream + ObjectInputStream 
FileInputStream fi = new FileInputStream("f.txt");
 ObjectInputStream in = new ObjectInputStream(fi);
 System.out.println(in.readObject()); // 101
 System.out.println(in.readObject()); // tom
สร้าง Class y ที่เป็น Serializable จึงจะ Writeobject แบบ y ลงไปได้
import java.io.*;
 class y implements Serializable{
 private int a;
 private String b;
 y(int a,String b){ this.a = a; this.b = b;}
 int getid(){ return this.a;}
 String getname(){ return this.b;}
 }
 public class x{
 public static void main(String[] args) throws Exception{
 FileOutputStream fo = new FileOutputStream("f.txt");
 ObjectOutputStream out = new ObjectOutputStream(fo);
 y o = new y(103,"burin");
 out.writeObject(o);
 }
 }
สร้าง Class y ที่เป็น Serializable ต้องตรงกับที่ Writeobject มิเช่นนั้น readObject ไม่เข้า
import java.io.*;
 class y implements Serializable{
 private int a;
 private String b;
 y(int a,String b){ this.a = a; this.b = b;}
 int getid(){ return this.a;}
 String getname(){ return this.b;}
 }
 public class x{
 public static void main(String[] args) throws Exception{
 FileInputStream fi = new FileInputStream("f.txt");
 ObjectInputStream in = new ObjectInputStream(fi);
 Object o = in.readObject();
 y ox = (y)o;
 System.out.println(ox.getid());
 System.out.println(ox.getname());
 } }
ถ้า father ไม่เป็น Serializable จะถูก catch ไว้ แม่ไม่ใช้ใน writeObject ก็ตาม
import java.io.*;
 class father implements Serializable{}
 public class child implements Serializable{
 private father y = new father();
 public static void main(String[] args) {
 child o = new child();
 try{
 FileOutputStream fo = new FileOutputStream("f.txt");
 ObjectOutputStream out = new ObjectOutputStream(fo);
 out.writeObject(o);
 out.close();
 }catch(Exception e){e.printStackTrace();}
 } }
 7. Fundamentals
 fundamental
สร้าง class ชื่อ x และมี inner class ชื่อ y จะได้ x.class และ x$y.class
class x { class xxx{ } }
ทั้ง static และ public ต่างเป็น modifier 2 ตัวนี้สลับที่ได้
static public void a(){	}
Boxing คือแปลง Primitive เป็น Object เช่น int x = 5; Integer y = new Integer(x);
Unboxing คือแปลง Object เป็น Primitive เช่น Integer x = new Integer("5"); int y = x.intValue();
Autoboxing คือแปลง Primitive เป็น Object เช่น int x = 5; Integer y = x;
Autounboxing คือแปลง Object เป็น Primitive เช่น Integer x = new Integer("5"); int y = x;
ใช้ Integer แปลง String เป็นตัวเลข และ Autounboxing
String x = "5";
 System.out.println((new Integer(x)) + 5 + Integer.valueOf(x) + x); // 155
ถ้าข้อมูลไม่เกินขอบเขตก็จะทำ Autoboxing ให้อย่างถูกต้อง
byte b = 10;
 b = 10; // b = 128; possible loss of precision
 b = 10 + 10; // Autoboxing
 System.out.println(b); // 20
 // b = b + 10; or b = 10 + b; possible loss of precision
Command line ที่ใช้ได้
javac -source 1.5 x.java หรือ javac -cp c:\ x.java
 javac -d c:\ x.java กำหนดตำแหน่งแฟ้ม .class
 javac -s c:\ x.java กำหนดตำแหน่งแฟ้ม .java
 java -esa x หรือ java -enablesystemassertions x
 java -dsa x หรือ java -disablesystemassertions x
 java -ea x หรือ java -enableassertions x
 java -da x หรือ java -disableassertions x
 java -Dtax=10 caltax
assert จะทำงานเมื่อเป็นเท็จ หยุดการทำงานทันที และรายงาน java.lang.AssertionError: break here
assert(false):"break here";
 System.out.println("test");
การส่งค่าของ boolean
boolean a = false;
 if (a = true) System.out.println(1);
 if (a) System.out.println(2);
 if (a == true) System.out.println(3);
 if (a == false) System.out.println(4);
 System.out.println(5); // 1 2 3 5
การใช้ equals และ hashCode แบบไม่ทำ Override
String x = new String("abc");
 String y = new String("abc");
 System.out.println(x.equals(y)); // true
 System.out.println(x==y); // false
 System.out.println(x.hashCode()); // 96354
 System.out.println(y.hashCode()); // 96354
ใช้ .equals กับ null ไม่ได้ เกิด exception
Object x = null;
 System.out.println(x==null); // true
 // System.out.println(x.equals(null)); // java.lang.NullPointerException
การส่งค่าให้ primitive เป็น null จะไม่ทำ Autoboxing แต่ถ้าตัวรับเป็น Object จะไม่พบปัญหา
public static void main(String[] args) {
 Integer i = null; // เกิด Autoboxing แต่ยังเป็น null
 method(i); // i ยังเป็น null ทำให้เกิด java.lang.NullPointerException ที่บรรทัดนี้
 }
 static void method(int k){ System.out.println(k);  }
เมื่อ overload จะเลือกทำตาม primitive ก่อน
public static void main(String[] args) {
 byte b = 10;
 method(b); // Primitive Type
 method(new Byte(b)); // Primitive Type by Promotion
 method(new Short(b)); // Primitive Type by Promotion
 method(new Integer(b)); // Wrapper Class
 // method(new Long(b)); Compile error
 // method(new Byte(10)); Compiler error
 }
 static void method(Integer i){ System.out.println("Wrapper Class"); }
 static void method(int i){ System.out.println("Primitive Type"); }
Local Object ต้องประกาศค่า เช่น Integer i = null; จึงจะ compile ผ่าน และพิมพ์ได้ 
Local Object หรือ primitive ที่ไม่ประกาศค่า เช่น Integer i; หรือ int j; จะ compile ผ่านถ้าไม่เรียกใช้ และ run ได้ปกติ
Local Object ที่ประกาศค่าเป็น null จะ compile ผ่าน แต่ใช้ .equals หรือ .hashCode จะพบ  java.lang.NullPointerException
continue เพื่อไม่ทำต่อส่วนที่เหลือ ถ้าไม่อยู่ท้าย block ของ for หรือ while จะ compile error แต่ถ้าอยู่ใน if ไม่เป็นไร
for(int i=0;i<=5;i++){
 System.out.println(i);
 if (true) continue;
 System.out.println("a");
 }
break จะหยุดทำงาน แล้วออกนอก block ใช้ได้กับ case, while, for แต่ถ้าอยู่ต้น block ทันที ต้องมี if คลุม
 |  | SCJP 1.5
 Object Oriented Programming
- constructor เรียกชื่อกันเองไม่ได้ ถ้าเรียกต้องใช้ this(); หรือ this(5); 
- this() หรือ super() ต้องอยู่ในบรรทัดแรกของ Constructor
- เป้าหมายของ encapsulation คือการซ่อน implement หลัง interface เช่น getter setter
Overload & Override
- constructor สามารถถูก overload แต่ไม่สามารถถูก override
- abstract method ต้องถูก override เมื่อถูกเรียกใน sub class ที่ไม่ใช่ abstract ครั้งแรก
- เมื่อ extends abstract class ใน abstract class ไม่จำเป็นต้อง override method ที่เป็น abstract 
- ถ้ามี method เป็น abstract ตัว class ต้องเป็น abstract ด้วย
 interface
- ใช้ implements เรียกจาก class แต่ extends ระหว่าง implements ได้
- สร้าง method ที่มี body ใน interface ไม่ได้ แต่สร้าง instance variable ได้
- implements หลาย interface กั้นด้วย , ได้ หรือ extends หลาย interface ก็ได้
- Variable ในหลาย interface ซ้ำกันไม่ได้
interface a1{ static int a=1; }
interface a2{ static int b=2; }
interface a3 extends a1,a2 { 
static int c=3;
}
interface a4{ static int d=4; }
class a5 { static int e=5; }
class child extends a5 implements a3,a4 { 
static{
  System.out.println(a + b + c + d + e); // 15
  System.exit(0);
}
}
 // casting
class x {
public static void main(String[] args) {
  System.out.println(xx(9));
}
static double xx(int xxx){
  return xxx/2.0; 
  // ถ้าเป็น /2 จะได้ผลลัพธ์เป็น 4
  // return (double) xxx/2; หรือ return xxx / (double) 2; จะได้ 4.5
}
}
 // Variable Arguments (VarArgs)
class x {
void print(int a,int b,String... c){
  a += b;
  for(String d : c) a+=Integer.parseInt(d);
  System.out.print(a); // 10
}
public static void main(String[] args) {
  x y = new x();
  y.print(1,2,"3","4");
}
}
 // VarArgs + Overloading
class x {
void print(int... a){System.out.print(1);}
void print(int a){System.out.print(2);}
void print(int a,int b){System.out.print(3);}
public static void main(String[] args) {
  x y = new x();
  y.print(9);
  y.print(9,9);
  y.print(9,9,9);
  // 231
}
}
 // System.arraycopy + VarArgs + foreach
class x {
void xx (int... xxx){
  int b[] = new int[xxx.length - 1];
  System.arraycopy(xxx,1,b,0,xxx.length - 1);
  for(int c:b) System.out.print(c);
  // 678
}
public static void main(String[] args) {
  int a[] = {5,6,7,8};
  x xxxx = new x();
  xxxx.xx(a);
}
}
 printf() format() in java.io.PrintStream, java.io.PrintWriter, java.lang.String
class x {
public static void main(String[] args) {
System.out.printf("%2$.2f %<.2f %1$o %n",20,Math.PI);
System.out.format("%.2f %<.2f %n",Math.PI,20);
System.out.printf("%x %<b %n",20);
System.out.format("%s %<c %n",65);
}
}
3.14 3.14 24
3.14 3.14
14 true
65 A
 // Calendar : java.util.Formatter
import java.util.*;
class x {
public static void main(String[] args) {
  Calendar t = Calendar.getInstance();
  System.out.printf("%tY-%<tm-%<td %<tH:%<tM:%<tS",t);
  // 2007-07-21 04:17:02
}
}
 // Wrapper class + Boxing + AutoUnboxing
class x {
public static void main(String[] args) {
  int a = 5;
  a = Integer.parseInt("3") + Integer.valueOf("3"); 
  Integer b = new Integer(7); // Boxing
  b = 8; // AutoBoxing
  Integer c = 9; // AutoBoxing
  int d = c.intValue(); // Unboxing
  int e = c; // AutoUnboxing
  System.out.println("" + a +  b + c + d + e);
  // 6899
}
}
 // Autoboxing + .equals
class x {
public static void main(String[] args){	
Integer i = new Integer(0);
while(i.equals(0)) {
  System.out.println(i); // 0
  i++;
}
while(i < 3){ // autoboxing
  System.out.println(i); // 1 2
  i++;
}
}
}
 // Generics + Collection + foreach
// ตรวจสอบใน compile time มิใช่ run time
import java.util.*;
class x {
static void p(ArrayList<String> a) {
 for(String b:a){
   System.out.println(b);
 }
}
public static void main(String[] args) {
  ArrayList<String> l = new ArrayList<String>();
  l.add("a");
  l.add("b"); // ถ้าส่งตัวอื่นจะ compile ไม่ผ่าน
  p(l);
}
}
 // Assigning Reference
Integer a = new Integer(1);
Integer b = a;
a = new Integer(2);
System.out.println(""+ a + b); // 2 1
 // Passing Argument (Primitive Type(By Value) & Reference Type(By Address of Object)
// a เป็น primitive ส่วน b เป็น Object
class x{
static int a = 1;
static StringBuffer b = new StringBuffer("b");
static void c(int d,StringBuffer e){ 
d = 2; 
e.replace(0,1,"x");
}
public static void main(String[] args) {
c(a,b);
System.out.println(a +""+ b); // 1 x
}
}
 // immutable object = ไม่สามารถเปลี่ยนแปลงค่าได้
// String objects are immutable 
// StringBuffer is a thread-safe, mutable sequence of characters
// StringBuilder is a mutable sequence of characters. no guarantee of synchronization.
// http://java.sun.com/j2se/1.5.0/docs/api/java/lang/StringBuilder.html
class x{
public static void main(String[] args) {
String a = "abcd";
a.replace("bc","fg");
String b = "abcd";
b = b.replace("bc","fg");
StringBuffer c = new StringBuffer("abcd");
c.replace(1,2,"fg");
System.out.println(a + b + c); // abcd afgd afgcd
// http://java.sun.com/j2se/1.4.2/docs/api/java/lang/StringBuffer.html
}
}
 // Static Member : Static Method และ Static Variable
// Static คือ สิ่งที่มีได้ตัวเดียวในหน่วยความจำ ทำให้ new กี่ครั้งก็ได้ค่าเดิม
class father { 
public static int a = 0; // static variable
public static int b() { return ++a; } // static method
}
class child extends father { 
static {
  father f1 = new father();
  System.out.println(f1.b());
  System.out.println(f1.b());
  father f2 = new father();
  System.out.println(f2.b()); วิธีที่ 3 เรียกผ่าน instant
}
public static void main(String a[]){
  System.out.println(new father().b()); วิธีที่ 1 เรียกผ่าน temporaly instant
  System.out.println(father.b()); // วิธีที่ 2 เรียกผ่าน class
  // 1 2 3 4 5 
}
}
 // polymorphism + inheritance + abstract
// abstract method ต้องอยู่ใน class ที่เป็น abstract
// abstract class ไม่มี member เป็น abstract ก็ไม่พบปัญหาใด
// ถ้ามี method มี return type ใน method ต้องมี return value
// ทดสอบแล้ว b ไม่เป็น abstract ก็ให้ผลเหมือนเดิม
abstract class human { 
public static int a = 0; 
abstract int b();
}
class father extends human { 
int b() { return ++a;}; // return required
}
class child { 
public static void main(String args[]){
  human h1 = new father();
  System.out.println(h1.b());
  System.out.println(h1.b());
  human h2 = new father();
  System.out.println(h2.b());
  // 1 2 3
}
}
 // Static Initializer หรือ Static Block
// Static Block ถูกทำหลัง Load Static member แล้ว
// java -Dx=5 child คือ set System Property
class child { 
static {
  String x = System.getProperty("x");
  System.out.println(x + y()); // ถูกทำหลัง Load y() ไปแล้ว
  System.exit(0);
}
static String y () { return "y"; } // ถูกทำก่อน
}
 // encapsulation : setter + getter + private
// Modifier ; public protected default private
class father { 
private int a = 1;
protected int geta() { return a; }
protected void seta(int a) { this.a = a; }
}
class child { 
public static void main(String args[]){
  father f = new father();
  f.seta(5);
  System.out.println(f.geta()); // 5
}
}
 // throws Exception
// ถ้า method throws ตัวนำ method ไปใช้ต้อง catch มิเช่นนั้น compile error
class father { 
static void a() throws java.lang.Exception { 
	System.out.println(5); 		
}
}
class child extends father { 
public static void main(String args[]){
	try { a(); }
	catch (java.lang.Exception e) {}
}
}
 // super. + this.
// เรียกใน method ที่เป็น static ไม่ได้ เช่น main หรือ d() ที่เติม static
class father { 
static int a = 1;
static int b() { return 2; }
}
class child extends father { 
static int c = 3;
public static void main(String args[]){
  new child().d();
}
void d() { 
  System.out.println(super.a + super.b()); // 3
  System.out.println(this.c); // 3 
}
}
 // polymorphism แบบ 1 (no casting)
// แบบนี้ใน father มี age จึงไม่ต้อง casting
class father { 
int age() { return 0; }
}
class child1 extends father { 
int age() { return 10; }
}
class child2 extends father { 
int age() { return 20; }
}
class child {
public static void main(String args[]){
  father f[] = new father[10]; // กำหนดไว้เกิน ต้องใช้ instanceof ตรวจ
  f[0] = new child1();
  f[1] = new child2();
  for(father a:f){
    if (a instanceof father) System.out.println(a.age());
  }
}
}
 // polymorphism แบบ 2 (casting)
// เพราะลูกแต่ละคนมี method ที่แตกต่างกัน
class father { }
class child1 extends father { 
String golf() { return "beginner"; }
}
class child2 extends father { 
String ball() { return "professional"; }
String tennis() { return "professional"; }
}
class child {
public static void main(String args[]){
  father f[] = new father[10];
  f[0] = new child1();
  f[1] = new child2();
  for(father a:f){
    if (a instanceof child1) { 
      child1 b = (child1)a;
	  System.out.println(b.golf()); 
    }
    if (a instanceof child2) { 
      child2 b = (child2)a;
	  System.out.println(b.ball() + b.tennis()); 
    }
  }
}
}
 // Exception
// Override ใช้ throws Exception ที่ใหญ่กว่าได้
// catch จะทำตามเงื่อนไขของ Exception อันแรกที่พบเท่านั้น
// ถ้าผิดลำดับชั้นจะ compile error เช่นนำ Exception ขึ้นก่อน
// ArithmeticException คือ หารด้วย 0
// NumberFormatException คือ ส่งอักษรเข้าตัวเลข
class father {
static void a() throws ArrayIndexOutOfBoundsException { } 
}
class child{ 
static void a() throws Exception { 
  int a[] = new int[1]; 
  a[5] = 0; 
} 
public static void main(String args[]){
  try { 
  a();
  } 
  catch (ArrayIndexOutOfBoundsException e) { System.out.println("error1"); }
  catch (Exception e) { System.out.println("error2"); }
  finally { System.out.println("finally"); }
  // error1 finally
}
}
 // ArrayList
// ArrayList เป็น Collection หนึ่งที่ต้อง import java.util.*
// ถ้าไม่ใช่ Genetic จะพบ Note : Recompile with -Xlint:unchecked for details.
import java.util.*;
public class a {
 public static void main (String args[]){
  ArrayList list = new ArrayList();
  list.add(new Integer(5));
  list.add(new Integer(6));
  list.add("hello");
  pout(list);
 }
 public static void pout(ArrayList ai){
  ListIterator a = ai.listIterator();
  while(a.hasNext()){
    Object o = a.next();
    if (o instanceof Integer) {
      Integer i = (Integer)o;
      System.out.println(i);
    }
  }
 }
}
 // Generic
// ใช้ตรวจสอบ object ขณะ compile ไม่ใช้ runtime
// อาจใช้ instanceof ตรวจสอบก่อน casting แต่ไม่สะดวก
import java.util.*;
public class a {
 public static void main (String args[]){
  ArrayList <Integer> list = new ArrayList <Integer>();
  list.add(new Integer(5));
  list.add(new Integer(6));
  pout(list);
 }
 public static void pout(ArrayList <Integer> ai){
  ListIterator a = ai.listIterator();
  Object o; 
  Integer i; 
  while(a.hasNext()){
    o = a.next();
    i = (Integer)o;
    System.out.println(i);
  }
 }
}
 // Generic
// โปรแกรมนี้มีปัญหา 2 อย่างคือ Compile Warning + java.lang.ClassCastException
// Collection ไม่เป็น Generic จึงเป็นเพียง warning compile และ Generic ไม่มีผล
// Integer Casting เป็น String ไม่ได้
import java.util.*; 
class x { 
public static void main(String [] args) { 
List samples = new ArrayList (); 
samples.add("1"); 
samples.add(2); 
samples.add("3"); 
pout(samples); 
} 
static void pout(List <String> o) { 
for(String s : o) System.out.print(s + " "); 
} 
}
 // Generic ต้องเป็น Object
// ใช้ int แทน Integer จะ Compile ไม่ผ่าน
import java.util.*; 
class x { 
public static void main(String [] args) { 
List<Integer> samples = new ArrayList<Integer> (); 
samples.add(1); // Autoboxing
samples.add(2); 
samples.add(3); 
System.out.print(samples); 
} 
}
 // Generic on Define Object
// Compile error เพราะตรวจพบ (1) ไม่ตรงกับ String
// ถ้าไม่มี (1) จะ warning compile แล้วได้ [one, two]
// ถ้าไม่มี (1) และ Set<String> vals = new TreeSet<String>(); ทำให้ warning compile หายไป
// ถ้าเป็น Set vals = new TreeSet<String>(); จะ warning compile แล้ว run error
// ผลของ Set vals = new TreeSet<String>(); ไม่ต่างกับ Set vals = new TreeSet();
// run error ที่พบคือ java.lang.ClassCastException
import java.util.*; 
class x { 
public static void main(String [] args) { 
  Set <String> vals = new TreeSet(); 
  vals.add("one"); 
  vals.add(1); // ถ้าไม่มี Generic จะ compile ผ่าน
  vals.add("two"); 
  System.out.println(vals); 
  // System.out.println(vals.get(0)); // Set ไม่มี get() ให้ใช้
} 
}
 // Generic + Collection
import java.util.*; 
class x { 
public static void main(String [] args) { 
  List <Object> vals = new LinkedList<Object>(); 
  vals.add("one"); 
  vals.add("two"); 
  System.out.println(vals); 
  System.out.println(vals.get(0)); // one
} 
}
 // Collection + Generic + pass by address of object
// ในภาษา Java มีแต่ passing by value ซึ่งไม่มี passing by reference
import java.util.*; 
class x { 
public static void main(String [] args) { 
List<Object> samples = new ArrayList<Object>(); 
samples.add(new Integer("1"));
int y = 5;
addList(samples,y); 
System.out.print(samples +""+ y); // 1 2 5
} 
static void addList(List <Object> o, int n) { 
n = 6;
o.add(new Integer("2"));
} 
}
 // Generic + HashMap
// Compile error เพราะ for(String b : bs.keySet())
// ถ้าเปลี่ยนเป็น Object b ก็จะ OK
import java.util.*; 
class School {} 
class Teacher extends School {} 
class Student extends School {} 
class x { 
public static void main(String [] args) { 
Map <String, School> s = new HashMap <String, School>();  
s.put("t1", new Teacher());  
s.put("s1", new Student()); 
Map bs = addBirds(s); 
for(String b : bs.keySet()) System.out.print(b + " "); 
} 
static Map addBirds(Map sx) { 
sx.put("s2", new Object());     
return sx; 
}   
}
 // Collection + Generic + ? + interface
// สามารถรับ interface ได้ด้วย
// สามารถใช้ static void checkAnimal(List <? extends Eat> pets) {
// สามารถใช้ static void checkAnimal(List <? extends Animal> pets) {
// When we use wildcard(?) to catch the collection , then modifications are not allowed in that collection
import java.util.*;
interface Eat{}
class Animal implements Eat{}
class Dog extends Animal {}
class Cat extends Animal  {}
class x {
public static void main(String[] args) {
List <Animal> a = new ArrayList <Animal>();
List <Dog> d = new ArrayList <Dog>();
List <Cat> c = new ArrayList <Cat>();
checkAnimal(a);
checkAnimal(d);
checkAnimal(c);
}
static void checkAnimal(List <?> pets) {
System.out.print("animals checked here");
}
}
 // Collection + type safe + autoboxing
// โปรแกรมนี้มอง a เป็น type safe จึง autoboxing ใน foreach อัตโนมัติ
import java.util.*;
class x {
public static void main(String[] args) {
List <Integer> a = new ArrayList <Integer>();
a.add(5);
a.add(6);
for(int aa:a)System.out.print(aa);
}
}
 // Generic
// โปรแกรมนี้ Compile warning เพราะ non-type safe ที่ ArrayList b = a; 
import java.util.*; 
class Vehicle {} 
class Car extends Vehicle {} 
class Bus extends Vehicle {} 
class x { 
public static void main(String [] args) { 
ArrayList<Car> a = new ArrayList<Car>(); 
a.add(new Car()); 
ArrayList b = a; 
ArrayList<Bus> c = (ArrayList<Bus>)b; 
c.add(new Bus()); 
for (Object d : b) System.out.println(d); 
} 
}
 // enum
// การสร้างประเภทของข้อมูลขึ้นใช้เอง
public class a {
 public static enum c { a,b,c }
 public static void main (String args[]){
  for(c x:c.values()){
    System.out.println(x); // a b c
  }
  c y = c.b;
  System.out.println(c.a);  
  System.out.println(y);  
 }
}
 // while และ break
// โปรแกรมนี้จะพิมพ์เลข 2 แล้วหยุดการทำงาน
class x {
public static void main(String[] args) {	
int a = 1;
while(a++ < 5) {
System.out.println(a);
break;
}}}
 // java.lang.ClassCastException 
class y {}
class z extends y {}
class x extends y{
public static void main(String[] args) {	
y z1 = new z();
y z2 = new z();
z2 = (x)z1;
}
}
 // FileReader + BufferedReader
import java.io.*;
class x {
public static void main(String[] args) throws IOException{	
FileReader f = new FileReader("x.java");
BufferedReader b = new BufferedReader(f);
String r = null;
while ((r=b.readLine()) != null){
System.out.print(r);
}
}
}
 // FileWriter + BufferWriter
import java.io.*;
class x {
public static void main(String[] args) throws IOException{	
FileWriter f = new FileWriter("xx.java");
BufferedWriter b = new BufferedWriter(f);
b.write("aa"+"\n");
b.write("aa"+"\n");
b.close();
}
}
 // enum + constructor
// ทำ constructor ก่อน ถ้าพิมพ์ AccountType.FIXED ก็จะได้คำว่า A FIXED
enum AccountType {
  SAVING, FIXED,  CURRENT;
  private AccountType() {
    System.out.println("A ");
  }       
}
 // enum + override method : toString()
// เมื่อพิมพ์ Drinks.TEA จะพบคำว่า hide value
static enum Drinks {
  COFFEE, TEA, JUICE;
  public String toString() { return "hide value"; }
}
// enum + toString ในแต่ละค่า
enum Taste {
  SWEET { public String toString() { return "Ok";}},
  HOT { public String toString() { return "Bad";}};
}
 // enum + method in enum
// ประกาศใช้ Level lx = Level.BEGINNER;                                                         // line 5
// ใช้ method ใน enum ด้วย lx.checkLevel(level); // 8 
enum Level {
  BEGINNER, INTERMEDIATE, EXPERT;                                                              // line 1
  public void checkLevel(Level l) {                                         // line 2
    System.out.println(l.toString().length());
 }
}
 // ส่ง argument ต้องมี type ตรงกัน ต่าง type ไม่ได้
// สามารถส่งค่าไปมาระหว่าง primitive และ wrapper class ได้
class x {
  static void aa (short a){}
  static void aa (Short a){}
  static void aa (Long a){}
  // static void aa (Integer a){}
  public static void main(String args[]){
    int xxx = 5;
    aa(xxx); // Compile fail because aa (int a) required
  }
}
 // แสดง instance แบบ non-static และ static
class x { 
int a;
static int b;
void c(int m,int n) { a += ++m; b += ++n; } 
void d(int m) { a += ++m; b += m; } 
void main(){
a++;
x e = new x();
e.c(1,2);  
System.out.println(""+ a + b + e.a + e.b); // 1 3 2 3
e.d(1);  
System.out.println(""+ a + b + e.a + e.b); // 1 5 4 5
x f = new x();
f.c(1,2);  
System.out.println(""+ a + b + f.a + f.b); // 1 8 2 8
f.d(1);  
System.out.println(""+ a + b + f.a + f.b); // 1 10 4 10
}
public static void main(String [] args) { new x().main(); }
}
 | 
 |