问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

...String str=new String("a") 这个语句创建了几个对象。

发布网友 发布时间:2024-10-23 13:58

我来回答

4个回答

热心网友 时间:2024-11-13 22:50

答案:两个,一个是字符串字面量"xyz"所对应的、驻留(intern)在一个全局共享的字符串常量池中的实例,另一个是通过new String(String)创建并初始化的、内容与"xyz"相同的实例

这是根据Java语言规范相关规定可以给出的合理答案。考虑到Java语言规范中明确指出了:
The Java Language Specification, Third Edition 写道
The Java programming language is normally compiled to the bytecoded instruction set and binary format defined in The Java Virtual Machine Specification, Second Edition (Addison-Wesley, 1999).

也就是规定了Java语言一般是编译为Java虚拟机规范所定义的Class文件,但并没有规定“一定”(must),留有不使用JVM来实现Java语言的余地。
考虑上Java虚拟机规范,确实在这段代码里涉及的常量种类为CONSTANT_String_info的字符串常量也只有"xyz"一个。CONSTANT_String_info是用来表示Java语言中String类型的常量表达式的值(包括字符串字面量)用的常量种类,只在这个层面上考虑的话,这个解答也没问题。
所以这种解答可以认为是合理的。

值得注意的是问题中“在运行时”既包括类加载阶段,也包括这个代码片段自身执行的时候。下文会再讨论这个细节与楼主原本给出的问题的关系。

碰到这种问题首先应该想到去查阅相关的规范,这里具体是Java语言规范与Java虚拟机规范,以及一些相关API的JavaDoc。很多人喜欢把“按道理说”当作口头禅,规范就是用来定义各种“道理”的——“为什么XXX是YYY的意思?”“因为规范里是这样定义的!”——无敌了。

在Java虚拟机规范中相关的定义有下面一些:

The Java Virtual Machine Specification, Second Edition 写道
2.3 Literals

A literal is the source code representation of a value of a primitive type (§2.4.1), the String type (§2.4.8), or the null type (§2.4). String literals and, more generally, strings that are the values of constant expressions are "interned" so as to share unique instances, using the method String.intern.

The null type has one value, the null reference, denoted by the literal null. The boolean type has two values, denoted by the literals true and false.

2.4.8 The Class String

Instances of class String represent sequences of Unicode characters (§2.1). A String object has a constant, unchanging value. String literals (§2.3) are references to instances of class String.

2.17.6 Creation of New Class Instances

A new class instance is explicitly created when one of the following situations occurs:

Evaluation of a class instance creation expression creates a new instance of the class whose name appears in the expression.
Invocation of the newInstance method of class Class creates a new instance of the class represented by the Class object for which the method was invoked.

A new class instance may be implicitly created in the following situations:

Loading of a class or interface that contains a String literal may create a new String object (§2.4.8) to represent that literal. This may not occur if the a String object has already been created to represent a previous occurrence of that literal, or if the String.intern method has been invoked on a String object representing the same string as the literal.
Execution of a string concatenation operator that is not part of a constant expression sometimes creates a new String object to represent the result. String concatenation operators may also create temporary wrapper objects for a value of a primitive type (§2.4.1).

Each of these situations identifies a particular constructor to be called with specified arguments (possibly none) as part of the class instance creation process.

5.1 The Runtime Constant Pool

...

● A string literal (§2.3) is derived from a CONSTANT_String_info structure (§4.4.3) in the binary representation of a class or interface. The CONSTANT_String_info structure gives the sequence of Unicode characters constituting the string literal.

● The Java programming language requires that identical string literals (that is, literals that contain the same sequence of characters) must refer to the same instance of class String. In addition, if the method String.intern is called on any string, the result is a reference to the same class instance that would be returned if that string appeared as a literal. Thus,
Java代码
("a" + "b" + "c").intern() == "abc"

must have the value true.

● To derive a string literal, the Java virtual machine examines the sequence of characters given by the CONSTANT_String_info structure.

○ If the method String.intern has previously been called on an instance of class String containing a sequence of Unicode characters identical to that given by the CONSTANT_String_info structure, then the result of string literal derivation is a reference to that same instance of class String.

○ Otherwise, a new instance of class String is created containing the sequence of Unicode characters given by the CONSTANT_String_info structure; that class instance is the result of string literal derivation. Finally, the intern method of the new String instance is invoked.

...

The remaining structures in the constant_pool table of the binary representation of a class or interface, the CONSTANT_NameAndType_info (§4.4.6) and CONSTANT_Utf8_info (§4.4.7) structures are only used indirectly when deriving symbolic references to classes, interfaces, methods, and fields, and when deriving string literals.

把Sun的JDK看作参考实现(reference implementation, RI),其中String.intern()的JavaDoc为:
JavaDoc 写道
public String intern()

Returns a canonical representation for the string object.

A pool of strings, initially empty, is maintained privately by the class String.

When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned.

It follows that for any two strings s and t, s.intern() == t.intern() is true if and only if s.equals(t) is true.

All literal strings and string-valued constant expressions are interned. String literals are defined in §3.10.5 of the Java Language Specification

Returns:
a string that has the same contents as this string, but is guaranteed to be from a pool of unique strings.

===============================================================

再换一个问题来问:
引用
问题:
Java代码
String s = new String("xyz");
涉及用户声明的几个String类型的变量?

答案也很简单:
引用
答案:一个,就是String s。

把问题换成下面这个版本,答案也一样:
引用
问题:
Java代码
String s = null;
涉及用户声明的几个String类型的变量?

Java里变量就是变量,引用类型的变量只是对某个对象实例或者null的引用,不是实例本身。声明变量的个数跟创建实例的个数没有必然关系,像是说:
Java代码
String s1 = "a";
String s2 = s1.concat("");
String s3 = null;
new String(s1);

这段代码会涉及3个String类型的变量,
1、s1,指向下面String实例的1
2、s2,指向与s1相同
3、s3,值为null,不指向任何实例

以及3个String实例,
1、"a"字面量对应的驻留的字符串常量的String实例
2、""字面量对应的驻留的字符串常量的String实例
(String.concat()是个有趣的方法,当发现传入的参数是空字符串时会返回this,所以这里不会额外创建新的String实例)
3、通过new String(String)创建的新String实例;没有任何变量指向它。

===============================================================

回到楼主开头引用的问题与“标准答案”
引用
问题:
Java代码
String s = new String("xyz");
创建了几个String Object?
答案:两个(一个是“xyz”,一个是指向“xyz”的引用对象s)

用归谬法论证。假定问题问的是“在执行这段代码片段时创建了几个String实例”。如果“标准答案”是正确的,那么下面的代码片段在执行时就应该创建4个String实例了:
Java代码
String s1 = new String("xyz");
String s2 = new String("xyz");

马上就会有人跳出来说上下两个"xyz"字面量都是引用了同一个String对象,所以不应该是创建了4个对象。

那么应该是多少个?

运行时的类加载过程与实际执行某个代码片段,两者必须分开讨论才有那么点意义。

为了执行问题中的代码片段,其所在的类必然要先被加载,而且同一个类最多只会被加载一次(要注意对JVM来说“同一个类”并不是类的全限定名相同就足够了,而是<类全限定名, 定义类加载器>一对都相同才行)。

根据上文引用的规范的内容,符合规范的JVM实现应该在类加载的过程中创建并驻留一个String实例作为常量来对应"xyz"字面量;具体是在类加载的resolve阶段进行的。这个常量是全局共享的,只在先前尚未有内容相同的字符串驻留过的前提下才需要创建新的String实例。

热心网友 时间:2024-11-13 22:54

String str=new String("a")
创建两个对象是正确的,当执行该语句时,系统会在栈中创建一个对象,在堆中创建一个字符串常量池,然后在里面寻找是否有“a“,如果有则通过栈中的对象引用此值,如果没有系统会再创建一个”a“来引用~~
所以说是创建了两个对象~~
希望对你有所帮助~~

热心网友 时间:2024-11-13 22:50

String类型是引用型的数据类型,也算是基本的数据类型,但是他比较特殊。
String str=new String("a")说明他是引用型的的,用了new关键字在堆里创建了一个字符串对象,然后是指向str的引用。
String str="a"是把string当基本类型的使用,直接给它初始化。
这两个的结果是一样的,但是存储的过程是不同的,一个在堆里,一个在栈里,对于学习后面的数据操作就可以看出来了。
多练习就理解了

热心网友 时间:2024-11-13 22:52

这个要看是在什么情况下 在编译阶段和运行阶段是不同的 都给你提示道这个程度了 剩下的你懂的哦(内存堆栈)
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
在筋骨堂治疗腰椎间盘突出一个疗程后已有好转,隔了三、四天又疼上了... 美的3⃣️匹柜机空调为什么不制热是什么原因? 小票打印机不出字的原因及解决方法如何解决小票打印机无法打印字的问题... 电脑打单打印机出不了小票超市收银台电脑键盘怎么用 交易房屋如何分类 城市规划用途分类该怎么做 规划用途的分类 ...打火机散件设备公司 值得信赖么 ?是不是《骗子》皮包公司? 希望给予... 哈尔滨农垦太阳神打火机散件厂是否骗人 有没有人知道网上那些打火机加工的广告是不是真是可靠?做打火机反销... 梦见修房子是什么预兆梦见修房子的寓意 衡水学院十月一放假能会家吗? 一级建造师合格线是怎么定的 一级建造师各科考多少分能过 都江堰上元古道徒步路线_八泉峡青龙峡红豆峡游玩顺序 想学手机、电脑硬件维修哪位师傅收学徒? 因家境贫寒不能念书,出门想学一门手艺,学什么好? 魔炼大陆游学记txt全集下载 我感觉前途渺茫怎么办 我的世界0.15.6怎么联机 登录注册都进不了直接闪回 我的世界0.15为什么按登录的时候进去一会就显示登录0Xbox live账号失败... 我的世界0.15为什么不能登录 安武林金蜘蛛诗意童心系列内容简介 泥巴男生内容简介 他最多有五个朋友。英语翻译 他几乎不懂英语,但他有几个英国朋友. 翻译句子 梦见熬药锅子打碎了什么意思 英语翻译。他有很多朋友,其中有两个是外国人! ...与 String str = new String("hello"); 有什么区别? 求一霸气的游戏名 String str=new String(""a");是两个还是三个对象 事实婚姻与婚姻的关系是怎样的 梦见修房子是什么预兆梦见修房子的寓意 神农架是哪个地区管 有没有男女对唱的英文歌?像way back into love一样的。推荐几首... 房产租赁管理系统软件 速腾、朗逸、朗动、4cl质量谁好 java中String s=new String("abc");创建了几个String对象? 梦见修房子是什么预兆梦见修房子的寓意 我的电脑有个文件删不了了!怎么删除?没查出病毒! 总是显示不在该位置... ...买z114从哈尔滨到广州,再买z111从广州到海口,可以不下车吗?_百度知 ... String str = nem String("1"+"2")产生了几个对象? 现代朗动和速腾哪个好 我想询问下从招远到济南最早是几点的车,到了济南以后怎么去飞机场,要详... 招远到济南长途汽车首班车发车时间和票价 虚幻四Gameplay Ability System入门(5)-冲刺奔跑和深入Attribute_百度... 电脑中的文件夹删除不了是怎么回事?明明在这个文件夹中却显示的是:该... 神农架是哪个市 神农架行政区划 雪鹰领主男主东伯雪鹰有几个女人-雪鹰领主男主东伯雪鹰结局和谁在一...