Tôi viết một lớp java có nhiều getters..now tôi muốn có được tất cả các phương thức getter và gọi chúng đôi khi .. Tôi biết có phương pháp như getMethods() hoặc getMethod (String name, Class ... parameterTypes), nhưng tôi chỉ muốn có được getter thực sự ..., sử dụng regex? bất cứ ai có thể cho tôi biết?Java Reflection: Làm thế nào tôi có thể nhận được tất cả các phương thức getter của một lớp java và gọi chúng
Trả lời
Không sử dụng regex, sử dụng Introspector
:
for(PropertyDescriptor propertyDescriptor :
Introspector.getBeanInfo(yourClass).getPropertyDescriptors()){
// propertyEditor.getReadMethod() exposes the getter
// btw, this may be null if you have a write-only property
System.out.println(propertyDescriptor.getReadMethod());
}
Thông thường, bạn không muốn tính từ Object.class, vì vậy bạn muốn sử dụng phương pháp này với hai tham số:
Introspector.getBeanInfo(yourClass, stopClass)
// usually with Object.class as 2nd param
// the first class is inclusive, the second exclusive
BTW: có các khung làm điều đó cho bạn và trình bày cho bạn một cái nhìn cấp cao. Ví dụ. commons/beanutils có phương pháp
Map<String, String> properties = BeanUtils.describe(yourObject);
(docs here) mà không chỉ rằng: tìm và thực hiện tất cả các getter và lưu trữ kết quả trong một bản đồ. Thật không may, BeanUtils.describe()
chuyển đổi tất cả các giá trị thuộc tính thành Chuỗi trước khi trở về. WTF. Cảm ơn @danw
Cập nhật:
Dưới đây là một Java 8 phương thức trả về một Map<String, Object>
dựa trên thuộc tính bean của một đối tượng.
public static Map<String, Object> beanProperties(Object bean) {
try {
return Arrays.asList(
Introspector.getBeanInfo(bean.getClass(), Object.class)
.getPropertyDescriptors()
)
.stream()
// filter out properties with setters only
.filter(pd -> Objects.nonNull(pd.getReadMethod()))
.collect(Collectors.toMap(
// bean property name
PropertyDescriptor::getName,
pd -> { // invoke method to get value
try {
return pd.getReadMethod().invoke(bean);
} catch (Exception e) {
// replace this with better error handling
return null;
}
}));
} catch (IntrospectionException e) {
// and this, too
return Collections.emptyMap();
}
}
Có thể bạn muốn xử lý lỗi mạnh mẽ hơn. Xin lỗi cho boilerplate, kiểm tra ngoại lệ ngăn cản chúng tôi đi đầy đủ chức năng ở đây.
Chỉ ra rằng Collectors.toMap() ghét giá trị null. Dưới đây là một phiên bản cấp bách hơn về đoạn code trên:
public static Map<String, Object> beanProperties(Object bean) {
try {
Map<String, Object> map = new HashMap<>();
Arrays.asList(Introspector.getBeanInfo(bean.getClass(), Object.class)
.getPropertyDescriptors())
.stream()
// filter out properties with setters only
.filter(pd -> Objects.nonNull(pd.getReadMethod()))
.forEach(pd -> { // invoke method to get value
try {
Object value = pd.getReadMethod().invoke(bean);
if (value != null) {
map.put(pd.getName(), value);
}
} catch (Exception e) {
// add proper error handling here
}
});
return map;
} catch (IntrospectionException e) {
// and here, too
return Collections.emptyMap();
}
}
Dưới đây là các chức năng tương tự một cách ngắn gọn hơn, sử dụng JavaSlang:
public static Map<String, Object> javaSlangBeanProperties(Object bean) {
try {
return Stream.of(Introspector.getBeanInfo(bean.getClass(), Object.class)
.getPropertyDescriptors())
.filter(pd -> pd.getReadMethod() != null)
.toJavaMap(pd -> {
try {
return new Tuple2<>(
pd.getName(),
pd.getReadMethod().invoke(bean));
} catch (Exception e) {
throw new IllegalStateException();
}
});
} catch (IntrospectionException e) {
throw new IllegalStateException();
}
}
và đây là một phiên bản Ổi:
public static Map<String, Object> guavaBeanProperties(Object bean) {
Object NULL = new Object();
try {
return Maps.transformValues(
Arrays.stream(
Introspector.getBeanInfo(bean.getClass(), Object.class)
.getPropertyDescriptors())
.filter(pd -> Objects.nonNull(pd.getReadMethod()))
.collect(ImmutableMap::<String, Object>builder,
(builder, pd) -> {
try {
Object result = pd.getReadMethod()
.invoke(bean);
builder.put(pd.getName(),
firstNonNull(result, NULL));
} catch (Exception e) {
throw propagate(e);
}
},
(left, right) -> left.putAll(right.build()))
.build(), v -> v == NULL ? null : v);
} catch (IntrospectionException e) {
throw propagate(e);
}
}
// Get the Class object associated with this class.
MyClass myClass= new MyClass();
Class objClass= myClass.getClass();
// Get the public methods associated with this class.
Method[] methods = objClass.getMethods();
for (Method method:methods)
{
System.out.println("Public method found: " + method.toString());
}
Có, nhưng bạn cũng sẽ phải kiểm tra từng phương thức công khai, không tĩnh, trả về void, hy vọng không có tham số và tuân theo quy ước get/isXyz name. Introspector làm tất cả những điều đó cho bạn, cộng với nó lưu trữ dữ liệu BeanInfo nội bộ cho các ứng dụng khác. –
không trả lại khoảng trống, tức là –
Bạn có thể sử dụng Reflections khuôn khổ cho
nàyimport org.reflections.ReflectionUtils.*;
Set<Method> getters = ReflectionUtils.getAllMethods(someClass,
ReflectionUtils.withModifier(Modifier.PUBLIC), ReflectionUtils.withPrefix("get"));
Không phải tất cả các getters đều bắt đầu bằng "get": (1) getters boolean-return có thể bắt đầu bằng "is"; (2) một lớp BeanInfo có thể nói rằng các phương thức bổ sung là getters.Bạn thực sự nên thêm một hạn chế như _if bạn biết rằng tất cả các getters của bạn bắt đầu bằng "get", bạn có thể làm điều này_. – toolforger
Bạn nên duy trì một getter chung trong mọi đậu, do đó để gọi getAttribute1(), bạn sẽ có thể gọi một getter get generic ("Attribute1")
này getter generic sẽ gọi trong-turn getter đúng
Object get(String attribute)
{
if("Attribute1".equals(attribute)
{
return getAttribute1();
}
}
cách tiếp cận này liên quan đến việc bạn duy trì danh sách riêng biệt này trong mọi đậu nhưng cách này bạn tránh phản chiếu trong đó có vấn đề hiệu suất, vì vậy nếu bạn viết mã sản xuất mà cần phải có hiệu suất tốt, bạn có thể sử dụng trên mẫu cho tất cả các hạt của bạn.Nếu nó là một số mã thử nghiệm hoặc mã tiện ích không có yêu cầu hiệu năng cao thì bạn nên sử dụng các cách tiếp cận khác vì phương pháp này dễ bị lỗi trừ khi bạn có thể viết một số loại trình biên dịch thời gian biên dịch. hoạt động cho tất cả các thuộc tính.
Spring cung cấp một cách dễ dàng BeanUtil method cho Bean mẫn:
PropertyDescriptor pd = BeanUtils.getPropertyDescriptor(clazz, property);
Method getter = pd.getReadMethod();
Mã này được kiểm tra OK.
private void callAllGetterMethodsInTestModel(TestModel testModelObject) {
try {
Class testModelClass = Class.forName("com.encoders.eva.testreflectionapi.TestModel");
Method[] methods = testModelClass.getDeclaredMethods();
ArrayList<String> getterResults = new ArrayList<>();
for (Method method :
methods) {
if (method.getName().startsWith("get")){
getterResults.add((String) method.invoke(testModelObject));
}
}
Log.d("sayanReflextion", "==>: "+getterResults.toString());
} catch (ClassNotFoundException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
- 1. Làm thế nào tôi có thể nhận được tất cả các tham chiếu với Reflection + C#
- 2. Làm thế nào tôi có thể tìm thấy tất cả các phương thức gọi một phương thức đã cho trong Java?
- 3. Aspectj @Around cắt tất cả các phương thức trong Java
- 4. Làm cách nào để tôi có thể chặn tất cả các phương thức trong một ứng dụng Java bằng Groovy?
- 5. Làm thế nào tôi có thể nhận được tất cả các lớp thừa kế của một lớp cơ sở?
- 6. Có thể liệt kê tất cả các lớp PHP và các phương thức và thuộc tính của chúng?
- 7. Làm thế nào để gọi một phương thức mà ném một ngoại lệ bằng cách sử dụng Java Reflection?
- 8. Làm thế nào tôi có thể gọi một phương thức tĩnh từ một lớp nếu tất cả những gì tôi có là một chuỗi tên lớp?
- 9. Phương thức lớp chính() có thể được gọi trong một lớp khác trong java
- 10. java gọi một phương thức từ một lớp khác
- 11. Tất cả các phương thức của thuộc tính Java có được đồng bộ hoàn toàn không?
- 12. Bạn sẽ gọi phương thức từ tất cả các phiên bản của một lớp như thế nào?
- 13. Làm thế nào để gọi một phương thức java dựa trên một loại phân lớp?
- 14. Java Reflection getDeclaredMethod() với các loại lớp
- 15. Lấy tên của tất cả các lớp Java được khai báo trong một gói
- 16. Làm thế nào tôi có thể đồng bộ hóa getter trong khi một setter đang làm việc trong Java
- 17. Làm cách nào để có được javadoc của tất cả các phương thức có chú thích cụ thể, với tên phương thức và tên gói/lớp?
- 18. Làm thế nào tôi có thể gọi một phương thức tĩnh trên một lớp biến?
- 19. Làm thế nào để gọi một phương thức python từ một lớp java?
- 20. Làm thế nào tôi có thể ghi đè lên phương thức toString của một ArrayList trong Java?
- 21. Chạy phương pháp trước tất cả các phương thức của một lớp
- 22. Java - Clone tài sản bên trong phương thức getter
- 23. Eclipse: liệt kê các phương thức và biến của tất cả các lớp
- 24. Làm thế nào tôi có thể nhận được tất cả các lớp trong một không gian tên?
- 25. Làm thế nào tôi có thể buộc một Constructor được định nghĩa trong tất cả các lớp con của lớp trừu tượng của tôi
- 26. Lớp nào đã gọi phương thức tĩnh của tôi?
- 27. Làm thế nào tôi có thể nhận được giá trị của tất cả các ô được chọn trong một DataGridView?
- 28. Java: Làm thế nào để hạn chế quyền truy cập của một phương thức vào một lớp cụ thể?
- 29. Làm cách nào để lặp qua tất cả các phương thức của một lớp trong Perl?
- 30. Làm thế nào tôi có thể nhận được tất cả các ổ đĩa USB (cắm vào)
Wow. Tôi không biết bạn có thể làm điều đó! Mát mẻ! –
Cảm ơn ..i kiểm tra mã ... kết thúc đầu ra là ** công khai java.lang.Class java.lang.Object.getClass() ** ... tôi không muốn gọi nó. .how để loại bỏ nó? – user996505
@ user996505 Sử dụng Introspector.getBeanInfo (yourClass, Object.class), để tìm kiếm tất cả các lớp bên dưới Object –