Tôi nghĩ rằng tôi có ý tưởng về câu hỏi và vì tôi đã tìm kiếm các cách để so sánh Pattern
tôi kết thúc ở đây (hai năm quá muộn có thể, tốt, xin lỗi ...).
Tôi đang viết các bài kiểm tra và tôi cần biết liệu phương pháp của tôi có trả về mẫu dự kiến hay không. Trong khi văn bản qua toString()
hoặc pattern()
có thể giống nhau, các cờ có thể khác nhau và kết quả khi sử dụng mẫu sẽ không mong muốn.
Một thời gian trước, tôi đã viết triển khai chung của riêng mình là toString()
. Nó thu thập tất cả các trường bao gồm các trường private
và xây dựng một chuỗi có thể được sử dụng để ghi nhật ký và dường như để thử nghiệm. Nó cho thấy rằng các trường root
và matchRoot
khác nhau khi biên dịch hai mẫu bằng nhau. Giả sử rằng hai điều đó không liên quan đến bình đẳng và vì có một trường flag
, giải pháp của tôi khá tốt nếu không hoàn hảo.
/**
* Don't call this method from a <code>toString()</code> method with
* <code>useExistingToString</code> set to <code>true</code>!!!
*/
public static String toString(Object object, boolean useExistingToString, String... ignoreFieldNames) {
if (object == null) {
return null;
}
Class<? extends Object> clazz = object.getClass();
if (useExistingToString) {
try {
// avoid the default implementation Object.toString()
Method methodToString = clazz.getMethod("toString");
if (!methodToString.getDeclaringClass().isAssignableFrom(Object.class)) {
return object.toString();
}
} catch (Exception e) {
}
}
List<String> ignoreFieldNameList = Arrays.asList(ignoreFieldNames);
Map<String, Object> fields = new HashMap<String, Object>();
while (clazz != null) {
for (Field field : clazz.getDeclaredFields()) {
String fieldName = field.getName();
if (ignoreFieldNameList.contains(fieldName) || fields.containsKey(fieldName)) {
continue;
}
boolean accessible = field.isAccessible();
if (!accessible) {
field.setAccessible(true);
}
try {
Object fieldValue = field.get(object);
if (fieldValue instanceof String) {
fieldValue = stringifyValue(fieldValue);
}
fields.put(fieldName, fieldValue);
} catch (Exception e) {
fields.put(fieldName, "-inaccessible- " + e.getMessage());
}
if (!accessible) {
field.setAccessible(false);
}
}
// travel upwards in the class hierarchy
clazz = clazz.getSuperclass();
}
return object.getClass().getName() + ": " + fields;
}
public static String stringifyValue(Object value) {
if (value == null) {
return "null";
}
return "'" + value.toString() + "'";
}
Và thử nghiệm là màu xanh lá cây:
String toString1 = Utility.toString(Pattern.compile("test", Pattern.CASE_INSENSITIVE), false, "root", "matchRoot");
String toString2 = Utility.toString(Pattern.compile("test", Pattern.CASE_INSENSITIVE), false, "root", "matchRoot");
assertEquals(toString1, toString2);
Nếu bạn so sánh 'pattern' bạn sẽ bỏ lỡ những lá cờ. –
@MarkusMalkusch - Vâng, đó là một lý do khác để so sánh các đối tượng 'Pattern' bằng cách sử dụng' pattern() 'có thể có vấn đề. –
Đối tượng mẫu chưa bao giờ được lưu trữ tự động. Như bằng chứng, các tài liệu API cảnh báo rằng 'Pattern.matches()' và 'String # matches()' không cho phép đối tượng Pattern được sử dụng lại, và do đó không nên được sử dụng cho các cuộc gọi lặp lại, như trong vòng lặp. (Lớp Scanner * làm * lưu trữ tất cả các mẫu mà nó sử dụng, nhưng đó là xử lý nội bộ.) –