`

java 堆 栈

 
阅读更多
由String看Java堆栈问题,包括==以及equal()。
首先看代码:
1
Java代码 复制代码 收藏代码java 堆 栈 - 依米 - 菜鸟,努力!
public class TestString {  
    public static void main(String[] args) {  
        String a0 = "abc";  
        String b0 = "abc";  
        if (a0 == b0) {  
            System.out.print("==");  
        } else {  
            System.out.print("!=");  
        }  
    }  


执行结果为:
==
2
Java代码 复制代码 收藏代码java 堆 栈 - 依米 - 菜鸟,努力!
public class TestString {  
    public static void main(String[] args) {  
        String a0 = String.valueOf("abc");  
        String b0 = String.valueOf("abc");  
        if (a0 == b0) {  
            System.out.print("==");  
        } else {  
            System.out.print("!=");  
        }  
    }  



执行结果为:
==
3
Java代码 复制代码 收藏代码java 堆 栈 - 依米 - 菜鸟,努力!
public class TestString {  
    public static void main(String[] args) {  
        String a0 = "abc"+"def";  
        String b0 = "abcdef";  
        if(a0==b0){  
            System.out.print("==");  
        }else{  
            System.out.print("!=");  
        }  
    }  

执行结果为:
==
4
Java代码 复制代码 收藏代码java 堆 栈 - 依米 - 菜鸟,努力!
public class TestString {  
    public static void main(String[] args) {  
                  String a0 = "abc";  
        String b0 = "def";  
        String c0 = "abcdef";  
        String d0 = a0 + b0;  
        if (c0 == d0) {  
            System.out.print("==");  
        } else {  
            System.out.print("!=");  
        }  
    }  

执行结果为:
!=
5
Java代码 复制代码 收藏代码java 堆 栈 - 依米 - 菜鸟,努力!
public class TestString {  
    public static void main(String[] args) {  
        String a0 = new String("abc");  
        String b0 = new String("abc");  
        if (a0 == b0) {  
            System.out.print("==");  
        } else {  
            System.out.print("!=");  
        }  
    }  


执行结果为:
!=
6
Java代码 复制代码 收藏代码java 堆 栈 - 依米 - 菜鸟,努力!
public class TestString {  
 
    public static void main(String[] args) {  
 
        String a0 = String.valueOf("abc")+String.valueOf("def");  
        String b0 = String.valueOf("abcdef");  
 
        if (a0 == b0) {  
            System.out.print("==");  
        } else {  
            System.out.print("!=");  
        }  
    }  
 


执行结果为:
!=
我们的都知道,Java的内存分配策略:栈中存放基本数据类型(或者叫内置类型)以及引用类型(或者叫对象句柄),而堆中存放对象数据。
String很特殊,根据Think In Java介绍:“通过编译器和特殊的覆盖或过载运算符+和+=,可将引号字符串转换成一个String”。可见引号字符串本身并不是一个String,而是通过运算符的重载转换成了String。注意:没有=号。
故此:我们要问,引号字符串通过重载以后转换成String存在于什么位置?
查询网上没有具体的分析,书籍上也没有准确的说明。
根据执行结果猜想:
学习过类加载可能知道,有个常量区。
暂且假设将此部分数据存放于此空间中,看能否得到合理的解释。
Java的内存分配栈中存放两种类型数据:
1、基本数据类型:此处疑问?存放的是具体的数据还是也是一个内存地址。
假设1:栈中存放的是具体的数据,当然所有出现在基本类型的操作均可以解释。
假设2:数据存放于上边提到的常量区,而栈中存放的是此常量区对应数据的地址。所有基本数据类型操作似乎也可以解释。
其实Java设计师们很注重内存的利用,我们可能看见很多文章曾提到这样一个概念,当int n =1;时,Java会在内存中搜索,看有没有1的存在,假如有的话,则不会重新分配空间建立1,如果没有的话,则会建立1,假如int m=1;则Java不会再建立1的空间。可见似乎内存中存在一个存放数据的地方。如果用次观点解释假设2完全成立。
现在以下的结论均在假设2下展开。
2、引用类型:栈中存放的是对象的引用,此引用是通过new创建的对象在对中分配的地址。
现在分析String。
属于什么类型?基本数据类型、引用类型。
当作为String str = "abc";建立时,作为基本类型的假设2合理一些(参见第1部分代码)。
当作为String str = new String("abc");建立时,毫无疑问作为引用类型处理(参见第5部分代码)。
我们暂且将+作为一种Java特殊的处理机制,当它处理引号字符串时不会采用new方式建立String(即像"abc"+"def"),而对于栈中数据处理时会采用new方式建立String(即像a+b)。(参见第3、4、6部分代码)。
当作为String str = String.valueOf("abc");建立或者执行+时,完全可以解释通过。
其实String.valueOf()可以看做是对"abc"的封装,但不是new的(参见第2、6部分代码)。
其实现在要是按照以上的观点,可以得出这样一种结论:
栈中存放的是句柄,包括基本数据类型。内存中存在另外一块区域(常量区),存放基本数据类型数据以及引号字符串数据。
堆中存放的是对象,且必须是new的或者通过+运算符的重载隐式new的。
乱想了一通,与一些理论违背,因为好多东西解释不通,所以胡思乱想了。
欢迎评论,谢谢。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics