- 浏览: 164780 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
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 3353使用EXTJS4,写联动的combo控件,首次选择联动效果,可 ... -
我想,我得回到servlet中去!
2008-12-30 14:58 1040华丽的外表掩盖了太多的实质。 servlet真的很强大,重 ... -
propedit,OK!
2008-12-30 14:52 1560在eclipse下开发,建立个messages_zh_CN.p ... -
简单示例搭建框架之一
2008-12-19 13:59 2369一直自己搭建框架的意 ... -
http://www.androidcn.net/wiki/index.php/
2008-12-01 15:28 0http://www.androidcn.net/wiki/i ... -
Android竟然会出现这样的问题??
2008-12-01 14:11 1155运行android程序后,我的磁盘空间不断减少,不知道为什么? ... -
Zip压缩继续分析
2008-11-24 10:58 1167前面的一篇文章说明了压缩以及解压缩,但是对于字节流的分析表示, ... -
java中的压缩以及解压类
2008-11-22 08:40 1855在查看zip以及unzip的时候,看到了这两个类(Deflat ... -
关于zip文件的字节码处理
2008-11-21 09:39 1273昨天写了一篇关于压缩文件以及压缩文件解压问题,现在对于自己压缩 ... -
Zip以及UnZip处理
2008-11-20 11:26 1432早上看到一篇关于压缩文件的处理文章,测试之后发现解压缩unzi ... -
自己写资源串处理文件
2008-11-19 14:13 1077本文主要是模拟配置文件中的资源串文件,将最终处理结果存放于Ma ... -
自己处理公式
2008-11-18 15:03 1025问题说明: 给定一个字符串,例如: String gsstri ... -
到底谁的效率高??
2008-11-17 11:24 1137在写代码的时候,常常使用if-else显得很麻烦,对于简单的赋 ... -
代理、监听器的理解,希望指点。
2008-10-31 17:29 954首先定义一个接口: public interface IWor ... -
手机触摸屏程序开发
2008-10-24 14:15 2466使用J2ME技术实现手机触摸屏开发的方法: 首先的修改调试环 ... -
J2EE中的基础知识
2008-10-23 12:58 1090转载:用于学习 J2EE ... -
OO的五大原则
2008-10-22 16:08 955OO的五大原则 OO的五大原则是指SRP、OCP、 ... -
奇怪而又无可厚非的类加载顺序
2008-10-21 09:05 4165昨天看到这样一篇帖子 ... -
笔试题目(摘)
2008-10-15 12:34 01、计算机系统中采用补 ... -
think in java回顾整理之RTTI
2008-10-10 15:08 2708运行期类型鉴定(RTTI)的概念初看非常简单——手上只有基础类 ...
相关推荐
在Java编程语言中,`equal`方法和`==`操作符都是用来比较对象之间是否相等的工具,但它们之间存在重要的差异。本文将从三个方面进行详细的对比分析:字符串的比较、非字符串对象的比较以及基本数据类型的比较。 ###...
Java 中关于 == 和 equal 的区别 及其 equals() 方法重写 Java 语言是 Sun 公司的开发成果,其主要特点是可以执行强,与平台的无关性使其实用性更强。但是 Java 中的 == 与 equal 是有区别的。 == 操作符是 Java ...
JAVA 中的 Integer 比较 在 Java 中,我们经常需要比较两个 Integer 对象是否相等,但是在使用 "==" 运算符时,可能会出现一些意外的结果。本文将深入探讨 Java 中的 Integer 比较,了解为什么使用 "==" 运算符可能...
Java 中的 String 类型是一个基本数据类型,然而在使用 String 类型的时候,我们经常会遇到“==”和 “equal” 两个操作符的使用问题。这两个操作符都是用于比较字符串的,但是它们在比较机制和结果上存在着很大的...
字符串池由 String 类维护,我们可以调用 intern() 方法来访问字符串池。当运用引号内包含文本创建对象时,所创建的对象是加入到字符串池里面的。 只有引号内包含文本创建对象才会将创建的对象放入到字符串池。...
Java_详解_1、==和Equal用法与比较
### Java字符串方法详解 #### 一、创建并初始化字符串 在Java中,字符串是一个非常重要的数据类型,通常用于处理文本信息。字符串一旦创建后不可改变,这是因为它被设计成不可变对象(`immutable object`)。Java...
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面试题】equals与==的区别
### Java常用类与基础API-String的构造器与常用方法 #### 一、String的常用API-1 ##### (1)构造器 1. **介绍** - `public String()`: - 初始化新创建的 `String` 对象,以使其表示空字符序列。即创建了一个...
在Java编程语言中,`equals()` 和 `==` 运算符经常被用来比较对象,但它们之间存在着显著的区别。理解这些差异对于编写正确、健壮的代码至关重要。以下是关于 `equals()` 和 `==` 在Java中的详细解释。 首先,`==` ...
在Java编程语言中,`String` 类是用于表示不可变文本序列的一个重要类。本文将详细介绍 `String` 类的一些常用方法及其应用场景,并通过示例代码加深理解。 #### 1. `length()` - **功能**:返回字符串中的字符...
### JAVA字符串函数详解 在Java编程语言中,字符串处理是一项非常重要的技能,特别是在面试或实际开发过程中。本文将详细介绍《JAVA字符串函数一览》中的关键函数及其用法。 #### 1. `substring()` `substring()`...
在编程领域,字符串(String)是数据处理中非常常见的一种数据类型,用于表示一系列字符。在很多情况下,我们可能需要比较两个字符串是否相等,但不考虑它们的大小写差异。这个任务在各种语言中都有相应的实现方法。...
在Java编程语言中,`String`类是用于处理文本字符串的基本类型之一。由于字符串经常被用来存储和操作文本数据,在实际应用中,对字符串进行比较是非常常见的需求。本文将深入探讨如何在Java中比较字符串,并解释几种...
### Java初学者必知六大问题详解 #### 问题一:我们声明了什么? 在Java中,当我们写下以下代码时: ```java String s = "Hello world!"; ``` 大多数人可能会回答:“声明了一个String类型的变量s,其值为'Hello ...
在Java中,一个`char`类型的变量可以存储一个Unicode字符,而Unicode字符集包含了几乎所有的文字,包括中文。每个Unicode字符都有一个唯一的编码,中文字符也不例外。 中文字符在Unicode中的范围通常是\u4e00到\u9...
- `String` 类在 Java 中是不可变的,这意味着一旦一个 `String` 对象被创建,其内容就不能更改。 - 示例:`String s = "Hello"; s = s + " world!";`,这里创建了两个 `String` 对象,`s` 的引用首先指向 `"Hello...
### Java常用方法详解 ...以上就是关于Java中常用的字符串操作、文本框和文本区、按钮、标签以及选择框的基本用法和实例。熟练掌握这些基本组件和操作能够帮助开发者更高效地进行GUI界面的设计和开发。