- 浏览: 160787 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
zbg1983:
jumboluo 写道这是一个Ext的一个bug:http:/ ...
EXTJS4 郁闷的Loading -
caelyntang:
在二级联动加载的时候提前加载一次二级联动,不是根据一级联动的值 ...
EXTJS4 郁闷的Loading -
55558888:
将 queryMode: 'local', 改为 query ...
EXTJS4 郁闷的Loading -
jumboluo:
这是一个Ext的一个bug:http://www.sencha ...
EXTJS4 郁闷的Loading -
jumboluo:
也遇到同样的问题,也不知道怎么解决啊。
EXTJS4 郁闷的Loading
由String看Java堆栈问题,包括==以及equal()。
首先看代码:
1
执行结果为:
==
2
执行结果为:
==
3
执行结果为:
==
4
执行结果为:
!=
5
执行结果为:
!=
6
执行结果为:
!=
我们的都知道,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的。
乱想了一通,与一些理论违背,因为好多东西解释不通,所以胡思乱想了。
欢迎评论,谢谢。
首先看代码:
1
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
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
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
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
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
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的。
乱想了一通,与一些理论违背,因为好多东西解释不通,所以胡思乱想了。
欢迎评论,谢谢。
评论
10 楼
tf03172003
2009-09-15
从4楼这里,学到一些东西:
只有"abc" + "def"是在常量池中操作,其他的比如:a0 + b0, String.valueOf("abc") + String.valueOf("def")等等都是对象操作
只有"abc" + "def"是在常量池中操作,其他的比如:a0 + b0, String.valueOf("abc") + String.valueOf("def")等等都是对象操作
9 楼
gao_20022002
2008-07-02
几天没有来了,呵呵。
感谢各位的支持。
让高手们见笑了。
感谢各位的支持。
让高手们见笑了。
8 楼
zhangxi123
2008-07-01
今天是第二次看到这样的内容了!其实他们原理是很简单的没必要这么深究!《JAVA优化编程》对String的讲解非常详细!
如果真想研究java的堆栈的话请读《深入java虚拟机》!如果想学习java基础方面的东西《java编程思想》是必不可少的!
如果真想研究java的堆栈的话请读《深入java虚拟机》!如果想学习java基础方面的东西《java编程思想》是必不可少的!
7 楼
bearice
2008-06-29
JVM的实现不保证具有相同内容的字符串一定具有相同的引用,一般来说,在类初始化时根据常量构造的相同字符串引用是相同的,后续构造出的字符串引用可能不同。要保证相同字符串引用相同,请使用intern方法。其他信息请参看JLS
6 楼
mercyblitz
2008-06-27
不客气!
5 楼
gao_20022002
2008-06-27
非常感谢mercyblitz的分析。
无意之间看到一篇关于此问题的文章,与大家共同分享。
http://gao-20022002.iteye.com/blog/208788
找不到原文了,自己转载一下。
无意之间看到一篇关于此问题的文章,与大家共同分享。
http://gao-20022002.iteye.com/blog/208788
找不到原文了,自己转载一下。
4 楼
mercyblitz
2008-06-27
我非常欣赏你的这种深入精神,不过我要指出一点你的误解:
首先,String一定是对象,是引用类型(大概你知道Java底层有三种数据类型,这里不错说了),你看看String的实现,他其实在类中有一个
我们暂且将+作为一种Java特殊的处理机制,当它处理引号字符串时不会采用new方式建立String(即像"abc"+"def"),而对于栈中数据处理时会采用new方式建立String(即像a+b)。(参见第3、4、6部分代码)。
在String两个常量“+”操作时,在底层的确在new String,实际上建立这一个StringBuilder()(参看Java语言规范);以你的例子:
在此层操作为
new StringBuilder().append("abc").append("def").toString(),
参考StringBuilder的toString(),实际上它又是对原字符的复制,而不是重新,他会复制字符串的地址。
这样的代码3就可以得到解释,对于非常量,如代码4中,即对象的“+”操作,这个实际上是C++的符号重载(实际上面也是重载),编译器会去判断(他们是对象,非常量),所以不会相等。代码6是同理,看看String.valueOf()方法的实现:
引用
当作为String str = "abc";建立时,作为基本类型的假设2合理一些(参见第1部分代码)。
首先,String一定是对象,是引用类型(大概你知道Java底层有三种数据类型,这里不错说了),你看看String的实现,他其实在类中有一个
private final char value[];,作为类的一个属性,这有可以说明为什么String不变,若在大于默认规定大小,String会动态的变化,但是一旦new只有里面的value是不会变化的,除非创建第二个对象。
引用
我们暂且将+作为一种Java特殊的处理机制,当它处理引号字符串时不会采用new方式建立String(即像"abc"+"def"),而对于栈中数据处理时会采用new方式建立String(即像a+b)。(参见第3、4、6部分代码)。
在String两个常量“+”操作时,在底层的确在new String,实际上建立这一个StringBuilder()(参看Java语言规范);以你的例子:
在此层操作为
new StringBuilder().append("abc").append("def").toString(),
参考StringBuilder的toString(),实际上它又是对原字符的复制,而不是重新,他会复制字符串的地址。
这样的代码3就可以得到解释,对于非常量,如代码4中,即对象的“+”操作,这个实际上是C++的符号重载(实际上面也是重载),编译器会去判断(他们是对象,非常量),所以不会相等。代码6是同理,看看String.valueOf()方法的实现:
public static String valueOf(Object obj) { return (obj == null) ? "null" : obj.toString(); }
3 楼
wangshu3000
2008-06-27
看不太明白。。。台基础了。。。对于“”+“”之类的不太懂。。。
2 楼
yeyongjin
2008-06-27
1 楼
rendq
2008-06-27
看了以后觉得不错,我也对相关程序进行了测试,仍持有个人看法:4,5,6三段程序中的if条件改成这样
if (a0.equals(b0)) { System.out.print("=="); } else { System.out.print("!="); }的话,结果就大相径庭了。在JAVA中,==比较的是地址,而equals()比较的是字面值。基本数据类型确实是一个内存地址,所以在示例1,2,3中可以完全成立。拿4来说吧,d0存方的是"abc"和"def"的两个地址,而c0只有"abcdef"一个地址,条件自然不能成立。
发表评论
-
EXTJS4 郁闷的Loading
2011-12-27 22:24 3268使用EXTJS4,写联动的combo控件,首次选择联动效果,可 ... -
我想,我得回到servlet中去!
2008-12-30 14:58 977华丽的外表掩盖了太多的实质。 servlet真的很强大,重 ... -
propedit,OK!
2008-12-30 14:52 1491在eclipse下开发,建立个messages_zh_CN.p ... -
简单示例搭建框架之一
2008-12-19 13:59 2328一直自己搭建框架的意 ... -
http://www.androidcn.net/wiki/index.php/
2008-12-01 15:28 0http://www.androidcn.net/wiki/i ... -
Android竟然会出现这样的问题??
2008-12-01 14:11 1085运行android程序后,我的磁盘空间不断减少,不知道为什么? ... -
Zip压缩继续分析
2008-11-24 10:58 1114前面的一篇文章说明了压缩以及解压缩,但是对于字节流的分析表示, ... -
java中的压缩以及解压类
2008-11-22 08:40 1819在查看zip以及unzip的时候,看到了这两个类(Deflat ... -
关于zip文件的字节码处理
2008-11-21 09:39 1228昨天写了一篇关于压缩文件以及压缩文件解压问题,现在对于自己压缩 ... -
Zip以及UnZip处理
2008-11-20 11:26 1399早上看到一篇关于压缩文件的处理文章,测试之后发现解压缩unzi ... -
自己写资源串处理文件
2008-11-19 14:13 1027本文主要是模拟配置文件中的资源串文件,将最终处理结果存放于Ma ... -
自己处理公式
2008-11-18 15:03 988问题说明: 给定一个字符串,例如: String gsstri ... -
到底谁的效率高??
2008-11-17 11:24 1093在写代码的时候,常常使用if-else显得很麻烦,对于简单的赋 ... -
代理、监听器的理解,希望指点。
2008-10-31 17:29 924首先定义一个接口: public interface IWor ... -
手机触摸屏程序开发
2008-10-24 14:15 2433使用J2ME技术实现手机触摸屏开发的方法: 首先的修改调试环 ... -
J2EE中的基础知识
2008-10-23 12:58 1018转载:用于学习 J2EE ... -
OO的五大原则
2008-10-22 16:08 872OO的五大原则 OO的五大原则是指SRP、OCP、 ... -
奇怪而又无可厚非的类加载顺序
2008-10-21 09:05 4046昨天看到这样一篇帖子 ... -
笔试题目(摘)
2008-10-15 12:34 01、计算机系统中采用补 ... -
think in java回顾整理之RTTI
2008-10-10 15:08 2678运行期类型鉴定(RTTI)的概念初看非常简单——手上只有基础类 ...
相关推荐
equal与==区别,从三个方面,进行举例比较。
Java语言是sun公司的开发成果,他的主要特点是可以执行强,与平台的无关性使他的实用性更强。但是Java中的==与equal是有区别的。
JAVA Integer == equal 比较 doc 比较大小 是否相等
主要介绍了浅析java中String类型中“==”与“equal”的区别,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
本文详细描述了==与equal() 的区别 初学者可以很好很专业的理解其区别
Java_详解_1、==和Equal用法与比较
JButton equal=new JButton("="); JButton point=new JButton("."); JButton plus=new JButton("+"); JButton minus=new JButton("-"); JButton multi=new JButton("×"); JButton division=new JButton("÷")...
【Java面试题】equals与==的区别
介绍了java中 == 与 equal 的区别,有需要的朋友可以参考一下
主要介绍了java 中equals和==的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
在对字符串的相等判断,==判断的是地址是否相同,equal()判断的是字符值是否相同。大多数时候==跟equal()的结果都是相同的。
详细介绍了java String 中的“==”和“equal”
Button bPoint,bEqual,bPlus,bMinus,bClear,bMulti,bDivision; //运算符按钮 Button[] b=new Button[10]; //数字按钮 String currentOp,preOp; //当前操作和上一步操作 String foreText,backText; //...
/* 定义有final的变量为最终变量不能为其赋值. ... public static void main(String args[]) { Test1 t1=new Test1(); //t1.a=33;//无法为最终变量 a 指定值 System.out.println(t1.a); } }
安装npm install string-hashcode 例子var hashCode = require ( 'string-hashcode' ) ;var s = 'abc' ;console . log ( s . hashCode ) ; // undefinedvar code = hashCode ( s ) ;console . log ( s . hashCode ) ...
2、程序流程图 详细设计 import java.awt.BorderLayout; //导入AWT页面设置类 import java.awt.Button; //导入AWT按钮类 import java.awt.Frame; import java.awt.GridLayout; import java.awt.Panel; import java....
18、Java中String的了解 19、String为什么要设计成不可变的? 20、Object类的equal和hashCode方法重写,为什么? 21-40题 21、List,Set,Map的区别 26、ArrayMap和HashMap的对比 29、HashMap和HashTable的区别 ...
//此对象中保存了页面的所有情况,包括多少页等信息 public PaginationBean getPagePagination() { return pagination; } /** * * */ //实例化PaginationBean的构造函数 public void Init...
Struts Logic标签库中包含的标签列表 Tag name Description empty 如果标签parameter,propertie等属性所指定的变量值为null或空字符串,则处理标签包含的内容 equal 如果标签parameter,propertie等属性所指定的...
[Java学习笔记01] 最近在学习Java程序设计,学到“==”和Object类中的equals()方法的时候有点混乱。 上结论!!! “==”:用于判断二者是否同一,即二者的引用变量是否指向同一个对象。 Object.equals():用于判断...