2013-08-07 30 views
17

Được rồi, đây là một câu hỏi phức tạp và tôi hoàn toàn bị mất.Java làm cách nào để kiểm tra xem giá trị chuỗi có phải là một loại Lớp nhất định <?>

Giả sử bạn có một chuỗi và một lớp chung. Như thế này.

String string; 
Class<?> clazz; 

Làm cách nào bạn kiểm tra xem chuỗi có biểu thị giá trị mà lớp có thể bằng nhau hay không.

Ví dụ cho phép nói rằng:

String string = "true"; 
Class<?> clazz = Boolean.class; 

Làm thế nào tôi sẽ kiểm tra và thấy rằng chuỗi "true" là trong thực tế một boolean?

Dưới đây là một ví dụ khác. Giả sử rằng:

String string = "true"; 
Class<?> clazz = Integer.class; 

Làm cách nào để kiểm tra và thấy chuỗi "true" không phải là số nguyên?

+0

Bạn có muốn thực hiện kiểm tra chỉ cho các loại Trình bao bọc không? –

+0

Tôi chủ yếu quan tâm đến các trình bao bọc kiểu nguyên thủy, có –

Trả lời

17

Cho rằng bạn muốn điều này chỉ dành cho loại Wrapper, bạn có thể sử dụng một số phản ánh Hack đây (xử lý mã không thích hợp ngoại lệ được bỏ qua ở đây cho ngắn gọn):

String string = "ABC"; 
Class<?> clazz = Integer.class; 

Method method = clazz.getDeclaredMethod("valueOf", String.class); 

if (method != null) { 
    try { 
     Object obj = method.invoke(null, string);  
     System.out.println("Success : " + obj); 

    } catch (InvocationTargetException ex) { 
     System.out.println("Failure : " + string + " is not of type " + 
              clazz.getName()); 
    } 
} 

Tôi đang tính đến thực tế là, mọi lớp trình bao bọc đều có phương thức tĩnh tĩnhvalueOf có tham số loại String và trả về giá trị của loại wrapper đó. Và ném một ngoại lệ, nếu tham số không chuyển đổi thành loại trình bao bọc tương ứng.

Vì vậy, trong trường hợp trên, nếu ngoại lệ được ném, giá trị string không phải là loại clazz.

P.S.: Lưu ý rằng đối với Boolean.class, bất kỳ chuỗi nào không phải là "true" sẽ được coi là false.

0

Trong javascript, bạn có thể eval() chuỗi. Trong Java bạn không có phương tiện như vậy. Bạn sẽ phải thực hiện chẩn đoán của riêng bạn cho kiểm tra này.

Tuy nhiên, một điều bạn có thể làm là phân tích cú pháp chuỗi với lớp đã cho. Giống như:

Iteger.parseInt(stringValue); 

Nếu phân tích thành công, thì chuỗi có thể được sử dụng làm giá trị cho loại đó. Nếu nó không thành công, bạn sẽ nhận được một ngoại lệ. Thực hiện các kiểm tra này và sau đó khấu trừ một số kết luận.

+0

Tôi không thể sử dụng phương thức đó vì tôi không biết lớp đó có phải là một số nguyên không. Nó là một loại chung. –

+0

Không có giải pháp duy nhất cho vấn đề của bạn. Đây là lý do tại sao tôi nói rằng bạn cần phải impement một loạt các kiểm tra và sau đó khấu trừ một kết luận. – allprog

+0

Tôi không mong đợi một giải pháp một dòng. Tôi chỉ nghĩ rằng phải có một cách tốt hơn là kiểm tra xem có bất kỳ kiểu nguyên thủy nào hay các lớp khác mà tôi thêm vào và sau đó kiểm tra nó với mỗi lớp tôi thêm –

0

Tôi không thể kiểm tra giải pháp này ngay bây giờ, nhưng tại sao lại không giống như vậy? Nếu bạn có thể liệt kê tất cả các lớp có thể, hãy tạo một số câu lệnh switch trên lớp.

boolean isStringClass (Class clazz, String string) { 

    try { 
     if (Integer.class == clazz) { 
      Integer.valueOf(string); 
     } else if (Boolean.class = clazz) { 
      Boolean.valueOf(string); 
     } [...etc] 
    } catch (Exception e) { 
     return false; 
    } 

    return true; 
} 

Tất nhiên bạn sẽ cần phải biết tất cả các lớp có thể, và bạn sẽ cần biết phương thức thuộc lớp đó có thể phân tích chuỗi và trả về loại của nó. Đối với các trình bao bọc nguyên thủy sẽ là valueOf.

Nếu bạn dự định chỉ chuyển đổi trình bao bọc, giải pháp của Rohit sẽ là lựa chọn tốt hơn. Tuy nhiên, nếu bạn không làm điều đó và bạn không thể thêm phương thức valueOf vào Lớp mới này, đây có thể là tùy chọn duy nhất của bạn.

1

Tôi giả sử bạn đang triển khai một số loại Đặc điểm kỹ thuật/Giao thức hoặc tương tự.

  1. Nhìn vào Spec.
  2. Xác định ngữ pháp của mục nhập hợp lệ
  3. Phân tích ngữ pháp đó.

Điều này tương tự với Ngôn ngữ lập trình đang làm gì với văn học.

0

Tôi sẽ xem xét sử dụng cơ chế JavaBeans PropertyEditor cho việc này.

@Test 
public void testIsOfType() {   
    assertFalse(test("nope", Integer.class)); 
    assertFalse(test("nope", Boolean.class)); 

    assertTrue(test("1", Integer.class)); 
    assertTrue(test("true", Boolean.class)); 
} 

boolean test(String str, Class<?> clazz) { 
    PropertyEditor propertyEditor = PropertyEditorManager.findEditor(clazz); 
    if (propertyEditor != null) { 
     try {   
      propertyEditor.setAsText(str); 
      return true; 
     } catch (Exception ex) {} 
    } 
    return false; 
} 

này tránh sự cần thiết cho phản ánh rõ ràng, và nếu bạn đã bao giờ quyết định bạn cần phải kiểm tra các lớp khác so với giấy gói nguyên thủy bạn có thể đăng ký một biên tập mới với PropertyEditorManager.registerEditor().

Thật không may, điều này vẫn có vấn đề là giải pháp của Rohit trong đó test("1", Number.class) sẽ không thành công.