【问题标题】:Java - Get object of class depending on its nameJava - 根据其名称获取类的对象
【发布时间】:2013-10-23 21:12:17
【问题描述】:

这是我的情况:

我有一个方法,它有一个字符串作为参数。此方法必须从名为 Urls 的类接收对象。它必须接收的对象与字符串的值具有相同的名称。这是我的代码:

private Object getObject(String objectName){
    try
    {
        Field field = Urls.class.getField(objectName);          
    }
    catch (NoSuchFieldException e)
    {}
    catch (IllegalAccessException e)
    {}
}

这是我的 Urls 类:

public class Urls{

public static final String[] ASTUN = new String[]{
    "http://www.astun.com/camara/truchas.jpg",
    "https://www.todonieve.com/photowebcam.asp?fotografia=astun/astun.jpg",
    "http://www.astun.com/camara/caba%C3%B1a%20sarrios.jpg",
    "http://www.astun.com/camara/sector%20sarrios.jpg",
    "http://www.astun.com/camara/sector%20raca%20prad.jpg",
    "http://www.astun.com/camara/sector%20aguila%20cr.jpg",
    "http://www.astun.com/camara/sector%20truchas.jpg",
    "http://www.astun.com/camara/sector%20llanos%20.jpg",
    "http://www.astun.com/camara/llegada.jpg",
    "http://www.astun.com/camara/terraza.jpg",
    "http://www.astun.com/camara/panoramica.jpg",
    "http://www.astun.com/camara/snow.jpg"
};

private static final String[] CANDANCHU = new String[]{
    "https://www.todonieve.com/photowebcam.asp?fotografia=candanchu/candanchu.jpg",
    "https://www.todonieve.com/photowebcam.asp?fotografia=CandanchuNew/CandanchuNew.jpg",
    "https://www.todonieve.com/photowebcam.asp?fotografia=candanchu_rinconada/candanchu_rinco.jpg",
"https://www.todonieve.com/photowebcam.asp?fotografia=candanchu_tobazo/candanchu_tobazo.jpg"
};

}

那么,这样我就有了一个 Field 对象,但是我怎样才能得到那个字段的 String[] 呢?我已经阅读了 Field 类的 get(Object object) 方法,但似乎我没有做我想做的事......

编辑:我想要 ASTUN 或 CANDACHU 字​​符串数组

【问题讨论】:

  • 对象没有“名称”。你是说变量吗?如果是这样,这会给代码带来代码气味。你想创建一个地图吗?请注意,您的 Urls 类只包含静态字符串数组。用String获取String的目的是什么?
  • 你能举例说明你期望的结果是什么吗?
  • +Hovercraft Full Of Eels 我的意思是其中一个字段...作为参数传递的字符串将包含“ASTUN”或“CANDANCHU”
  • 您能否更好地描述此代码试图解决的问题,而不是您尝试使用的代码解决方案。这对我来说完全不对劲,我想知道是否有更好的方法来解决整体问题,也许你在找错树了。

标签: java class object field


【解决方案1】:

尽可能避免反思。它往往弊大于利。

将它们放入地图中:

public class Urls {
  //put your arrays here

  private static final Map<String,String[]> urlsLists = new HashMap<>();
  static {
    urlLists.put("ASTUN", ASTUN);
    urlLists.put("CANDANCHU", CANDANCHU);
  }

  public static String[] getUrlList(String name) {
    return urlLists.get(name);
  }
}

然后这样称呼它:

private Object getObject(String objectName){
  return Urls.getUrlList(objectName);
}

更新

你失去了很多 Java 帮助你的好东西,包括类型安全、封装和编译时检查。因此,它更容易出错。运行时错误的风险大大增加,您需要一堆额外的代码来处理这个问题。您的简短示例已经有两个 catch 子句。相信我 - 这只会变得更糟。

您甚至可以通过创建 Enum 来定义 url 类型来进一步提高类型安全性。然后,您将获得编译时检查您是否拼写正确的名称,甚至自动完成整个代码。 :)

public class Urls {
  public enum UrlTypes {ASTUN; CANDANCHU;}
  // ..
  private static final Map<UrlTypes,String[]> urlsLists = new HashMap<>();
  static {
    urlLists.put(UrlTypes.ASTUN, ASTUN);
    urlLists.put(UrlTypes.CANDANCHU, CANDANCHU);
  }
  ..
  public static String[] getUrlList(UrlTypes name) {
    return urlLists.get(name);
  }
}

当事情变得复杂时,您可以在编译时而不是在运行时捕获的每个错误都可以为您节省半小时或半周的工作时间。

【讨论】:

  • 我为什么要避免反射?感谢您的回答
  • @BamsBamx:因为 1)它很慢。 2)它使您将内容硬编码到代码中,不必要地使您的代码更加僵化且可扩展性降低。 3) 这是一个暴露内部结构的非常底层的解决方案,这增加了产生难以调试的错误的危险。 4) 您的 IDE 对反射视而不见,因此很难重构代码。当任务需要它时肯定会使用反射,尤其是当它需要它时,但这种情况并非如此。
  • 同意气垫船。扩大了答案。
【解决方案2】:

你需要这样的东西:

private Object getObject(String objectName){
    try
    {
        Field field = Urls.class.getField(objectName);
        Object o = field.get(null); // null works as well.
        return o;
    }
    catch (NoSuchFieldException e)
    { e.printStackTrace(); }
    catch (IllegalAccessException e)
    { e.printStackTrace(); }
}

private String[] getStringArray(String arrayName)
{
    return (String[]) getObject(arrayName);
}

用法:

Object o = getObject("ASTUN");
// or:
String[] arr = getStringArray("ASTUN");

【讨论】:

  • 你是怎么得出这个结论的? OP 说他得到了Field,所以这不是问题所在。
  • 嗯,这对我有用......我决定问这个问题的原因是 th Field.get() 方法的参数,传递 'this' 对我有用。我也使用了 getField()如您所说,安装了 getDeclaredField()
  • 我编辑了我的答案。 null 也可以。其实null更正确,因为字段是静态的。
【解决方案3】:

getField 将返回 Urls 类中字段概念的(自反)表示。然后,您需要将其与该类的实际对象绑定,以访问该对象中字段的内容。

Field field = Urls.class.getFiled(objectName);
String[] values = (String[]) field.get(o);

其中oUrls 类型的变量。

请注意转换为String[],因为Field.get() 将返回Object,因为它不知道实际类型。您应该使用Field.getType() 方法确保类型确实正确,并将其与Urls.class 进行比较。

【讨论】:

  • @BamsBamx - 真的,想念这些字段是static
【解决方案4】:

由于对象没有名称,您需要创建 ypur 自己的类,将字段变量放入其中,然后使用它代替 Object。或者使用 Map 来更好地记录键/值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-24
    • 2023-03-14
    • 2014-05-18
    • 2021-03-18
    • 1970-01-01
    • 2013-06-08
    相关资源
    最近更新 更多