gpt4 book ai didi

java - 使用反射从扩展实例获取特定属性

转载 作者:行者123 更新时间:2023-12-01 18:12:32 25 4
gpt4 key购买 nike

我想创建一个通用方法来从参数对象获取列表。

问题是因为我有一个声明的对象,其中包含扩展该声明类的另一个类的实例。我不想使用 instanceof 解决方案,因为扩展 LimitedValue 的类数量可能很大。

我想使用反射作为解决方案,但我不知道如何在这部分代码中将其与对象实例一起使用:

    Class cls = Class.forName(limitedValue.getClass().getName());
Object obj = cls.newInstance();
//This is wrong, I don't want a new instance.

Method[] methods = cls.getDeclaredMethods();
for(int x= 0; x < methods.length; x++) {
Method method = methods[x];
if ("java.util.List".equals(method.getReturnType().getName())) {
//How to get the value of this method from limitedValue instance ?
}
}

这是我的完整代码:

public class CalculatorLimitedValue {

public static void main(String[] args) throws Exception {
StoreItem storeItem = new StoreItem(1L, "Name of StoreItem", 50L);
List listOfStoreItems = new ArrayList();
listOfStoreItems.add(storeItem);
LimitedValue limitedValue0 = new Store(listOfStoreItems);

List firstList = calculator(limitedValue0);
//do something with the list

SupermarketItem supermarketItem = new SupermarketItem(1L, "Name of SupermarketItem", 21L);
List listOfSupermarketItems = new ArrayList();
listOfSupermarketItems.add(supermarketItem);
LimitedValue limitedValue1 = new Supermarket(listOfSupermarketItems);

List secondList = calculator(limitedValue1);
//do something with the list
}

/** This is the method that I'd like to make generic to return a List */
private static List calculator(LimitedValue limitedValue) throws Exception{

Class cls = Class.forName(limitedValue.getClass().getName());
Object obj = cls.newInstance();
//This is wrong, I don't want a new instance.

Method[] methods = cls.getDeclaredMethods();
for(int x= 0; x < methods.length; x++) {
Method method = methods[x];
if ("java.util.List".equals(method.getReturnType().getName())) {
//How to get the value of this method from limitedValue instance ?
}
}

/* I don't want to use this one way, because my classes that extends LimitedValue
can be big. I would like to made a generic way to get de list of classes. */
if (limitedValue instanceof Store) {
System.out.println("This is a store");
return ((Store) limitedValue).getStoreItems();
} else if (limitedValue instanceof Supermarket) {
System.out.println("This is a supermarket");
return ((Supermarket) limitedValue).getSupermarketItems();
}
return null;
}
}

如果有帮助,这些是我的其他类(class):

LimitedValue.class

public class LimitedValue { }

StoreItem.class

public class StoreItem {
private Long id;
private String nameOfStoreItem;
private Long valueOfStoreItem;

public StoreItem(Long id, String nameOfStoreItem, Long valueOfStoreItem){
this.id = id;
this.nameOfStoreItem = nameOfStoreItem;
this.valueOfStoreItem = valueOfStoreItem;
}
//getters and setters...
}

SupermarketItem.class

public class SupermarketItem {
private Long id;
private String nameOfSupermarketItem;
private Long valueOfSupermarketItem;

public SupermarketItem() {
}

public SupermarketItem(Long id, String nameOfSupermarketItem, Long valueOfSupermarketItem) {
this.id = id;
this.nameOfSupermarketItem = nameOfSupermarketItem;
this.valueOfSupermarketItem = valueOfSupermarketItem;
}
//getters and setters...
}

商店.class

public class Store extends LimitedValue {
private List<StoreItem> storeItems;

public Store(List<StoreItem> storeItems) {
this.storeItems = storeItems;
}
//getters and setters
}

超市.class

public class Supermarket extends LimitedValue {
private List<SupermarketItem> supermarketItems;

public Supermarket(List<SupermarketItem> supermarketItems) {
this.supermarketItems = supermarketItems;
}
//getters and setters
}

最佳答案

您可以尝试在这里使用反射来尝试实现您想要的目标,但最好重新考虑您的整体设计并尝试使用更好的面向对象设计来解决手头的问题。

特别是,假设我们考虑将一个名为 getItems 的方法添加到 LimitedValue 中。返回项目列表的类,可能是 SupermarketItem或可能是StoreItem s。如果它的结构正确,您将不需要知道实际类型,因为代码将以多态方式对其进行抽象。

public abstract class LimitedValue {    
List<? extends Item> getItems();
}

我们现在在 LimitedValue 上定义了一个新方法,但我们还必须考虑到我们已经引入了这个新的 Item 事物。我注意到SupermarketItemStoreItem都具有相似的属性,name , idvalue ,因此似乎可以使用单个类来表示所有这些。

public abstract class Item {
final Long id;
final String name;
final Long value;

public Item(final Long id, final Long name, final Long value) {
this.id = id;
this.name = name;
this.value = value;
}

String getName() {
return name;
}
// other getters and setters
}

public class SupermarketItem extends Item {
public SupermarketItem(final Long id, final Long name, final Long value) {
super(id, name, value);
}
}

public class StoreItem extends Item {
public StoreItem(final Long id, final Long name, final Long value) {
super(id, name, value);
}
}

现在,我们已经完全抽象化了访问这些对象时对任何反射的需求 - 您只需调用 item.getValue() 即可,因为您将知道列表中的每个项目都是 Item 类型。

当然,您还需要重构 Store 和 SuperMarket 类,例如:

public class Supermarket extends LimitedValue {
private List<SupermarketItem> supermarketItems;

public Supermarket(List<SupermarketItem> supermarketItems) {
this.supermarketItems = supermarketItems;
}

public List<? extends Item> getItems() {
return supermarketItems;
}
}

因为您只返回 List<Item>您始终知道其中的内容,并且可以更改主要代码来使用它。

这是一个更干净的长期解决方案。

关于java - 使用反射从扩展实例获取特定属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31898781/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com