Có sự khác biệt về sở thích hoặc hành vi giữa việc sử dụng:
if(obj.getClass().isArray()) {}
và
if(obj instanceof Object[]) {}
?
Có sự khác biệt về sở thích hoặc hành vi giữa việc sử dụng:
if(obj.getClass().isArray()) {}
và
if(obj instanceof Object[]) {}
?
Câu trả lời:
Trong hầu hết các trường hợp, bạn nên sử dụng instanceof
toán tử để kiểm tra xem một đối tượng có phải là một mảng hay không.
Nói chung, bạn kiểm tra loại đối tượng trước khi chuyển sang loại cụ thể được biết đến tại thời điểm biên dịch. Ví dụ, có lẽ bạn đã viết một số mã có thể làm việc với một Integer[]
hoặc một int[]
. Bạn muốn bảo vệ dàn diễn viên của mình với instanceof
:
if (obj instanceof Integer[]) {
Integer[] array = (Integer[]) obj;
/* Use the boxed array */
} else if (obj instanceof int[]) {
int[] array = (int[]) obj;
/* Use the primitive array */
} else ...
Ở mức JVM, instanceof
toán tử chuyển thành mã byte "instanceof" cụ thể , được tối ưu hóa trong hầu hết các triển khai JVM.
Trong các trường hợp hiếm hơn, bạn có thể sử dụng sự phản chiếu để duyệt qua biểu đồ đối tượng của các loại không xác định. Trong những trường hợp như thế này, isArray()
phương pháp có thể hữu ích vì bạn không biết loại thành phần tại thời điểm biên dịch; ví dụ, bạn có thể thực hiện một số loại cơ chế tuần tự hóa và có thể truyền từng thành phần của mảng cho cùng một phương thức tuần tự hóa, bất kể loại nào.
Có hai trường hợp đặc biệt: tham chiếu null và tham chiếu đến mảng nguyên thủy.
Một tham chiếu null sẽ gây ra instanceof
kết quả false
, trong khi isArray
ném a NullPointerException
.
Áp dụng cho một mảng nguyên thủy, instanceof
sản lượng false
trừ khi loại thành phần trên toán hạng bên phải khớp chính xác với loại thành phần. Ngược lại, isArray()
sẽ trả về true
cho bất kỳ loại thành phần.
obj instanceof int[]
mang lại lợi nhuận false
khi bạn gán int[]
cho obj
, bạn đã nhầm.
obj instanceof Object[]
năng suất false
nếu Object obj = new int[7]
.
java.lang.Object
, vì vậy điều đó có ý nghĩa. Nhưng instanceof
vẫn có thể được sử dụng để kiểm tra các mảng nguyên thủy.
isArray()
nên được sử dụng. Trong trường hợp không đặc biệt chung là chỉ có mảng các đối tượng, instanceof
cung cấp một sự thay thế hiệu suất cao.
Nếu obj
là kiểu int[]
nói, thì nó sẽ có một mảng Class
nhưng không phải là một thể hiện của Object[]
. Vậy bạn muốn làm gì với obj
. Nếu bạn sẽ đúc nó, đi với instanceof
. Nếu bạn sẽ sử dụng sự phản chiếu, sau đó sử dụng .getClass().isArray()
.
getClass().isArray()
chậm hơn đáng kể trên Sun Java 5 hoặc 6 JRE so với trên IBM.
Quá nhiều việc sử dụng clazz.getName().charAt(0) == '['
nhanh hơn trên Sun JVM.
Gần đây tôi đã gặp phải một vấn đề khi nâng cấp ứng dụng Groovy từ JDK 5 lên JDK 6. Sử dụng isArray()
thất bại trong JDK6:
MissingMethodException:
No signature of sun.reflect.generics.reflectiveObjects.GenericArrayTypeImpl.isArray() ...
Thay đổi để instanceof Object[]
sửa lỗi này.
isArray
là một phương pháp Class
, không Type
, vì vậy tất nhiên GenericArrayTypeImpl
không có phương pháp đó. Và getClass
không bao giờ có thể trả lại một người không Class
Type
, vì vậy bạn (hoặc Groovy ??) phải làm điều gì đó sai để có được điều này, như giả sử mọi thứ Type
là a Class
.
Phản chiếu mảng Java dành cho các trường hợp bạn không có phiên bản Class có sẵn để thực hiện "instanceof". Ví dụ: nếu bạn đang viết một số khung công tác tiêm, tiêm các giá trị vào một thể hiện mới của một lớp, chẳng hạn như JPA, thì bạn cần sử dụng chức năng isArray ().
Tôi viết blog về điều này sớm hơn vào tháng 12. http://blog.adamsbros.org/2010/12/08/java-array-reflection/
Nếu bạn có lựa chọn giữa giải pháp phản chiếu và giải pháp không phản chiếu, không bao giờ chọn giải pháp phản chiếu (liên quan đến các đối tượng Class). Không phải là "Sai" hay bất cứ điều gì, nhưng bất cứ điều gì liên quan đến sự phản chiếu thường không rõ ràng và ít rõ ràng hơn.
Không có sự khác biệt trong hành vi mà tôi có thể tìm thấy giữa hai người (trừ trường hợp null rõ ràng). Đối với phiên bản nào thích hơn, tôi sẽ đi với phiên bản thứ hai. Đây là cách tiêu chuẩn để làm điều này trong Java.
Nếu nó gây nhầm lẫn cho người đọc mã của bạn (vì String[] instanceof Object[]
là đúng), bạn có thể muốn sử dụng mã đầu tiên để rõ ràng hơn nếu người đánh giá mã tiếp tục hỏi về mã đó.