Constants, Static members, Method, this
Final
การประกาศค่าคงที่ทำได้ดังนี้
class A {
public static final int a = 199;
}
ซึ่งเราจะเห็น keywords 3 ตัวด้วยกันได้แก่ public, static และ final จะขออธิบายถึง final ก่อนซึ่งจะบังคับให้ Compiler ตรวจสอบในโปรแกรมว่ามีการเปลี่ยนค่า a ในภายหลังหรือไม่
เช่น
class A {
public static final int a = 199;
}
class B {
public static void main(String[]args) {
A.a = 500;
}
}
คำถาม
- จะเกิดอะไรขึ้นหากประกาศ final เช่น class B { public static final int b; }
เราสามารถประกาศ final ในระดับ local ได้ดังนี้
class A {
public static void main(String[] args) {
final int a=123;
System.out.println(a);
}
}
คำถาม
- จะเกิดอะไรขึ้นหาก code เป็นดังนี้
public class A {
public static void main(String[] args) {
final int a;
a = 1;
System.out.println(a);
}
} หรือ
public class A {
public static void main(String[] args) {
final int a;
a = 1;
a = 2;
System.out.println(a);
}
}
Static
การที่จะพูดถึงเรื่อง static ต้องขออธิบายถึงการจัดการ memory ของ jvm ซะก่อน
ซึ่งจะมีการแบ่งเนื้อที่จัดเก็บ memory หลักๆออกเป็น stack ,heap และ method-area
หลังจากที่เราเรียก >>java {ชื่อคลาสที่มี main} แล้ว Class loader จะทำการ load class เราขึ้นมาแล้ว allocate หน่วยความจำสำหรับ static member โดยแบ่งพื้นที่
การจัดเก็บข้อมูลต่างๆ ดังรูป

ซึ่งข้อมูล class และ method จะถูกเก็บใน method area และเมื่อทุกครั้งที่เรา
new instance ขึ้นมาข้อมูลของ Object จะถูก allocate และัจัดเก็บอยู่ใน heap

สำหรับข้อมูล static นั้นก็จะถูกจัดเก็บใน method area เช่นกัน นั่นหมายความว่าทุกครั้งที่ new instance ข้อมูล static จะไม่ถูก allocate พื้นที่ใน heap ใหม่ ลองดูผมลัพท์จาก code ตัวอย่างครับ
class A { static int i = 0; int j = 1;}
class B {
public static void main(String[]args) {
A a1 = new A();
A a2 = new A();
a1.i = 5;
System.out.println(a2.i);
a1.j = 6;
System.out.println(a2.j);
}
เราสามารถอ้างอิงถึงข้อมูล static ผ่านทางชื่อ class ได้เลยเช่น
A.i = 100;
System.out.println(A.i);
Method
การประกาศ method ทำได้ดังนี้
class A {
void test() {} //ไม่ return ค่า
int test2() {return 9;}//return ค่า value ของ integer คือ 9
void test(int i) {} //Overload method ของ test
static int print(){return 0;}//static method
}
การเรียกใช้ Method ก็จะทำเหมือนการอ้างถึง Data Member เช่น
A a = new A();
a.test();
สำหรับ static Method นั้นสามารถอ้างถึงผ่านทางชื่ิอ class ได้เลยโดยไม่ต้องสร้าง instance เช่น
A.print();
เมื่อเริ่มโปรแกรมหลังจาก Class Loader load Class ที่มี main funtion เข้ามาจะทำการ allocate ข้อมูลที่เป็น static มาไว้ใน Method Area ก่อน ดังนั้น lifecycle ของข้อมูลอื่นจะเกิดขึ้นตอน new instance ทำให้ static method อ้างถึง member หรือ method ที่เป็น static ได้เท่านั้น ส่วน method ที่ไม่ใ่ช่ static ก็สามารถอ้างอิงถึง member หรือ method ที่เป็น static ได้ เพราะ lifecycle ของ static นั้นเกิดขึ้นมาก่อนเช่น
class A {
int a;//จะถูก allocate หลังจาก new A();
static int b;//จะถูก allocate เมื่อ class loader load A ขึ้นมา
static int getA() {
return a;//ผิด
}
static int getB() {
return b;//ถูก
}
int getA2() {
return a;//ถูก
}
int getB2() {
return b;//ถูก
}
}
Static Block
เราสามารถประกาศใช้ static block หากต้องการให้ static member หรือ method เริ่มการทำงานบางอย่างเช่น
class A {
static int a;
static {
a = 999;
System.out.println(a);
}
public static void main(String[]args) {
System.out.println("Hello");
}
}
จาก code ตัวอย่างให้สังเกตุผลลัพท์ลำดับการทำงานว่าอะไรทำก่อนและหลัีงครับ
และเช่นเดียวกับ static method, static block อ้างอิงได้แต่ static member และ method ได้ืเท่านั้น
this
บางครั้งในการเขียนโปรแกรม เราอาจต้องการแจก reference ของ instance ของตัวเอง
ไปให้ Object อื่นเช่น
class A {
int i = 25;
B b = new B();
void print() {
b.print(this);
}
}
class B {
void print(A a) {
System.out.println("Value of A is "+a.i);
}
}
จาก code ตัวอย่างจะสังเกตว่าที่ class B มี Method ที่รับ parameter A และที่
method print ใน class A สามารถส่ง reference ของ instance ของตัวมันเองไปให้ B
ทำงานได้ เราสามารถใช้ this ช่วยในตัวอย่างต่อไปได้
class A {
int a;
void setA(int a) {
this.a = a;//assign ค่า a ที่รับมาให้กับ data member a
}
}
สอนพื้นฐาน Java
Line: wizarud
Gmail: [email protected]