คำถามและคำตอบสัมภาษณ์ Java Core 50 อันดับแรก ส่วนที่ 1
แผนภาพแสดงให้เห็นว่าโดยทั่วไปข้อยกเว้นทั้งหมดแบ่งออกเป็นสองกลุ่ม - ข้อยกเว้นและข้อผิดพลาด ข้อผิดพลาด - JVM ใช้เพื่อแสดงข้อผิดพลาดหลังจากที่แอปพลิเคชันไม่สมเหตุสมผลอีกต่อไป ตัวอย่างเช่น StackOverFlowError ซึ่งบอกว่าสแต็กเต็มและโปรแกรมไม่สามารถทำงานได้อีกต่อไป ข้อยกเว้น - ข้อยกเว้นที่สร้างขึ้นโดยทางโปรแกรมในโค้ด มีข้อยกเว้นต่างๆ มากมาย ทั้งที่เลือกและไม่ถูกเลือก แต่สิ่งสำคัญคือมีอยู่จริง และสามารถตรวจจับได้ และแอปพลิเคชันสามารถทำงานได้ต่อไป ในทางกลับกัน ข้อยกเว้นจะถูกแบ่งออกเป็นส่วนที่สืบทอดมาจาก RuntimeException และลูกหลานของข้อยกเว้นอื่นๆ มีข้อมูลเพียงพอเกี่ยวกับปัญหานี้ เราจะพูดถึงข้อยกเว้นที่เลือก/ไม่ได้ตรวจสอบด้านล่าง
พิจารณาโปรแกรม Java ต่อไปนี้
คอลเลกชัน
25. Collections ใน Java หมายถึงอะไร?
คอลเลกชันเป็นเฟรมเวิร์กที่ออกแบบมาเพื่อจัดเก็บและจัดการออบเจ็กต์ ใช้เพื่อดำเนินการดังต่อไปนี้:- ค้นหา;
- การเรียงลำดับ;
- การจัดการ;
- ส่วนที่เพิ่มเข้าไป;
- การลบ
java.util
แพ็คเกจ
26. คลาสและอินเทอร์เฟซใดบ้างที่มีอยู่ในกรอบงานคอลเลกชัน?
อินเทอร์เฟซ:- ของสะสม;
- รายการ;
- ชุด;
- แผนที่;
- ชุดเรียง;
- แผนที่เรียงลำดับ;
- คิว.
- รายการ:
- อาร์เรย์รายการ;
- รายการที่เชื่อมโยง;
- เวกเตอร์(เลิกใช้แล้ว)
- ชุด:
- แฮชเซ็ต;
- LinkedHashSet;
- ทรีเซ็ต
- แผนที่:
- แฮชแมป
- ทรีแมป
- HashTable (เลิกใช้แล้ว)
- เชื่อมโยงHashMap
- คิว
- คิวลำดับความสำคัญ
27. การเรียงลำดับและเรียงลำดับในคอลเลกชันหมายถึงอะไร?
สั่งซื้อ:
ซึ่งหมายความว่ารายการที่ถูกเก็บไว้ในคอลเลกชันนั้นจะขึ้นอยู่กับค่าที่เพิ่มเข้าไปในคอลเลกชัน วิธีนี้ทำให้เราสามารถวนซ้ำค่าต่างๆ จากคอลเลคชันตามลำดับเฉพาะได้ กล่าวอีกนัยหนึ่ง นี่หมายความว่าองค์ประกอบของคอลเลกชันมีลำดับเฉพาะของตัวเองตามที่จัดเรียงไว้ เพื่อความเข้าใจที่ดีขึ้น คอลเลกชันที่ไม่ได้เรียงลำดับจะจัดเก็บองค์ประกอบต่างๆ ตามลำดับแบบสุ่ม ตัวอย่างเช่น ชุด.จัดเรียง:
ซึ่งหมายความว่ากลุ่มขององค์ประกอบจะถูกจัดเรียงเป็นคอลเลกชันตามข้อมูลขององค์ประกอบคอลเลกชัน นั่นคือ ไม่เพียงแต่การเรียงลำดับคอลเลกชันเท่านั้น แต่ยังรวมถึงลำดับขององค์ประกอบด้วยที่ขึ้นอยู่กับค่าของมันด้วย ลำดับนี้อาจเปลี่ยนแปลงได้หากคุณจัดเรียงตามค่าองค์ประกอบอื่น28. มีคอลเลกชันใดบ้างที่มีอินเทอร์เฟซรายการ? คุณร่วมงานกับลิสต์เป็นยังไงบ้าง?
ค่าขององค์ประกอบในชีตจะขึ้นอยู่กับดัชนี โดยเรียงลำดับตามดัชนี อนุญาตให้ทำซ้ำองค์ประกอบได้ (นั่นคือคุณสามารถเพิ่มวัตถุเดียวกันลงในคอลเลกชันได้หลายครั้งและจะไม่เป็นไร)รายการอาร์เรย์:
คอลเลกชันที่พบบ่อยที่สุด โดยพื้นฐานแล้ว มันคืออาร์เรย์ที่มีขนาดขยายแบบไดนามิก งานในการจัดการขนาดของอาเรย์ขึ้นอยู่กับคอลเลกชัน สิ่งสำคัญสำหรับเราคือต้องเข้าใจว่าโดยส่วนใหญ่นี่คือสิ่งที่เราจำเป็นต้องใช้ ลักษณะเฉพาะ:- ค้นหาอย่างรวดเร็วและค้นหาดัชนีอย่างรวดเร็ว
- คอลเลกชันเรียงลำดับตามดัชนี แต่ไม่ได้เรียงลำดับ
- ใช้อินเทอร์เฟซ RandomAccess
- ค่อย ๆ เพิ่มเข้าไปตรงกลางรายการ
public class A {
public static void main(String[] args) {
ArrayList names = new ArrayList<>();
names.add("John");
names.add("John");
names.add("Roman");
names.add("Ivan");
}
}
>> เอาท์พุท
[John, John, Roman, Ivan]
ผลลัพธ์แสดงให้เห็นว่าสิ่งเหล่านี้เป็นองค์ประกอบที่ทำซ้ำได้ โดยจะแสดงตามลำดับที่บันทึกไว้ มีอะไรให้อ่านอีกบ้าง? ใช่ มีข้อมูลมากมาย คุณไม่จำเป็นต้องออกจาก JavaRush ด้วยซ้ำ:
- การวิเคราะห์รายละเอียดของคลาส ArrayList
- คลาส ArrayList
- การทำงานของ ArrayList ในรูปภาพ
- ArrayList ใน Java
รายการที่เชื่อมโยง:
นี่คือคอลเลกชันที่แต่ละองค์ประกอบมีลิงก์ไปยังองค์ประกอบก่อนหน้าและถัดไป ลิงก์เหล่านี้ช่วยให้คุณสามารถย้ายจากองค์ประกอบหนึ่งไปยังอีกองค์ประกอบหนึ่งได้ เมื่อเพิ่มองค์ประกอบ ลิงก์ไปยังองค์ประกอบก่อนหน้าและถัดไปจะเปลี่ยนไป:
- องค์ประกอบเชื่อมต่อถึงกันนั่นคือมีการใช้รายการที่เชื่อมโยงสองเท่า
- ความเร็วโดยรวมของการทำงานต่ำกว่าใน ArrayList อย่างเห็นได้ชัด
- ตัวเลือกที่ยอดเยี่ยมสำหรับการแทรกและการลบจำนวนมากตรงกลางอาเรย์
- ใช้อินเทอร์เฟซรายการ Queue และ Deque ดังนั้นจึงมีวิธีการทำงาน
LinkedList<String> linkedList = new LinkedList<>();
linkedList.add("One");
linkedList.add("Two");
linkedList.add("Three");
29. บอกเราเกี่ยวกับคอลเลกชั่นแผนที่และการใช้งานของมันหน่อยสิ?
แผนที่เป็นคอลเล็กชันคีย์-ค่า มีคีย์เฉพาะและค่าที่ตรงกับค่านั้น วิธีการยัง ใช้เพื่อกำหนดเอกลักษณ์ของคีย์equals()
ด้วยhashcode()
แฮชแมป:
- ไม่เรียงลำดับหรือเรียงลำดับ;
- ใช้ถ้าลำดับและการเรียงลำดับไม่สำคัญ
- รองรับคีย์ว่าง
public class CollectionExample {
public static void main(String[] args) {
HashMap positions = new HashMap<>();
positions.put("junior", "Ivan");
positions.put("middle", "Roman");
positions.put("senior", "Vasily");
positions.put("team lead", "Anton");
positions.put("arthitect", "Andrew");
positions.put("senior", "John");
System.out.println(positions);
}
}
// вывод в консоль
// {junior=Ivan, middle=Roman, senior=John, team lead=Anton, arthitect=Andrew}
กุญแจจะไม่ซ้ำกันเสมอ ดังนั้นจึงมีการบันทึกผู้อาวุโสเพียงคนเดียวเท่านั้น
แผนที่แฮชที่เชื่อมโยง:
- รักษาลำดับการแทรก
- ช้ากว่า HashMap;
- คาดว่าการวนซ้ำจะเร็วกว่าใน HashMap
public class CollectionExample {
public static void main(String[] args) {
LinkedHashMap<String, String> positions = new LinkedHashMap<>();
positions.put("junior", "Ivan");
positions.put("middle", "Roman");
positions.put("senior", "Vasily");
positions.put("team lead", "Anton");
positions.put("arthitect", "Andrew");
positions.put("senior", "John");
System.out.println(positions);
}
}
// вывод в консоль
// {junior=Ivan, middle=Roman, senior=John, team lead=Anton, arthitect=Andrew}
แผนที่ต้นไม้:
การใช้งานแผนที่ที่เก็บรายการเรียงลำดับตามลำดับปกติของคีย์ หรือดีกว่านั้นโดยใช้ตัวเปรียบเทียบหากมีระบุไว้ใน Constructor เมื่อสร้างแผนที่ ตัวอย่าง:-
โดยไม่ต้องมีเครื่องเปรียบเทียบ
public class CollectionExample { public static void main(String[] args) { TreeMap<Integer, String> positions = new TreeMap<>(); positions.put(1, "Ivan"); positions.put(3, "Roman"); positions.put(2, "Vasily"); positions.put(10, "Anton"); positions.put(7, "Andrew"); positions.put(1, "John"); System.out.println(positions); } } // вывод в консоль // {1=John, 2=Vasily, 3=Roman, 7=Andrew, 10=Anton}
-
ด้วยเครื่องเปรียบเทียบ
public class CollectionExample { public static void main(String[] args) { //используем реализацию Strategy Pattern'a и добавим компаратор: TreeMap<Integer, String> positions = new TreeMap<>(Comparator.reverseOrder()); positions.put(1, "Ivan"); positions.put(3, "Roman"); positions.put(2, "Vasily"); positions.put(10, "Anton"); positions.put(7, "Andrew"); positions.put(1, "John"); System.out.println(positions); } } // вывод в консоль // {10=Anton, 7=Andrew, 3=Roman, 2=Vasily, 1=John}
30. บอกเราเกี่ยวกับ Set collection และการนำไปใช้งานหน่อยได้ไหม?
Set คือชุดขององค์ประกอบที่เป็นเอกลักษณ์ และนี่คือคุณสมบัติหลัก นั่นคือ Set ไม่อนุญาตให้มีองค์ประกอบเดียวกันซ้ำ สิ่งสำคัญที่นี่คือ อ อบเจ็กต์ที่เพิ่มจะต้องใช้วิธีการดำเนินการequals
ชุดแฮช:
- ไม่ได้เรียงลำดับหรือเรียงลำดับ ใต้ฝากระโปรงจะมี HashMap พร้อมตัวยึดตำแหน่งสำหรับค่า ดูด้วยตัวคุณเอง;)
- ใช้ hashCode เพื่อเพิ่มวัตถุ
- ควรใช้เมื่อคุณต้องการวัตถุที่ไม่ซ้ำใครและลำดับของวัตถุนั้นไม่สำคัญ
public class CollectionExample {
public static void main(String[] args) {
HashSet<String> positions = new HashSet<>();
positions.add("junior");
positions.add("junior");
positions.add("middle");
positions.add("senior");
positions.add("team lead");
positions.add("architect");
System.out.println(positions);
}
}
// вывод в консоль
// [senior, middle, team lead, architect, junior]
ที่นี่คุณจะเห็นว่าองค์ประกอบ "จูเนียร์" ซึ่งเพิ่มเข้ามาสองครั้งนั้นปรากฏอยู่ในอินสแตนซ์เดียวเท่านั้น และลำดับไม่เหมือนกับตอนบวก
ชุดแฮชที่เชื่อมโยง:
- เวอร์ชันที่สั่งของ HashSet;
- รองรับรายการเชื่อมโยงสองเท่าสำหรับองค์ประกอบทั้งหมด
- ใช้เมื่อต้องการความเป็นระเบียบในระหว่างการทำซ้ำ
public class CollectionExample {
public static void main(String[] args) {
LinkedHashSet<String> positions = new LinkedHashSet<>();
positions.add("junior");
positions.add("junior");
positions.add("middle");
positions.add("senior");
positions.add("team lead");
positions.add("architect");
System.out.println(positions);
}
}
// вывод в консоль
// [senior, middle, team lead, architect, junior]
ชุดต้นไม้:
- หนึ่งในสองคอลเลกชันที่เรียงลำดับ;
- ใช้ โครงสร้าง ต้นไม้สีแดงดำและตรวจสอบให้แน่ใจว่าองค์ประกอบต่างๆ เรียงลำดับจากน้อยไปมาก
- ภายใต้ประทุนมันเป็น TreeMap ที่มีส่วนต่อค่าต่างๆ และองค์ประกอบของ TreeSet คือกุญแจสำคัญใน TreeMap (ดูเพิ่มเติม ;))
public class CollectionExample {
public static void main(String[] args) {
TreeSet<String> positions = new TreeSet<>();
positions.add("junior");
positions.add("junior");
positions.add("middle");
positions.add("senior");
positions.add("team lead");
positions.add("architect");
System.out.println(positions);
}
}
// вывод в консоль
// [architect, junior, middle, senior, team lead]
ข้อยกเว้น
31. ข้อยกเว้นคืออะไร?
ข้อยกเว้นคือปัญหาที่อาจเกิดขึ้นขณะรันไทม์ นี่เป็น สถานการณ์ พิเศษที่เกิดขึ้นเนื่องจากสาเหตุบางประการ แผนภาพการสืบทอดข้อยกเว้นมีลักษณะดังนี้ (คุณต้องรู้ด้วยใจ ;)):
32. JVM จัดการกับข้อยกเว้นอย่างไร?
มันทำงานอย่างไร? ทันทีที่มีข้อยกเว้นเกิดขึ้นที่ไหนสักแห่ง รันไทม์จะสร้างวัตถุข้อยกเว้น (แสดงเป็น ExcObj) เก็บข้อมูลทั้งหมดที่จำเป็นสำหรับการทำงาน - ข้อยกเว้นที่เกิดขึ้นและสถานที่ที่เกิดขึ้น การสร้างExcObj
และการส่งผ่านไปยังรันไทม์นั้นไม่มีอะไรมากไปกว่า “การทิ้งข้อยกเว้น” ExcObj
มีวิธีการที่สามารถใช้เพื่อไปยังตำแหน่งที่เกิดข้อยกเว้น ชุดวิธีการนี้เรียกว่า Call Stack ถัดไป ระบบรันไทม์จะค้นหาวิธีการใน Call Stack ที่สามารถจัดการข้อยกเว้นของเราได้ หากไม่พบตัวจัดการที่เกี่ยวข้อง นั่นคือประเภทข้อยกเว้นตรงกับประเภทในตัวจัดการ ทุกอย่างก็เรียบร้อยดี หากไม่พบ รันไทม์จะส่งทุกอย่างไปยังตัวจัดการข้อยกเว้นเริ่มต้น ซึ่งจะเตรียมการตอบกลับและออก มันดูเป็นอย่างไร:
/**
* Пример, в котором показываются две опции — когда находится обработчик для исключения и когда нет.
*/
class ThrowerExceptionExample {
public static void main(String[] args) throws IllegalAccessException {
ThrowerExceptionExample example = new ThrowerExceptionExample();
System.out.println(example.populateString());
}
/**
* Здесь происходит перехват одного из возможных исключений — {@link IOException}.
* А вот второй будет пробрасываться дальше вверх по вызову.
*/
private String populateString() throws IllegalAccessException {
try {
return randomThrower();
} catch (IOException e) {
return "Caught IOException";
}
}
/**
* Здесь две опции: or бросается {@link IOException} or {@link IllegalAccessException}.
* Выбирается случайным образом.
*/
private String randomThrower() throws IOException, IllegalAccessException {
if (new Random().nextBoolean()) {
throw new IOException();
} else {
throw new IllegalAccessException();
}
}
}
ในกรณีของเรา CallStack จะมีลักษณะตามแผนผังดังนี้:
randomThrower() => populateString() => main(String[] args)
มีสองตัวเลือก: ข้อยกเว้นอย่างใดอย่างหนึ่งจะถูกส่งแบบสุ่ม สำหรับ IOException ทุกอย่างก็โอเค หากสร้างขึ้น ผลลัพธ์ของงานจะเป็น"Caught IOException"
: แต่หากมีข้อยกเว้นประการที่สองซึ่งไม่มีตัวจัดการ โปรแกรมจะหยุดทำงานด้วยเอาต์พุตต่อไปนี้:
Exception in thread "main" java.lang.IllegalAccessException
at ThrowerExceptionExample.randomThrower(CollectionExample.java:38)
at ThrowerExceptionExample.populateString(CollectionExample.java:24)
at ThrowerExceptionExample.main(CollectionExample.java:15)
33. โปรแกรมเมอร์จัดการกับข้อยกเว้นอย่างไร?
ในคำถามข้างต้น เราได้ใช้คำหลักบางคำเพื่อทำงานกับข้อยกเว้นแล้ว ตอนนี้เราจำเป็นต้องพูดถึงคำหลักเหล่านั้นโดยละเอียดมากขึ้น คำหลักคืออะไร?- พยายาม
- จับ
- โยน
- พ่น
- ในที่สุด
try-catch-finally
เป็นโครงสร้างที่ช่วยให้คุณสามารถจับและจัดการข้อยกเว้นได้อย่างถูกต้องtry
- มีได้เพียงครั้งเดียวเท่านั้น นั่นคือสิ่งที่ตรรกะเกิดขึ้นcatch
— บล็อกที่ได้รับข้อยกเว้นบางประเภท อาจมีได้หลายรายการ ตัวอย่างเช่น try block จะส่งข้อยกเว้นหลายประการที่ไม่เกี่ยวข้องกันfinally
- "ในที่สุด" บล็อกนี้ นี่คือบล็อกที่จะดำเนินการในทุกกรณี โดยไม่คำนึงถึงสิ่งที่ทำใน try, catch
try {
// сюда передают тот code, который может вызвать исключение.
} catch (IOException e) {
// первый catch блок, который принимает IOException и все его подтипы(потомки).
// Например, нет file при чтении, выпадает FileNotFoundException, и мы уже соответствующе
// обрабатываем это.
} catch (IllegalAccessException e) {
// если нужно, можно добавить больше одного catch блока, в этом нет проблем.
} catch (OneException | TwoException e) {
// можно даже объединять несколько в один блок
} catch (Throwable t) {
// а можно сказать, что мы принимаем ВСЁ))))
} finally {
// этот блок может быть, а может и не быть.
// и он точно выполнится.
}
อ่านคำอธิบายตัวอย่างอย่างละเอียดแล้วทุกอย่างจะชัดเจน)
34. โยนและโยนใน Java
โยน
throw
ใช้เมื่อคุณต้องการสร้างข้อยกเว้นใหม่อย่างชัดเจน มันถูกใช้เพื่อสร้างและโยนข้อยกเว้นแบบกำหนดเอง ตัวอย่างเช่น ข้อยกเว้นที่เกี่ยวข้องกับการตรวจสอบความถูกต้อง โดยปกติแล้ว สำหรับการตรวจสอบความถูกต้อง พวกมันจะสืบทอดมาจากRuntimeException
. ตัวอย่าง:
// пример пробрасывания исключения
throw new RuntimeException("because I can :D");
สิ่งสำคัญคือโครงสร้างนี้สามารถใช้ได้โดยสิ่งที่สืบทอดมาจากThrowable
. นั่นคือคุณไม่สามารถพูดสิ่งนี้ได้:
throw new String("How тебе такое, Илон Маск?");
ถัดไป งานของเธรดจะสิ้นสุดลง และการค้นหาตัวจัดการที่สามารถประมวลผลจะเริ่มต้นขึ้น เมื่อไม่พบ ระบบจะไปที่เมธอดที่เรียก จากนั้นการค้นหาจะขยายไปตามสายการโทรจนกว่าจะพบตัวจัดการที่เกี่ยวข้องหรือปล่อยให้แอปพลิเคชันทำงานต่อไป มาดูกัน:
// Пример, который демонстрирует работу throw
class ThrowExample {
void willThrow() throws IOException {
throw new IOException("Because I Can!");
}
void doSomething() {
System.out.println("Doing something");
try {
willThrow();
} catch (IOException e) {
System.out.println("IOException was successfully handled.");
}
}
public static void main(String args[]) {
ThrowExample throwExample = new ThrowExample();
throwExample.doSomething();
}
}
ถ้าเรารันโปรแกรมเราจะได้ผลลัพธ์ดังนี้:
Doing something
IOException was successfully handled.
พ่น
throws
- กลไกที่เมธอดสามารถส่งข้อยกเว้นตั้งแต่หนึ่งรายการขึ้นไป โดยคั่นด้วยเครื่องหมายจุลภาค มาดูกันว่าง่ายและสะดวกแค่ไหน:
private Object willThrow() throws RuntimeException, IOException, FileNotFoundException
นอกจากนี้ สิ่งสำคัญคือต้องทราบว่ามีทั้งข้อยกเว้นที่ถูกตรวจสอบและไม่ถูกตรวจสอบ แน่นอนว่าไม่สามารถเพิ่มข้อยกเว้นที่ไม่ได้ตรวจสอบลงใน ได้throws
แต่มารยาทที่ดีจะระบุไว้เป็นอย่างอื่น หากสิ่งเหล่านี้สามารถตรวจสอบได้ คุณจะต้องดำเนินการด้วยวิธีใดวิธีหนึ่งโดยใช้วิธีที่สร้างขึ้น มีสองตัวเลือก:
- เขียน
try-catch
ด้วยข้อยกเว้นการสืบทอดที่เหมาะสมและสูงกว่า - ใช้มัน
throws
ในลักษณะเดียวกันเพื่อให้คนอื่นประสบปัญหานี้อยู่แล้ว :D
35. ข้อยกเว้นที่ถูกตรวจสอบและไม่ถูกตรวจสอบใน Java
มีข้อยกเว้นสองประเภทใน Java - เลือกและยกเลิกการเลือกตรวจสอบข้อยกเว้น:
สิ่งเหล่านี้เป็นข้อยกเว้นที่ถูกตรวจสอบ ณ เวลาคอมไพล์ หากโค้ดบางโค้ดในเมธอดส่งข้อยกเว้นที่เลือกระหว่างข้อยกเว้น เมธอดนั้นจะต้องประมวลผลโดยใช้try-catch
หรือส่งต่อต่อไป ตัวอย่างเช่น ซึ่งอ่านรูปภาพจากพาธ "/users/romankh3/image.png" ให้อัปเดตโค้ดนั้น ในทางใดทางหนึ่ง (สำหรับเราสิ่งนี้ไม่สำคัญ) และบันทึกกลับคืนมา
class CheckedImageExample {
public static void main(String[] args) {
File imageFile = new File("/users/romankh3/image.png");
BufferedImage image = ImageIO.read(imageFile);
updateAndSaveImage(image, imageFile);
}
private static void updateAndSaveImage(BufferedImage image, File imageFile) {
ImageIO.write(image, "png", imageFile);
}
}
รหัสดังกล่าวจะไม่คอมไพล์ เนื่องจากวิธีการแบบสแตติกImageIO.read()
ส่งImageIO.write()
IOException ซึ่งได้รับการตรวจสอบและจะต้องได้รับการจัดการตามนั้น มีสองตัวเลือกที่เราได้กล่าวถึงข้างต้นแล้ว: ใช้try-catch
หรือส่งต่อเพิ่มเติม เพื่อการดูดซึมที่ดีขึ้น เราจะทำสิ่งนี้และสิ่งนั้น นั่นคือupdateAndSave
เราจะส่งต่อในวิธีการแล้วใช้ในวิธีหลักtry-catch
:
class CheckedImageExample {
public static void main(String[] args) {
File imageFile = new File("/users/romankh3/image.png");
try {
BufferedImage image = ImageIO.read(imageFile);
updateAndSaveImage(image, imageFile);
} catch (IOException e) {
e.printStackTrace();
}
}
private static void updateAndSaveImage(BufferedImage image, File imageFile) throws IOException {
ImageIO.write(image, "png", imageFile);
}
}
ข้อยกเว้นที่ไม่ได้ตรวจสอบ:
สิ่งเหล่านี้เป็นข้อยกเว้นที่ไม่ได้ตรวจสอบในขั้นตอนการคอมไพล์ นั่นคือเมธอดสามารถสร้าง RuntimeException ได้ แต่คอมไพเลอร์จะไม่เตือนให้คุณจัดการด้วยวิธีใดวิธีหนึ่ง ดังที่แสดงด้านล่าง เรามีทุกสิ่งที่สืบทอดมาจาก RuntimeException และข้อผิดพลาดจะไม่ถูกเลือก
ArrayIndexOutOfBoundsException
รหัสคอมไพ ล์ได้ดี แต่จะเกิดข้อยกเว้นเมื่อเรียกใช้ คอมไพเลอร์อนุญาตให้คอมไพล์ได้เนื่องจากArrayIndexOutOfBoundsException
เป็นข้อยกเว้นที่ไม่ได้ตรวจสอบ สถานการณ์ทั่วไปกับอาร์เรย์ซึ่งอาจเป็น:
class CheckedImageExample {
public static void main(String[] args) {
int[] array = new int[3];
array[5] = 12;
}
}
ผลลัพธ์จะเป็น:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
at main(CheckedImageExample.java:12)
คุณสังเกตไหมว่าใน Java ไม่มีใครตั้งชื่อสั้น ๆ ? ใหญ่กว่าดีกว่า. Spring Framework เขาประสบความสำเร็จอย่างมากในเรื่องนี้: เพียงแค่ใช้ คลาส BeanFactoryPostProcessor )))
36. การลองใช้ทรัพยากรคืออะไร?
นี่เป็นกลไกที่ต้องปิดทรัพยากรทั้งหมดอย่างถูกต้อง ยังไม่ชัดเจนใช่ไหม) ก่อนอื่นเลย ทรัพยากรคืออะไร... ทรัพยากรคือวัตถุ หลังจากทำงานด้วยซึ่งคุณต้องปิดมัน นั่นคือ เรียกไฟล์close()
. ทรัพยากรคือออบเจ็กต์ทั้งหมดที่ใช้อินเทอร์เฟซ ซึ่งในทางกลับกัน จะAutoClosable
ใช้อินเทอร์เฟซ Closeable
เป็นสิ่งสำคัญสำหรับเราที่จะเข้าใจว่าทุกอย่างInputStream
เป็นOutpuStream
ทรัพยากรและจำเป็นต้องได้รับการเผยแพร่อย่างถูกต้องและประสบความสำเร็จ นี่คือเหตุผลว่าทำไมเราจึงต้องใช้try-with-resource
โครงสร้าง นี่คือสิ่งที่ดูเหมือน:
private void unzipFile(File zipFile) throws IOException {
try(ZipInputStream zipOutputStream = new ZipInputStream(new FileInputStream(zipFile))) {
ZipEntry zipEntry = zipOutputStream.getNextEntry();
while (zipEntry != null) {
}
}
}
private void saveZipEntry(ZipEntry zipEntry) {
// логика сохранения
}
ในตัวอย่างนี้ ทรัพยากรคือZipInputStream
หลังจากที่ทำงานด้วยแล้ว คุณจะต้องปิดมัน และเพื่อไม่ให้คิดถึงการเรียกใช้เมธอดclose()
เราเพียงแค่กำหนดตัวแปรนี้ในบล็อก try ดังที่แสดงในตัวอย่าง และภายในบล็อกนี้ เราจะทำทุกอย่างที่จำเป็น ตัวอย่างมีไว้ทำอะไร? มันจะคลายซิปไฟล์ zip เมื่อต้องการทำเช่นนี้ คุณต้องใช้InputStream
'om คุณสามารถกำหนดตัวแปรได้มากกว่าหนึ่งตัวแปร โดยคั่นด้วยเครื่องหมายอัฒภาค มีปัญหาอะไร? แต่คุณสามารถใช้finally
บล็อกได้คุณอาจพูดได้ นี่คือบทความที่ให้รายละเอียดปัญหาเกี่ยวกับวิธีการนี้ นอกจากนี้ยังอธิบายรายการความล้มเหลวทั้งหมดที่อาจเกิดขึ้นกับผู้ที่ละเลยการใช้การออกแบบนี้ แนะนำให้อ่านครับ ;) ในส่วนสุดท้ายมีคำถาม/คำตอบในหัวข้อ Multithreading ครับ โปรไฟล์ GitHub ของฉัน
GO TO FULL VERSION