2011-02-04 22 views
32

Nếu tôi có một thể hiện của Class, có cách nào để lấy một cá thể Class cho loại mảng của nó không? Những gì tôi đang về cơ bản yêu cầu là tương đương với một phương pháp getArrayType đó là nghịch đảo của phương pháp getComponentType(), chẳng hạn rằng:Lấy mảng Lớp của một loại thành phần

array.getClass().getComponentType().getArrayType() == array.getClass() 

Trả lời

43

Một điều mà nói đến cái tâm là:

java.lang.reflect.Array.newInstance(componentType, 0).getClass(); 

Nhưng nó tạo ra một thể hiện không cần thiết.

Btw, điều này dường như làm việc:

Class clazz = Class.forName("[L" + componentType.getName() + ";"); 

Đây là thử nghiệm. Nó in true:

Integer[] ar = new Integer[1]; 
Class componentType = ar.getClass().getComponentType(); 
Class clazz = Class.forName("[L" + componentType.getName() + ";"); 

System.out.println(clazz == ar.getClass()); 

The documentation of Class#getName() xác định đúng định dạng của tên lớp mảng:

Nếu đối tượng lớp này đại diện cho một lớp học của các mảng, sau đó các hình thức nội bộ của tên bao gồm tên của loại phần tử đứng trước một hoặc nhiều ký tự '[' đại diện cho độ sâu của mảng làm tổ.

Cách tiếp cận Class.forName(..) sẽ không làm việc trực tiếp với nguyên thủy mặc dù - cho họ biết bạn sẽ phải tạo ra một ánh xạ giữa tên (int) và viết tắt mảng - (I)

+0

Trang đầu tiên rsion (sử dụng 'Array.newInstance (...). getClass()') * làm * làm việc cho các nguyên thủy. – finnw

+0

vâng, quan điểm của tôi là thứ hai sẽ không. – Bozho

+0

Điều này rất hữu ích, cảm ơn. Vì mục đích của tôi, tôi không cần phải xử lý nguyên thủy để có thể sử dụng được cách tiếp cận. –

6

Bạn có thể làm như sau

array.getClass() == 
    Array.newInstance(array.getClass().getComponentType(), 0).getClass() 

Thông thường, bạn don' t cần phải biết loại, bạn chỉ muốn tạo mảng.

1

Một refactoring có thể là sử dụng một superclass chung và truyền vào hai đối tượng lớp cho hàm tạo.

protected AbstractMetaProperty(Class<T> valueClass, Class<T[]> valueArrayClass) { 
    this.valueClass = valueClass; 
    this.valueArrayClass = valueArrayClass; 
} 

Sau đó, trong lớp con:

public IntegerClass() { 
    super(Integer.class, Integer[].class); 
} 

Sau đó, trong lớp trừu tượng, bạn có thể sử dụng valueClass.cast(x), valueArrayClass.isInstance(x), vv

9

Trên thực tế do ClassLoader, nguyên thủy và mảng đa chiều, câu trả lời là phức tạp hơn một chút:

public static Class<?> getArrayClass(Class<?> componentType) throws ClassNotFoundException{ 
    ClassLoader classLoader = componentType.getClassLoader(); 
    String name; 
    if(componentType.isArray()){ 
     // just add a leading "[" 
     name = "["+componentType.getName(); 
    }else if(componentType == boolean.class){ 
     name = "[Z"; 
    }else if(componentType == byte.class){ 
     name = "[B"; 
    }else if(componentType == char.class){ 
     name = "[C"; 
    }else if(componentType == double.class){ 
     name = "[D"; 
    }else if(componentType == float.class){ 
     name = "[F"; 
    }else if(componentType == int.class){ 
     name = "[I"; 
    }else if(componentType == long.class){ 
     name = "[J"; 
    }else if(componentType == short.class){ 
     name = "[S"; 
    }else{ 
     // must be an object non-array class 
     name = "[L"+componentType.getName()+";"; 
    } 
    return classLoader != null ? classLoader.loadClass(name) : Class.forName(name); 
} 
+1

Trong dòng cuối cùng, bạn cũng có thể sử dụng phương thức forName với tham số trình nạp lớp (cũng làm việc cho 'null', do đó tránh sự phân biệt chữ hoa chữ thường). –

Các vấn đề liên quan