Các câu lệnh chuyển đổi với String
các trường hợp đã được triển khai trong Java SE 7 , ít nhất 16 năm sau khi chúng được yêu cầu lần đầu tiên. Một lý do rõ ràng cho sự chậm trễ không được cung cấp, nhưng nó có thể phải làm với hiệu suất.
Triển khai trong JDK 7
Tính năng này hiện đã được triển khai trong javac
quy trình "khử đường"; một cú pháp cấp cao, rõ ràng bằng cách sử dụng các String
hằng số trong các case
khai báo được mở rộng tại thời gian biên dịch thành mã phức tạp hơn theo một mẫu. Mã kết quả sử dụng các hướng dẫn JVM luôn tồn tại.
A switch
với String
các trường hợp được dịch thành hai công tắc trong quá trình biên dịch. Đầu tiên ánh xạ mỗi chuỗi thành một số nguyên duy nhất, vị trí của nó trong công tắc ban đầu. Điều này được thực hiện bằng cách chuyển đổi đầu tiên trên mã băm của nhãn. Trường hợp tương ứng là một if
câu lệnh kiểm tra sự bằng nhau của chuỗi; nếu có va chạm trên hàm băm, thử nghiệm là một tầng if-else-if
. Công tắc thứ hai phản ánh rằng trong mã nguồn ban đầu, nhưng thay thế nhãn trường hợp bằng các vị trí tương ứng của chúng. Quy trình hai bước này giúp bạn dễ dàng duy trì kiểm soát dòng chảy của công tắc ban đầu.
Chuyển đổi trong JVM
Để biết thêm về kỹ thuật switch
, bạn có thể tham khảo Đặc tả JVM, trong đó việc biên dịch các câu lệnh chuyển đổi được mô tả. Tóm lại, có hai hướng dẫn JVM khác nhau có thể được sử dụng cho một công tắc, tùy thuộc vào độ thưa của các hằng số được sử dụng trong các trường hợp. Cả hai đều phụ thuộc vào việc sử dụng hằng số nguyên cho từng trường hợp để thực thi hiệu quả.
Nếu các hằng số dày đặc, chúng được sử dụng như một chỉ mục (sau khi trừ đi giá trị thấp nhất) vào một bảng các con trỏ tableswitch
lệnh Hướng dẫn lệnh.
Nếu các hằng số thưa thớt, việc tìm kiếm nhị phân cho trường hợp chính xác được thực hiện theo lookupswitch
hướng dẫn.
Trong khử đường a switch
trên String
các đối tượng, cả hai hướng dẫn có khả năng được sử dụng. Điều lookupswitch
này phù hợp cho việc chuyển đổi đầu tiên trên mã băm để tìm vị trí ban đầu của vụ án. Các thứ tự kết quả là một phù hợp tự nhiên cho a tableswitch
.
Cả hai hướng dẫn đều yêu cầu các hằng số nguyên được gán cho từng trường hợp được sắp xếp tại thời điểm biên dịch. Trong thời gian chạy, mặc dù O(1)
hiệu năng tableswitch
thường xuất hiện tốt hơn O(log(n))
hiệu năng của lookupswitch
nó, nó đòi hỏi một số phân tích để xác định xem bảng có đủ dày đặc để biện minh cho sự đánh đổi thời gian của Space không. Bill Venners đã viết một bài viết tuyệt vời bao gồm chi tiết này, cùng với cái nhìn sâu sắc về các hướng dẫn kiểm soát luồng Java khác.
Trước JDK 7
Trước JDK 7, enum
có thể xấp xỉ một String
công tắc dựa trên cơ sở. Điều này sử dụng phương thức tĩnhvalueOf
được tạo bởi trình biên dịch trên mọi enum
loại. Ví dụ:
Pill p = Pill.valueOf(str);
switch(p) {
case RED: pop(); break;
case BLUE: push(); break;
}