2009-04-08 41 views
14

Tôi có một phương pháp hữu ích và khi logic không liên quan được lấy ra từ nó, phương pháp đơn giản sẽ trông như thế này:Instantiating một lớp bên trong

public static <A extends Foo> List<A> getFooList(Class<A> clazz) { 
    List<A> returnValue = new ArrayList<A>(); 
    for(int i=0; i < 5; i++) { 
     A object = clazz.newInstance(); 
     returnValue.add(object); 
    } 

    return returnValue; 
} 

Vấn đề là, rằng nếu clazz là một lớp bên trong như Foo.Bar.class , sau đó phương thức newInstance() sẽ không hoạt động ngay cả khi Bar sẽ công khai, vì nó sẽ ném một số java.lang.InstantiationException.

Có cách nào để tự động khởi tạo các lớp bên trong không?

Trả lời

27

Nếu đó là thực sự một lớp nội thay vì một lồng nhau (tĩnh) lớp , có một tham số constructor ngầm, đó là tham chiếu đến thể hiện của các lớp bên ngoài. Bạn không thể sử dụng Class.newInstance ở giai đoạn đó - bạn phải có được hàm tạo thích hợp. Dưới đây là ví dụ:

import java.lang.reflect.*; 

class Test 
{ 
    public static void main(String[] args) throws Exception 
    { 
     Class<Outer.Inner> clazz = Outer.Inner.class; 

     Constructor<Outer.Inner> ctor = clazz.getConstructor(Outer.class); 

     Outer outer = new Outer(); 
     Outer.Inner instance = ctor.newInstance(outer); 
    } 
} 

class Outer 
{ 
    class Inner 
    { 
     // getConstructor only returns a public constructor. If you need 
     // non-public ones, use getDeclaredConstructors 
     public Inner() {} 
    } 
} 
0

Ngoại lệ này sẽ chỉ được ném nếu clazz đại diện cho lớp trừu tượng hoặc giao diện. Bạn có chắc là bạn đang truyền một đối tượng Lớp đại diện cho một lớp cụ thể không?

5

Something chung chung hơn:

public static <T> T createInstance(final Class<T> clazz) throws SecurityException, NoSuchMethodException, 
      IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException { 

      T instanceToReturn = null; 
      Class<?> enclosingClass = clazz.getEnclosingClass(); 

      if (enclosingClass != null) { 
       Object instanceOfEnclosingClass = createInstance(enclosingClass); 

       Constructor<T> ctor = clazz.getConstructor(enclosingClass); 

       if (ctor != null) { 
        instanceToReturn = ctor.newInstance(instanceOfEnclosingClass); 
       } 
      } else { 
       instanceToReturn = clazz.newInstance(); 
      } 

      return instanceToReturn; 
    } 
+0

Bạn vẫn cần phải kiểm tra xem lớp bên trong không phải là tĩnh ... – Corin

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