如何在java中获取调用该方法的对象的名称?

How to get the name of the object that is calling the method in java?

提问人:prateek khanal 提问时间:6/17/2023 更新时间:6/19/2023 访问量:73

问:

我试图创建一个方法,该方法打印调用该方法的“对象名称”以及同一对象的“字段值”。


class ProgLang {
    String language;

    // Constructor to set the language field of the object as per the argument given
    ProgLang(String lang) {
        this.language = lang;
    }

    // method to check the field of an object
    void getField() {
        System.out.println("\n Programming Language of "+ this + " : " + this.language);
    }
}

public class ConstructorOverLoading {
    public static void main(String[] args) {
        //create a instance of ProgLang class
        ProgLang obj1 = new ProgLang("Python");

        // get the value of the language field
        obj1.getField();

    }
}

我期望的输出是:-

Programming Language of obj1 : Python

但输出是:-

Programming Language of ProgLang@2f92e0f4 : Python

我是Java OOP的菜鸟。我试图在互联网上查找并阅读了有关方法的信息,所以我用它替换了最终出现错误的方法。getName()thisthis.getName()

如何打印调用该方法的对象的名称?

java 这个

评论

0赞 prateek khanal 6/17/2023
我不太确定“对象调用方法”的措辞是否正确!我提前道歉
2赞 Sweeper 6/17/2023
那是不可能的。如果我这样做了,你期望会发生什么?在这种情况下,“名称”是什么?new ProgLang("Python").getField()
2赞 Sweeper 6/17/2023
顺便说一句,对象自然没有名称。变量是,但变量本身不是对象。
3赞 user16320675 6/17/2023
如果需要实例具有名称,则必须向该类添加一个字段(类似于已发布代码中的字段)namelanguage
1赞 Mark Rotteveel 6/17/2023
ProgLang@2f92e0f4打印是因为你没有覆盖,但你真正想要的是不可能的。变量名称实际上只在源代码中有意义(尽管这是一种简化),在任何情况下,您都无法知道对象被分配到的变量的名称(并且单个对象可以分配给许多变量,或者根本没有,那么它应该使用哪个?toString()ProgLangProgLang

答:

2赞 Hi computer 6/17/2023 #1
1. 程序不关心变量名称

你可以命名它或其他任何名称。我们通常使用有意义的名称,例如因为它更容易被人们理解。obj1apythonLang

2. 执行代码时,JVM 用于存储变量slot

对于这样的代码:

int a= 2;
int b= 3;
int c= a + b;

它将按如下方式执行:

    Code:
      stack=2, locals=4, args_size=1
         0: iconst_2
         1: istore_1
         2: iconst_3
         3: istore_2
         4: iload_1
         5: iload_2
         6: iadd
         7: istore_3
         8: return
      LineNumberTable:
        line 473: 0
        line 474: 2
        line 475: 4
        line 485: 8
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       9     0  args   [Ljava/lang/String;
            2       7     1     a   I
            4       5     2     b   I
            8       1     3     c   I

STEP1:加载常数 2,然后将其存储到 slot1

STEP2:加载常数 3,存储到 slot2

STEP3:加载插槽 1 和插槽 2

STEP4:调用iadd(在操作数堆栈顶部添加2个数字),并存储到slot3。然后返回

3.如果两个局部变量具有不重叠的有限范围,则可以重用插槽

对于这样的代码:

if (true) {
    ProgLang obj1 = new ProgLang("Python");
    obj1.getField();
}
if (true) {
    ProgLang obj2 = new ProgLang("Python");
    obj2.getField();
}

它将像以下方式执行:

    Code:
      stack=3, locals=2, args_size=1
         0: new           #2                  // class ProgLang
         3: dup
         4: ldc           #3                  // String Python
         6: invokespecial #4                  // Method ProgLang."<init>":(Ljava/lang/String;)V
         9: astore_1
        10: aload_1
        11: invokevirtual #5                  // Method ProgLang.getField:()V
        14: new           #2                  // class ProgLang
        17: dup
        18: ldc           #3                  // String Python
        20: invokespecial #4                  // Method ProgLang."<init>":(Ljava/lang/String;)V
        23: astore_1
        24: aload_1
        25: invokevirtual #5                  // Method ProgLang.getField:()V
        28: return
      LineNumberTable:
        line 475: 0
        line 476: 10
        line 479: 14
        line 480: 24
        line 482: 28
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
           10       4     1  obj1   LProgLang;
           24       4     1  obj2   LProgLang;
            0      29     0  args   [Ljava/lang/String;

正如您在 LocalVariableTable 部分中看到的,只有两个插槽。slot0 用于系统参数,slot1 用于 obj1 和 obj2。

由于变量名称与代码无关,因此不会打印。

4. 如果您真的想区分 obj1,请添加另一个字段,例如 或 到类中namevariableName
class ProgLang {
    String variableName;
    String language;

    ProgLang(String lang, String variableName) {
        this.language = lang;
        this.variableName = variableName;
    }

    void getField() {
        System.out.println("\n Programming Language of " + this.variableName + " : " + this.language);
    }
}

class ConstructorOverLoading {
    public static void main(String[] args) {
        ProgLang obj1 = new ProgLang("Python", "obj1");
        obj1.getField();
        ProgLang obj2 = new ProgLang("Python", "obj2");
        obj2.getField();
    }
}

// Programming Language of obj1 : Python
// Programming Language of obj2 : Python

评论

0赞 prateek khanal 6/17/2023
感谢您抽出宝贵时间详细解释。
0赞 Abhijit Sarkar 6/19/2023
不要试图听起来迟钝,而是“向类添加另一个字段,例如 name 或 variableName”是 OP 所需的所有建议。故事的其余部分似乎完全是多余的。