当前位置: 首页 > 面试题库 >

获取字段名称

金承嗣
2023-03-14
问题内容

在Java中能否从实际字段中获取字符串中的字段名称?喜欢:

public class mod {
    @ItemID
    public static ItemLinkTool linkTool;

    public void xxx{
        String fieldsName = *getFieldsName(linkTool)*;
    }
}

PS:我 不是 在寻找字段的类/类名,也不是从String中的名称获取Field。

编辑:当我查看它时,我可能不需要一种获取字段名称的方法,该Field实例(来自字段的“代码名称”)就足够了。[例如Field myField = getField(linkTool)]

Java本身可能没有想要的东西。我将看一下ASM库,但最后我可能最终会使用字符串作为字段的标识符:/

EDIT2:我的英语不好(但是即使是我的母语,我也很难解释这一点),所以我再添加一个例子。希望现在会更加清楚:

public class mod2 {
    @ItemID
    public static ItemLinkTool linkTool;

    @ItemID
    public static ItemLinkTool linkTool2;

    @ItemID
    public static ItemPipeWrench pipeWrench;

    public void constructItems() {
        // most trivial way
        linkTool = new ItemLinkTool(getId("linkTool"));
        linkTool2 = new ItemLinkTool(getId("linkTool2"));
        pipeWrench = new ItemPipeWrench(getId("pipeWrench"));

        // or when constructItem would directly write into field just
        constructItem("linkTool");
        constructItem("linkTool2");
        constructItem("pipeWrench");

        // but I'd like to be able to have it like this
        constructItemIdeal(linkTool);
        constructItemIdeal(linkTool2);
        constructItemIdeal(pipeWrench);
    }

    // not tested, just example of how I see it
    private void constructItem(String name){
        Field f = getClass().getField(name);
        int id = getId(name);

        // this could be rewritten if constructors take same parameters
        // to create a new instance using reflection
        if (f.getDeclaringClass() == ItemLinkTool){
            f.set(null, new ItemLinkTool(id));
        }else{
            f.set(null, new ItemPipeWrench(id));
        }
    }
}

问题是:怎么看constructItemIdeal方法?(通过答案和谷歌搜索,我发现这在Java中是不可能的,但是谁知道呢。)


问题答案:

不幸的是,您无法做任何您想做的事。 为什么?

在一个我们仍在尝试证明Java并不慢的时代,存储对象的构造位置或方式的元数据会产生很大的开销,并且由于它的使用范围非常小,因此不存在。不仅如此:还有很多技术原因。

原因之一是因为如何实现JVM。Java
class文件格式的规范可以在这里找到。这是一个很大的嘴,但它非常有用。

如前所述,即使在 对象没有名称的 情况下,也可以从任何地方构造 对象
。只有定义为类成员的对象才具有名称(出于访问的明显原因):在方法中构造的对象则没有。JVM具有一个本地变量表,最多包含65535个条目。它们通过
load和
store操作码加载到堆栈中并存储到表中。

换句话说,像

public class Test {
int class_member = 42;

   public Test() {
      int my_local_field = 42;
   }
}

被编译成

public class Test extends java.lang.Object
  SourceFile: "Test.java"
  minor version: 0
  major version: 50
  Constant pool:
  --snip--

{
int class_member;

public Test();
  Code:
   Stack=2, Locals=2, Args_size=1
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   aload_0
   5:   bipush  42
   7:   putfield        #2; //Field class_member:I
   10:  bipush  42
   12:  istore_1
   13:  return
  LineNumberTable:
   --snip--    
}

在那里,您可以看到一个清晰的示例,javap -v Test即在class_member保留名称的同时,将my_local_field其抽象为局部变量表中的索引1(为保留0 this)。

这本身就给调试器带来了麻烦,因此,设计了一组属性(认为是类文件的元数据)。这些包括LocalVariableTable,LineNumberTable和LocalVariableTypeTable。这些属性对于堆栈跟踪(LineNumberTable)和调试器(LocalVariableTable和LocalVariableTypeTable)很有用。但是,这些是
包含在文件 中的 完全可选的,并且不能保证它们是:

LineNumberTable属性是属性表中的可选可变长度属性

对于其余的人也是如此。

另外,默认情况下,大多数编译器只生成LineNumberTable而不生成任何内容,因此即使有可能,您也会很走运。

基本上,对于开发人员来说,拥有一个getFieldName(object)(首先对于局部变量是不可能的)是非常令人沮丧的,并且只有当那些属性存在时才起作用。

因此,在可预见的将来,您将无法使用getFieldStrings。无耻的插件:IntelliJ似乎可以很好地处理反射问题:编写Minecraft
mods我也很了解,可以说IntelliJ大大减少了重构工作。但是对于大多数现代IDE来说,情况可能也是这样:我敢肯定,大型参与者,Eclipse,Netbeans
等。 拥有实施良好的重构系统



 类似资料:
  • 我已经建立了一个字段声明列表,需要找出每个字段的名称: 我找不到任何检索字段名称的方法。 奇怪的是,其中一个构造函数确实接受一个字段参数,所以不确定为什么它没有getter。我需要从另一个节点获取它吗? FieldDeclaration(节点列表修饰符、类型、字符串名称)创建一个FieldDeclaration。https://www.javadoc.io/doc/com.github.javap

  • 我使用的是ApacheJMeter5.3。我有一个HTTP请求,它返回JSON响应,如下所示: 有没有办法使用JSON提取器从“certificates”对象(本例中为4b89aa6c131)中提取第一个字段名?

  • 本文向大家介绍postgresql 实现获取所有表名,字段名,字段类型,注释,包括了postgresql 实现获取所有表名,字段名,字段类型,注释的使用技巧和注意事项,需要的朋友参考一下 获取表名及注释: 过滤掉分表: 加条件 and relchecks=0 即可 获取字段名、类型、注释、是否为空: 补充:PostgreSQL查询表主键及注释内容 网上关于pgSql获取表主键的内容都是千篇一律,并

  • 我试图制作一个方法,获取封闭实例中的任何字段,对于一对2D坐标(其字段名以“X”结尾)的任何“X”组件具有整数值。 但我在编译器中得到的只是: 方法将这样使用: 我做错了什么?

  • 我有一个包含大量成员的类,我想检查每个成员是否为null。我不想手动添加它,只要运行一个for循环(或类似的东西),每次添加一个字段时,它将遍历所有字段,而不需要“人工”添加。 到目前为止,我可以查看字段,并收到字段的名称(这是我所需要的)。然而,字段上并没有检查其值是否为null的内容。 以下是我目前掌握的情况: - 在此示例中,打印将为: 缺少名称1 缺少名称3

  • 因此,我正在对其执行JSR-303 bean验证的类有两个字段,每个字段都应用了相同的模式约束: 重要信息-此类不是经典Spring MVC webapp中的表单支持类,而是位于web服务基础上的实体类。因此,验证正在服务中进行。 现在,使用web服务的web客户端是一个Spring MVC,它有一个表单支持bean,该bean与jsp绑定,并带有放置错误消息的位置。 因此,假设用户在这两个字段中