Đối với những gì đáng giá, hầu hết các ngôn ngữ kịch bản (như Perl) và các ngôn ngữ thời gian biên dịch không tĩnh (như Pick) đều hỗ trợ chuyển đổi Chuỗi động thời gian chạy tự động sang chuyển đổi đối tượng (tương đối tùy ý). Điều này cũng CÓ THỂ được thực hiện trong Java mà không làm mất tính an toàn của kiểu chữ và những thứ tốt nhất mà các ngôn ngữ được định kiểu tĩnh cung cấp mà KHÔNG có tác dụng phụ khó chịu của một số ngôn ngữ khác làm những điều xấu xa với tính năng ép kiểu động. Một ví dụ Perl thực hiện một số phép toán đáng ngờ:
print ++($foo = '99'); # prints '100'
print ++($foo = 'a0'); # prints 'a1'
Trong Java, điều này được thực hiện tốt hơn (IMHO) bằng cách sử dụng một phương pháp mà tôi gọi là "ép kiểu chéo". Với truyền chéo, phản xạ được sử dụng trong bộ đệm ẩn được tải chậm của các hàm tạo và phương thức được phát hiện động thông qua phương thức tĩnh sau:
Object fromString (String value, Class targetClass)
Thật không may, không có phương thức Java nào được tích hợp sẵn như Class.cast () sẽ thực hiện điều này đối với Chuỗi sang BigDecimal hoặc Chuỗi thành Số nguyên hoặc bất kỳ chuyển đổi nào khác mà không có phân cấp lớp hỗ trợ. Về phần tôi, quan điểm là cung cấp một cách hoàn toàn năng động để đạt được điều này - mà tôi không nghĩ rằng tài liệu tham khảo trước là cách tiếp cận đúng - phải viết mã mọi chuyển đổi. Nói một cách đơn giản, việc triển khai chỉ là ép kiểu từ chuỗi nếu nó hợp pháp / có thể.
Vì vậy, giải pháp là phản ánh đơn giản tìm kiếm các Thành viên công khai của một trong hai:
STRING_CLASS_ARRAY = (Lớp mới [] {String.class});
a) Thành viên thành viên = targetClass.getMethod (method.getName (), STRING_CLASS_ARRAY); b) Thành viên thành viên = targetClass.getConstructor (STRING_CLASS_ARRAY);
Bạn sẽ thấy rằng tất cả các nguyên thủy (Integer, Long, v.v.) và tất cả các khái niệm cơ bản (BigInteger, BigDecimal, v.v.) và thậm chí cả java.regex.Pattern đều được đề cập thông qua cách tiếp cận này. Tôi đã sử dụng điều này với thành công đáng kể trong các dự án sản xuất có một lượng lớn đầu vào giá trị Chuỗi tùy ý, nơi cần phải kiểm tra nghiêm ngặt hơn. Trong cách tiếp cận này, nếu không có phương thức nào hoặc khi phương thức được gọi, một ngoại lệ sẽ được ném ra (vì đó là giá trị không hợp lệ, chẳng hạn như đầu vào không phải số cho BigDecimal hoặc RegEx không hợp lệ cho Mẫu), điều này cung cấp kiểm tra cụ thể cho logic vốn có của lớp đích.
Có một số nhược điểm của điều này:
1) Bạn cần hiểu rõ về phản xạ (điều này hơi phức tạp và không dành cho người mới). 2) Một số lớp Java và thực sự là các thư viện của bên thứ 3 (đáng ngạc nhiên là) không được mã hóa đúng cách. Có nghĩa là, có những phương thức lấy một đối số chuỗi đơn làm đầu vào và trả về một thể hiện của lớp đích nhưng nó không như bạn nghĩ ... Hãy xem xét lớp Integer:
static Integer getInteger(String nm)
Determines the integer value of the system property with the specified name.
Phương thức trên thực sự không liên quan gì đến Số nguyên vì các đối tượng bao bọc các int nguyên thủy. Reflection sẽ thấy đây là một ứng cử viên khả dĩ để tạo một Số nguyên từ một Chuỗi không chính xác so với các Thành viên giải mã, valueof và constructor - tất cả đều phù hợp với hầu hết các chuyển đổi Chuỗi tùy ý mà bạn thực sự không có quyền kiểm soát dữ liệu đầu vào của mình mà chỉ muốn biết nếu nó có thể là một số nguyên.
Để khắc phục điều trên, việc tìm kiếm các phương thức ném Ngoại lệ là một khởi đầu tốt vì các giá trị đầu vào không hợp lệ tạo ra các thể hiện của các đối tượng như vậy nên ném Ngoại lệ. Thật không may, việc triển khai khác nhau tùy thuộc vào việc các Ngoại lệ có được khai báo là đã kiểm tra hay không. Ví dụ: Integer.valueOf (String) ném một NumberFormatException đã kiểm tra, nhưng không tìm thấy ngoại lệ Pattern.compile () trong khi tra cứu phản chiếu. Một lần nữa, không phải là thất bại của phương pháp tiếp cận "truyền chéo" động này, tôi nghĩ rất nhiều như một cách triển khai không chuẩn cho các khai báo ngoại lệ trong các phương pháp tạo đối tượng.
Nếu có ai muốn biết thêm chi tiết về cách thực hiện ở trên, hãy cho tôi biết nhưng tôi nghĩ giải pháp này linh hoạt hơn nhiều / có thể mở rộng và ít mã hơn mà không làm mất đi các phần tốt của type-safe. Tất nhiên, tốt nhất là "biết dữ liệu của bạn" nhưng như nhiều người trong chúng ta thấy, đôi khi chúng ta chỉ là người nhận nội dung không được quản lý và phải cố gắng hết sức để sử dụng nó đúng cách.
Chúc mừng.