云计算爱好者V 2016-08-11 09:09 采纳率: 33.3%
浏览 1040
已采纳

java的内存问题(堆,常量池)

刚开始学java,今天遇到三个不太懂的地方,问题是这样的:

问题一:
堆中的方法区是用来存放类的信息,其中包括方法代码(比如study()方法)。
老师说,新建的对象的方法是使用指针指向方法区类的方法代码,那么如果用这个类新建两个对象,两个对象中的study()方法都是指向方法区的同一个地址吗?

问题二:
常量池中如果已经存在某一个字符串了(如"java"),那么再新建一个变量,为它赋值为"java",那么这个变量是不是指向之前已经存在的那个"java"的地址?这样如果常量池中有很多常量,每次新建时程序都要去常量池挨个寻找吗?会不会太麻烦。

问题三:
java中可以像C++中一样打印某一个变量的地址吗?

谢谢。

  • 写回答

3条回答

  • CanvaChen 2016-08-11 14:20
    关注

    一、同一个类的方法是被各个实例对象共用的,指向的地址一样。
    对比:这和属性不同,属性一般每个对象都有自己的一份,当然了静态属性也是共用的。
    二、很多问题自己是可以测试的,学会自己测试很重要,比如这个问题,帮你写个junit测试一下更明了:
    @Test
    public void testString(){
    String s1 = "java";
    String s2 = "java";
    System.out.println("s1 eq s2?"+s1.equals(s2));
    System.out.println("s1 == s2?"+(s1==s2));
    }
    串口的输出为:
    s1 eq s2?true
    s1 == s2?true
    从第一个可以看出,s1和s2值是相等的,这很显然;从第二个可以看出,s1和s2地址也是相同的。这是因为s1和s2都直接用赋值号引用"java"。
    但是!别得意,再看一种情况。
    @Test
    public void testString(){
    String s1 = "java";
    String s2 = "java";
    String s3 = new String("java");
    System.out.println("s1 eq s2?"+s1.equals(s2));
    System.out.println("s1 == s2?"+(s1==s2));
    System.out.println("s1 eq s3?"+s1.equals(s3));
    System.out.println("s1 == s3?"+(s1==s3));
    }
    结果为:
    s1 eq s2?true
    s1 == s2?true
    s1 eq s3?true
    s1 == s3?false
    可以看到,s1和s3值相等,但是地址不同,这是因为s3是在其他地址上动态开辟出来的,只是初始化时值也为"java"。
    三、java中打印出来的地址是哈希码,不是真正的地址。
    其实就算C语言中的指针,也只是逻辑地址而不是物理地址,搞应用开发的虽然可以直接操作内存,不过也是在操作系统分配好的内存段内操作。此外操作系统中地址还有地址映射的问题。搞过单片机开发的人应该对操作物理地址和寄存器比较了解,那些就交给搞底层开发的人做吧。
    最后,希望你遇到问题可以学会自己写测试程序解决问题,祝学习进步!

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 shape_predictor_68_face_landmarks.dat
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料