Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
关于Java对象方法的信息保存在哪里?_Java_Class_Object_Memory_Jvm - Fatal编程技术网

关于Java对象方法的信息保存在哪里?

关于Java对象方法的信息保存在哪里?,java,class,object,memory,jvm,Java,Class,Object,Memory,Jvm,我的同事刚刚问了我一个非常有趣的问题,我无法给他答案 假设我们有以下类: public class Person { String name; public Person(String name) { this.name = name; } public void print() { System.out.println("xxx"); } } 现在,我们正在创建对象: Person p1 = new Person("

我的同事刚刚问了我一个非常有趣的问题,我无法给他答案

假设我们有以下类:

public class Person {
    String name;

    public Person(String name) {
        this.name = name;
    }

    public void print() {
        System.out.println("xxx");
    }
}
现在,我们正在创建对象:

Person p1 = new Person("a");
Person p2 = new Person("b");
Person p3 = new Person("c");
Person p4 = new Person("d");
Person p5 = new Person("e");
Person p6 = new Person("f");
Person p7 = new Person("g");
Person p8 = new Person("h");
问题是:

我们是否在每个对象中保留可用方法的信息?如果我们创建一个新对象
p9
,JVM会创建一个只包含字段信息的对象,还是会向这个对象添加方法信息

另一个问题:


如果调用
p1.print()
,会发生什么?
p1
是否必须要求
Person
类提供此方法,或者它是否已保存在
p1
对象中?

方法的代码并非对所有实例都重复,这是完全不必要的。代码存在于内存中的一个特殊区域中,它由所有实例共享。另一方面,实例变量所需的内存自然属于每个实例

至于如何调用方法,对象并不需要每次调用方法时都询问类,它有一个指向方法代码的指针,可以立即调用它


有关JVM内部工作的更多信息,请参阅此处:

通常,代码只表示一次,而不管有多少个对象。对象“拥有”方法的OO概念只是一种抽象。所以,本质上,无论方法是实例化的还是静态的,在幕后它仍然“属于”类

对于最终的方法,调用使用静态绑定(根据表达式的类型,已经预先确定了将调用哪个方法)


对于虚拟方法,会发生一些更有趣的事情。根据实现的不同,要么对象包含正确方法的地址(同样不是方法本身),要么运行时对该对象进行反射,以确定其实际类并在层次结构中找到适当的方法。

我不知道Oracle JVM是如何做到这一点的,但在一般的面向对象编程系统中,对象具有指向其类的隐藏实例变量。所有实例都指向同一个类对象,而指向实例方法的指针是该类的一部分。

JVM通过不将对象和方法绑定在一起而做了出色的工作。要清楚地了解它的功能,您需要了解它的底层架构

JVM有一个类加载器系统,它由以下资源组成:

  • 方法区域
  • Java堆栈
  • PC寄存器
  • 本机方法堆栈。

  • 当我们创建一个对象时,类被加载(延迟加载)并获得所有必需的资源。在这里的方法区域中,所有方法和对象都驻留在堆中,并且在所有线程之间共享。JVM将执行程序所需的所有内存分配/组织到几个运行时内存区域中

    @Vallentin你建议他用什么术语搜索?@KevinWorkman这个问题怎么样?@Vallentin我觉得这个问题很有趣。请记住,Google经常会发现StackOverflow问题作为答案。这个问题只需要问一下。然而,在这种情况下,也有类似的问题,但关键是它是QA站点。这个特殊的内存区域称为堆,对吗?:-)不是堆。