แพ็คเกจจาวา
ที่มา:
Usemynotes โพสต์นี้จะช่วยให้คุณเข้าใจแพ็คเกจใน Java ได้ดีขึ้น เข้าใจวัตถุประสงค์และวิธีนำไปใช้
แพ็คเกจใน Java คืออะไร
แพ็คเกจใน Javaเป็นวิธีการจัดกลุ่มคลาส อินเทอร์เฟซ และแพ็คเกจย่อยเข้าด้วยกัน แพ็คเกจใช้เพื่อสร้างกลุ่มของคลาสที่เกี่ยวข้อง อินเทอร์เฟซ การแจงนับ และอื่นๆ
แพ็คเกจย่อยคือแพ็คเกจที่อยู่ภายในแพ็คเกจอื่น สิ่งเหล่านี้จะไม่นำเข้าตามค่าเริ่มต้น แต่คุณสามารถนำเข้าด้วยตนเองได้หากจำเป็น ข้อกำหนดการเข้าถึงไม่ได้จัดเตรียมไว้ให้กับสมาชิกแต่ละรายของแพ็คเกจย่อย แต่จะถือเป็นแพ็คเกจที่แยกจากกัน
แพ็คเกจบางประเภทใน Java:
- java.lang - มาพร้อมกับ Java เป็นค่าเริ่มต้น
- java.io - ประกอบด้วยคลาส วิธีการ และองค์ประกอบอื่นๆ ที่เกี่ยวข้องกับอินพุต/เอาท์พุต
เหตุใดจึงต้องมีแพ็คเกจ?
- เพื่อหลีกเลี่ยงความขัดแย้งเรื่องชื่อ
- เพื่อให้มีการควบคุมการเข้าถึง
- เพื่อให้เกิดการห่อหุ้มข้อมูล
จะสร้างแพ็คเกจใน Java ได้อย่างไร?
มาสร้างแพ็คเกจที่เรียกว่า
คอมพิวเตอร์กัน โดยทั่วไปชื่อแพ็คเกจจะเขียนด้วยตัวอักษรพิมพ์เล็ก ทำเช่นนี้เพื่อหลีกเลี่ยงความขัดแย้งของชื่อกับชื่อคลาสเท่านั้น เราจะสร้างอินเทอร์เฟซที่เรียกว่าPluggable
ซึ่งจะอยู่ใน แพ็คเกจ
คอมพิวเตอร์
package computer;
interface Pluggable {
public void pluggedIn();
public void pluggedOut();
}
ตอนนี้เราจะสร้างคลาสที่เรียกว่า
PenDriveซึ่งจะใช้อินเทอร์เฟซข้างต้น
package computer;
public class PenDrive implements Pluggable {
int storage = 64;
public void pluggedIn () {
System.out.println("Pen Drive is connected");
}
public void pluggedOut () {
System.out.println("Pen Drive is removed");
}
public int storage() {
return storage;
}
public static void main(String args[]) {
PenDrive p = new PenDrive ();
p.pluggedIn();
System.out.println("Pen Drive Storage: " + p.storage());
p.pluggedOut();
}
}
จะสร้างลำดับชั้นแพ็คเกจใน Java ได้อย่างไร?
เมื่อสร้างลำดับชั้น แพ็กเกจใน Java จะถูกตั้งชื่อในลำดับย้อนกลับ ทำให้คล้ายกับไดเร็กทอรีหรือโฟลเดอร์มาก เช่นเดียวกับบนคอมพิวเตอร์ส่วนบุคคล โดยที่โฟลเดอร์หนึ่งสามารถมีโฟลเดอร์ย่อยได้ตั้งแต่หนึ่งโฟลเดอร์ขึ้นไป แพ็คเกจใน Java ก็เช่นเดียวกัน มาดูแพ็คเกจที่ชื่อ
Asia.India.Kolkataกัน โฟลเดอร์เหล่านี้คือโฟลเดอร์ที่มีอยู่ทั้งหมด แต่หากคุณพิจารณาตามภูมิศาสตร์ จะเห็นได้ชัดว่ากัลกัตตาอยู่ในอินเดีย และอินเดียอยู่ในเอเชีย วัตถุประสงค์หลักของลำดับชั้นคือเพื่อให้ค้นหาคลาสได้ง่ายขึ้น
ประเภทของแพ็คเกจในภาษา Java
แพ็คเกจในตัว
แพ็คเกจบิวท์อินคือแพ็คเกจที่ประกอบด้วยคลาสบิวท์อินจำนวนมากที่เป็นส่วนหนึ่งของ Java API แพ็คเกจเหล่านี้ประกอบด้วย:
- java.util - แพ็คเกจนี้มีจำนวนคลาสยูทิลิตี้ที่จำกัดซึ่งใช้ในการปรับใช้โครงสร้างข้อมูล เช่น รายการที่เชื่อมโยง ชุด และอื่นๆ นอกจากนี้ยังรองรับการทำงานวันที่และเวลาและอื่นๆ อีกมากมาย
- java.net - ประกอบด้วยคลาสที่ใช้สำหรับการทำงานของเครือข่าย
แพ็คเกจที่ผู้ใช้กำหนด
แพ็คเกจที่กำหนดโดยผู้ใช้เรียกว่าแพ็คเกจผู้ใช้ ผู้ใช้สามารถสร้างแพ็คเกจด้วยตนเองและมีคลาสได้มากเท่าที่ต้องการ
จะเข้าถึงแพ็คเกจจากแพ็คเกจอื่นได้อย่างไร?
คุณสามารถเข้าถึงแพ็คเกจจากแพ็คเกจอื่นได้สามวิธีง่ายๆ:
- การใช้เครื่องหมายดอกจันในคำสั่งนำเข้า
เครื่องหมาย ดอกจัน (
* ) ใช้เพื่อแสดงถึง “ทุกสิ่ง” ในภาษา Java เมื่อใช้มัน เราสามารถนำเข้าทุกอย่างที่อยู่ภายในแพ็คเกจย่อยของแพ็คเกจได้
ตัวอย่าง: พิจารณาแพ็คเกจชื่อ
tools หากเราต้องการนำเข้าทุกอย่างที่อยู่ในแพ็คเกจนี้ เราจำเป็นต้องใช้คำสั่งนำเข้าเช่น:
import tools.*;
- ใช้การนำเข้าpackage.ClassName;
การกล่าวถึงชื่อคลาสในแพ็คเกจเป็นวิธีที่มีประสิทธิภาพในการนำเข้าเฉพาะคลาสที่คุณต้องการลงในโปรแกรมของคุณ ซึ่งจะช่วยหลีกเลี่ยงการนำเข้าคลาสที่ไม่จำเป็น
ตัวอย่าง: พิจารณาแพ็คเกจชื่อ
books หากเราต้องการนำเข้าคลาสหรืออินเทอร์เฟซเฉพาะจากนั้น (เราจะดูที่ คลาส
Pages ) เราก็สามารถนำเข้าได้โดยใช้:
import book.Pages;
มีวิธีใช้แพ็กเกจ Java หรือคลาสโดยตรงโดยใช้ชื่อแบบเต็ม ด้วยวิธีนี้คุณไม่จำเป็นต้องนำเข้าแพ็คเกจและสามารถใช้งานได้โดยตรงในโปรแกรม
ตัวอย่าง:
java.awt.List aSimpleList = new java.awt.List();
ขนาดแบตช์เริ่มต้นใน Java
ตามค่าเริ่มต้น Java จะนำเข้าแพ็คเกจ
java.lang มีหลายคลาสที่ใช้กันทั่วไปในโปรแกรม Java ธรรมดา เช่น
String ,
Integerและอื่นๆ หนึ่งในคลาสที่สำคัญที่สุดคือ คลาส
Objectซึ่งจะพบได้ใน แพ็คเกจ
java.lang เช่น กัน ขนาดของแพ็คเกจนี้ขึ้นอยู่กับส่วนประกอบ: 8 อินเทอร์เฟซ, 37 คลาส, 3 enums, 27 ข้อยกเว้น, 23 ประเภทข้อผิดพลาด และ 5 ประเภทคำอธิบายประกอบ
วิธี Java ที่ปลอดภัยสำหรับเธรดสำหรับผู้เริ่มต้น
ที่มา:
ปานกลาง จากการใช้บทความนี้ คุณสามารถเรียนรู้เกี่ยวกับการทำงานของวิธี thread safe ใน Java ![คอฟฟี่เบรค #165. แพ็คเกจในภาษาจาวา วิธีที่ปลอดภัยสำหรับผู้เริ่มต้น - 2]()
ฉันพบว่านักพัฒนา Java รุ่นเยาว์/กลางจำนวนมากเข้าใจผิดว่าวิธีการรักษาความปลอดภัยของเธรดควรทำงานอย่างไรในโครงการจริง และเนื่องจากปกติแล้วเราทำงานในสภาพแวดล้อมแบบมัลติเธรด การใช้อย่างถูกต้องจึงมีความสำคัญมาก วิธีการที่ปลอดภัยสำหรับเธรดเป็นวิธีการที่สามารถเรียกจากหลายเธรดพร้อมกันได้ โดยไม่ส่งผลกระทบต่อสถานะข้อมูลของกันและกัน ความเข้าใจแนวคิดนี้ไม่เพียงพอทำให้เกิดจุดบกพร่องที่ยากต่อการค้นหาและแก้ไข เพื่อหลีกเลี่ยงข้อผิดพลาด มาดูตัวอย่างกัน
ตัวอย่าง #1:
public static int countLetters(String input) {
int counter = 0;
for (Character c : input.toCharArray()) {
if (Character.isAlphabetic(c)) {
counter++;
}
}
return counter;
}
- เมธอดcountLettersเป็นแบบคงที่ โดยจะส่งกลับ ค่า intและยอมรับพารามิเตอร์สตริงเป็นอินพุต
- ตัวนับตัวแปรดั้งเดิมจะถูกสร้างขึ้นภายในเมธอด จากนั้นวนซ้ำผ่านอักขระของสตริงอินพุตและเพิ่มตัวนับตัวแปรทุกครั้งที่พบอักขระตัวอักษร
เธรดวิธีนี้ปลอดภัยหรือไม่ นักพัฒนาหลายคนปฏิเสธ เพราะในกรณีนี้ เรามีการดำเนินการที่เพิ่มขึ้นซึ่งไม่ปลอดภัยสำหรับเธรด ลองคิดดูสิ ในโมเดลหน่วยความจำ Java เรามีสแต็กและฮีป แต่ละเธรดมีสแต็กของตัวเอง และเธรดทั้งหมดใช้ฮีปเดียวกัน ในเรื่องนี้ ข้อมูลสแต็กจะปลอดภัยสำหรับเธรดเสมอ แต่ข้อมูลฮีปไม่ปลอดภัย สแต็กเก็บการอ้างอิงดั้งเดิมและวัตถุ ฮีปประกอบด้วยอ็อบเจ็กต์เอง ซึ่งหมายความว่าในตัวอย่างโค้ดนี้ แต่ละเธรดจะเก็บตัว นับตัวแปร
ของตัวเองไว้บนสแต็ก และไม่มีผลกระทบใด ๆ ต่อข้อมูลของเธรดอื่น ดังนั้นวิธีการนี้จึง
ปลอดภัยสำหรับเธรด
โปรดทราบว่า ค่า String อินพุต ก็เป็นอ็อบเจ็กต์เช่นกัน แต่Stringและ wrappers ดั้งเดิม ( Integer , Long , Double , Booleanและอื่นๆ) ปลอดภัยสำหรับเธรดเนื่องจากไม่เปลี่ยนรูป
ตัวอย่าง #2:
public static int countLetters2(String input) {
List<Character> listCounter = new ArrayList<>();
for (Character c : input.toCharArray()) {
if (Character.isAlphabetic(c)) {
listCounter.add(c);
}
}
return listCounter.size();
}
รหัสนี้ใช้ตรรกะเดียวกันกับตัวอย่างแรก แต่ใช้ วัตถุ
รายการ แทนตัวแปร intดั้งเดิม จากส่วนที่แล้ว เรารู้ว่าอ็อบเจ็กต์ใน Java ถูกเก็บไว้ในฮีป และ
รายการก็คืออ็อบเจ็กต์ เรายังรู้ด้วยว่าสแต็กเก็บการอ้างอิงถึงออบเจ็กต์บนฮีป ในตัวอย่าง #2 แต่ละเธรดจะสร้าง อ็อบเจ็กต์
ArrayList ใหม่ : และ ตัวแปร
listCounterจะเก็บการอ้างอิงไปยังอ็อบเจ็กต์ของมันบนฮีป ดังนั้นจึงไม่มีเธรดอื่นใดที่สามารถเปลี่ยนอ็อบเจ็กต์นั้นได้
List<Character> listCounter = new ArrayList<>();
ซึ่งหมายความว่าวิธีนี้ปลอดภัยสำหรับเธรด
ตัวอย่าง #3:
public class CounterUtil {
List<Character> listCounter = new ArrayList<>();
public int countLetters3(String input) {
for (Character c : input.toCharArray()) {
if (Character.isAlphabetic(c)) {
listCounter.add(c);
}
}
return listCounter.size();
}
}
ในตัวอย่างนี้ เรามี CounterUtil คลาสซิงเกิลตัน (ซึ่งเป็นสิ่งสำคัญ) พร้อมด้วยตัวแปรโกลบอล
listCounter ตัวแปรนี้ถูกสร้างขึ้นพร้อมกับอินสแตนซ์ซิงเกิลตัน เมื่อหลายเธรดเรียกใช้เมธอด
countChars3 เธรด ทั้งหมดจะใช้ตัวแปรโกลบอล
listCounter เดียวกัน ซึ่งจัดเก็บการอ้างอิงไปยังออบเจ็กต์เดียวกันบนฮีป และเธรดในนั้นจะมีอิทธิพลซึ่งกันและกัน ดังนั้นเราจึงสรุปได้ว่าวิธีนี้ไม่ปลอดภัยสำหรับเธรด และแม้ว่าเราจะเปลี่ยน
List<Character> listCounterเป็นตัวแปรดั้งเดิม
int counterมันก็จะไม่ปลอดภัยสำหรับเธรดเช่นกัน เนื่องจากเธรดทั้งหมดจะใช้ตัวแปรดั้งเดิมตัวเดียวกัน
ตัวอย่างสุดท้าย:
public static int countLetters4(List<Character> inputList) {
List<Character> listCounter = new ArrayList<>();
for (Character c : inputList) {
if (Character.isAlphabetic(c)) {
listCounter.add(c);
}
}
return listCounter.size();
}
เมธอด
countLetters4ยอมรับรายการอักขระแทนพารามิเตอร์
String ที่นี่เรา
ไม่สามารถรับประกันได้ว่าวิธีนี้ปลอดภัยสำหรับเธรด ทำไม เพราะเราไม่แน่ใจว่านักพัฒนาจะใช้วิธีนี้อย่างไร หากเธรดอื่นจากภายนอกเปลี่ยนข้อมูลใน
inputListพร้อมกับ เมธอด
counterLetters4 ของเรา อาจส่งผลต่อผลลัพธ์สุดท้าย
บทสรุป
เราได้ดูตัวอย่างเพียงสี่ตัวอย่างเท่านั้น และไม่ครอบคลุมทุกแง่มุมของความปลอดภัยของเธรดในโปรเจ็กต์ Java แต่เป็นจุดเริ่มต้นที่ดี ครั้งต่อไปที่คุณเห็นวิธีการในโค้ดของคุณ ให้ถามตัวเองว่า “เธรดวิธีนี้ปลอดภัยหรือไม่” และอีกไม่นานคุณก็จะเข้าใจคำตอบได้ชัดเจน
GO TO FULL VERSION