2012-02-06 47 views
6

Tôi đang gọi một phương thức bằng cách phản ánh và kiểu trả về của nó là chung chung. Tôi không muốn giá trị trả về là null, vì vậy tôi trong trường hợp đó tôi muốn gán giá trị mặc định của loại chung đó.Gán một giá trị mặc định cho một số chung là

Đó là, sau gọi phương thức bằng cách phản chiếu, tôi muốn thực hiện một cái gì đó như thế này:

T resultNotNull = (T) reflectionMethodThatCanReturnNull.invoke(anObject); 
// If it's null, let's assign something assignable. 
if (resultNotNull == null) { 
    if (resultNotNull.getClass().isAssignableFrom(Long.class)) { 
     resultNotNull = (T) Long.valueOf(-1); 
    } else if (resultNotNull.getClass().isAssignableFrom(String.class)) { 
     resultNotNull = (T) "NOTHING"; 
    } 
} 

Nhưng, tất nhiên, nếu 'resultNotNull == null', chúng ta không thể gọi 'resultNotNull.getClass()' mà không bị ngoại lệ.

Bất kỳ ý tưởng nào về cách gán giá trị mặc định tùy thuộc vào loại chung chung?

Toàn bộ code sẽ là một cái gì đó như thế này:

public class ReflectionTest { 
    public class Class1ok { 
     public Long method() { return Long.valueOf(1); } 
    } 
    public class Class1null { 
     public Long method() { return null; } // It returns null 
    } 
    public class Class2ok { 
     public String method() { return "SOMETHING"; } 
    } 

    public static void main(String[] args) { 
     ReflectionTest test = new ReflectionTest(); 

     Long notNullValue1 
      = test.methodReturnNotNull(Class1ok.class); // 1 
     Long notNullValue2 
      = test.methodReturnNotNull(Class1null.class); // -1, not null 
     String notNullValue3 
      = test.methodReturnNotNull(Class2ok.class); // "SOMETHING" 
    } 

    public <T> T methodReturnNotNull(Class theClass) { 
     T resultNotNull = null; 
     try { 
      Object theObject = theClass.newInstance(); 
      Method methodThatCanReturnNull = theClass.getMethod("method"); 
      resultNotNull = (T) methodThatCanReturnNull.invoke(theObject); 
     } catch (Exception e) { 
      // Meh. 
     } 

     // If it's null, assign something assignable. 
     if (resultNotNull == null) { 
      if (resultNotNull.getClass().isAssignableFrom(Long.class)) { 
       resultNotNull = (T) Long.valueOf(-1); 
      } else if (resultNotNull.getClass().isAssignableFrom(String.class)) { 
       resultNotNull = (T) "NOTHING"; 
      } 
     } 
     return resultNotNull; 
    } 
} 

Trả lời

3

Bạn có thể sử dụng getReturnType();

private static final Map<Class, Object> replacementForNull = new HashMap<>(); 
static { 
    replacementForNull.put(String.class, "NOTHING"); 
    replacementForNull.put(Long.class, 1L); 
} 


Method reflectionMethodThatCanReturnNull = ... 
T resultNotNull = (T) reflectionMethodThatCanReturnNull.invoke(anObject); 
// If it's null, let's assign something assignable. 
if (resultNotNull == null) { 
    Class returnType = reflectionMethodThatCanReturnNull.getReturnType(); 
    resultNotNull = replacementForNull.get(returnType); 
} 
+0

Không getReturnType() trả về Object? Generics được xóa tại thời gian biên dịch. – Pablo

+0

getReturnType() sẽ trả về Object nếu kiểu trả về là Object hoặc Generic trả về Object. Trong các ví dụ trên, nó sẽ là 'Long' và' String' –

+0

OK, tôi đã đọc sai câu hỏi, tôi nghĩ rằng anh ta có nghĩa là phương pháp "phương pháp" là chung chung. – Pablo

0

Tại sao T của bạn không thể triển khai một số giao diện hoặc mở rộng một số lớp cơ sở? Sau đó, bạn có thể gọi một số phương thức mặc định tĩnh từ T trả về giá trị mặc định cho một lớp học là T. Ưu điểm? Nó sẽ đóng gói mã số switch của bạn chỉ đến đúng lớp.

Tất nhiên, không có bất kỳ giao diện nào, tất cả các lớp học T có thể chỉ có một số phương pháp như getDefaultValue().

+0

Không, tôi không thể thay đổi các lớp T để thêm phương thức 'getDefaultValue()', cũng như không thay đổi những gì chúng trả về. –

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