精华内容
下载资源
问答
  • 在用赋值运算符进行字符串初始化时,JVM自动每个字符串生成一个String类的实例。The String class represents character strings. All string literals in Java programs, such as "abc",...

    这两种写法都可以创建一个String对象。在用赋值运算符进行字符串初始化时,JVM自动为每个字符串生成一个String类的实例。
    The String class represents character strings. All string literals in Java programs, such as "abc", are implemented as instances of this class.


    解释一下,String作为一个类来说,当然可以用new来构造,String有3个构造函数:


    String();
    String("xxx");
    String(new StringBuffer());


    这两条语句的效果是一样的

    String password="ok";
    String password=new String("ok");

    不同的是,第一条现在内存中创建了"ok"这个String,然后将reference赋给password,如果这个时候还有一条语句String pwd = "ok";那么JVM将不再创建"ok",而是直接将第一个"ok"的reference赋给pwd,也就是说,password和pwd是使用同一块内存,而如果加上String pwd = new String("ok");那JVM将在内存中再创建一块区域放上“ok”这个字符串。
    展开全文
  • 为什么String str = new String("abc");是创建了两个对象

    本文转载自http://www.cnblogs.com/ydpvictor/archive/2012/09/09/2677260.html 侵删



    String str=new String("abc");   紧接着这段代码之后的往往是这个问题,那就是这行代码究竟创建了几个String对象呢?

    相信大家对这道题并不陌生,答案也是众所周知的,2个。

    接下来我们就从这道题展开,一起回顾一下与创建String对象相关的一些JAVA知识。  

    我们可以把上面这行代码分成String str、=、"abc"和new String()四部分来看待。String str只是定义了一个名为str的String类型的变量,因此它并没有创建对象;=是对变量str进行初始化,将某个对象的引用(或者叫句柄)赋值给它,显然也没有创建对象;现在只剩下new String("abc")了。那么,new String("abc")为什么又能被看成"abc"和new String()呢?

    我们来看一下被我们调用了的String的构造器:  

    public String(String original) {  //other code ...  }   大家都知道,我们常用的创建一个类的实例(对象)的方法有以下两种:

    一、使用new创建对象。 

    二、调用Class类的newInstance方法,利用反射机制创建对象。

    我们正是使用new调用了String类的上面那个构造器方法创建了一个对象,并将它的引用赋值给了str变量。同时我们注意到,被调用的构造器方法接受的参数也是一个String对象,这个对象正是"abc"。由此我们又要引入另外一种创建String对象的方式的讨论——引号内包含文本。

     

    这种方式是String特有的,并且它与new的方式存在很大区别。  

    String str="abc";  

    毫无疑问,这行代码创建了一个String对象。  

    String a="abc";  String b="abc";   那这里呢?

    答案还是一个。  

    String a="ab"+"cd";   再看看这里呢?

    答案是三个。(这里原文的作者认为是三个 但是实际上我认为编译阶段会进行优化,从而只是生成了一个对象"abcd")

    说到这里,我们就需要引入对字符串池相关知识的回顾了。  

    在JAVA虚拟机(JVM)中存在着一个字符串池,其中保存着很多String对象,并且可以被共享使用,因此它提高了效率。由于String类是final的,它的值一经创建就不可改变,因此我们不用担心String对象共享而带来程序的混乱。字符串池由String类维护,我们可以调用intern()方法来访问字符串池。  

    我们再回头看看String a="abc";,这行代码被执行的时候,JAVA虚拟机首先在字符串池中查找是否已经存在了值为"abc"的这么一个对象,它的判断依据是String类equals(Object obj)方法的返回值。如果有,则不再创建新的对象,直接返回已存在对象的引用;如果没有,则先创建这个对象,然后把它加入到字符串池中,再将它的引用返回。因此,我们不难理解前面三个例子中头两个例子为什么是这个答案了。

     

    只有使用引号包含文本的方式创建的String对象之间使用“+”连接产生的新对象才会被加入字符串池中。对于所有包含new方式新建对象(包括null)的“+”连接表达式,它所产生的新对象都不会被加入字符串池中,对此我们不再赘述。因此我们提倡大家用引号包含文本的方式来创建String对象以提高效率,实际上这也是我们在编程中常采用的。

     

    栈(stack):主要保存基本类型(或者叫内置类型)(char、byte、short、int、long、float、double、boolean)和对象的引用,数据可以共享,速度仅次于寄存器(register),快于堆。 

    堆(heap):用于存储对象

    展开全文
  • String中创建字符串常量用new和不用new的区别

    千次阅读 多人点赞 2019-01-19 16:11:33
    例如 String s1 = new String(“myString”); 和 String s1 = “myString”; 第一种方式通过关键字new定义过程: 1.在程序编译期,编译程序先去字符串常量池检查,是否存在“myString”,如果不存在,则在常量池中...

    String实质是字符数组,两个特点:1、该类不可被继承;2、不可变性(immutable)

    例如 String s1 = new String(“myString”);

    和 String s1 = “myString”;

    在这里插入图片描述
    第一种方式通过关键字new定义过程:
    1.在程序编译期,编译程序先去字符串常量池检查,是否存在“myString”,如果不存在,则在常量池中开辟一个内存空间存放“myString”;如果存在的话,则不用重新开辟空间,保证常量池中只有一个“myString”常量,节省内存空间。
    2.然后在内存堆中开辟一块空间存放new出来的String实例,在栈中开辟一块空间,命名为“s1”,存放的值为堆中String实例的内存地址,这个过程就是将引用s1指向new出来的String实例。
    3.你会发现String s1 = new String(“myString”); 这一句代码实际上可能创建了2个对象, 一个是String对象,存放在堆中, 一个是字符串常量对象,存放在串池中

    第二种方式直接定义过程:在程序编译期,编译程序先去字符串常量池检查,是否存在“myString”,如果不存在,则在常量池中开辟一个内存空间存放“myString”;如果存在的话,则不用重新开辟空间。然后在栈中开辟一块空间,命名为“s1”,存放的值为常量池中“myString”的内存地址(相当于指向常量池中的“myString”)

    展开全文
  • java Stringnew和直接赋值的区别

    千次阅读 2018-09-07 10:27:13
    在此之前,我们要知道的是,String是不可变对象,...原理是:现在java的常量池中寻找hello world对象,如果没有,在堆内存中new一个值”hello world” 的对象,放到常量池中. 之后再用直接赋值的方法时,如果值相同,就直接...

    在此之前,我们要知道的是,String是不可变对象,只要创建就不能修改,所有的修改操作实际上都是新建的String对象.

    1.直接赋值

    String myString = "hello world";

    原理是:现在java的常量池中寻找hello world对象,如果没有,在堆内存中new一个值为”hello world” 的对象,放到常量池中. 之后再用直接赋值的方法时,如果值相同,就直接引用这个对象,不用新建.
    如果直接赋值的值相同,那么他们两个就是同一个对象
    比如

            String myString = "hello world";
            String yourString = "hello world";
    
            System.out.println("is same object?");
            System.out.println(myString==yourString);

    运行
    这里写图片描述

    2.用new新建对象

    String myString = new String("hello world");

    新建对象是直接在堆内存中新建一个对象,再赋值.用new新建对象的对象都不是同一个对象

            String myString = new String("hello world");
            String yourString = new String("hello world");
    
            System.out.println("is same object?");
            System.out.println(myString==yourString);

    运行
    这里写图片描述

    3.补充:hashcode()方法
    在上篇博文中,我想通过hashcode来从侧面验证他是不是同一个对象,但是发现不同对象的hashcode也可以相同=-=.也是今天才发现的,昨天没有仔细看.接下来,我们就看一下hashcode的定义吧.先给出源码

        /**
         * Returns a hash code for this string. The hash code for a
         * {@code String} object is computed as
         * <blockquote><pre>
         * s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
         * </pre></blockquote>
         * using {@code int} arithmetic, where {@code s[i]} is the
         * <i>i</i>th character of the string, {@code n} is the length of
         * the string, and {@code ^} indicates exponentiation.
         * (The hash value of the empty string is zero.)
         *
         * @return  a hash code value for this object.
         */
        public int hashCode() {
            int h = hash;
            if (h == 0 && value.length > 0) {
                char val[] = value;
    
                for (int i = 0; i < value.length; i++) {
                    h = 31 * h + val[i];
                }
                hash = h;
            }
            return h;
        }

    发现了没有,hashcode是通过value生成的h = 31*h + val[i],所以只要value相同,hashcode就相同.hashcode但是可以验证一下equals方法.

    这样,我们尝试着自己写一下hashcode,看看与String自带的hashcode是否相同

        public static void hashcodeTest(){
            String name = new String("yangqi");
            char[] a = name.toCharArray();
    
            int hash = 0;
            //自己生成hashcode
            for(int i = 0;i<name.length();i++){
                hash = 31*hash + a[i];
            }
            System.out.println("myHashCode::"+hash);
            System.out.println("current hashcode:"+name.hashCode());
        }
    

    运行结果:
    这里写图片描述

    4.那么,java中又没有唯一标识对象的变量或者标识
    百度了半天,也看了看object的源码,没有在类的内部找到有定义唯一的标识.
    那么,这么标识呢? 可以生成一个 UUID ,UUID介绍:https://blog.csdn.net/zheng963/article/details/42551265
    使用方法:

    String logid = java.util.UUID.randomUUID().toString(); 

    当然,这个标识只能存在我们自定义的类中,而且声明必须为final 且不能为static

    private final String suuid = UUID.randomUUID().toString();
    展开全文
  • 字符串常量池(String类型为什么可以直接赋值?就和它有关) String类是我们平常项目中使用频率非常高的一种对象类型,jvm为了提升性能和减少内存开销,避免字符的重复创建,其维护了一块特殊的内存空间,即字符串池...
  • String str=new String("abc"); 紧接着这段代码之后的往往是这个问题,那就是这行代码究竟创建了几个String对象呢?相信大家对这道题并不 陌生,答案也是众所周知的,2个。接下来我们就从这道题展开,...
  • String直接赋值与使用new String的区别

    千次阅读 多人点赞 2018-04-24 10:11:47
    在研究String直接赋值与new String的区别之前我们需要先了解java中的字符串常量池的概念 字符串常量池 String类是我们平常项目中使用频率非常高的一种对象类型,jvm为了提升性能和减少内存开销,避免字符的重复...
  • java中String,new String,StringBuffer的思考

    千次阅读 2007-01-13 14:05:00
    java.lang.String类对大家来说最熟悉不过了,我们写java程序很少能不用String的。本文讲述如何正确的使用String,内容主要涉及初始化、串联和比较等操作。 首先我们必须清楚的一点是String类是final类型的,因此你...
  • String str=new String(“abc”); 这行代码究竟创建了几个String对象呢?
  • 1、Map m=new HashMap()  Map是个接口  HashMap是它的实现类。 这就是new 了一个对象 2、HashMap hashMapOut=new HashMap()  a、 这种申明方式没有问题。.  只不过一般习惯在前面使用接口来进行创建,...
  • 网上的争论不少,分析如下:String str=new String("abc");1. 思路我们可以把上面这行代码分成String str、=、”abc”和new String()四部分来看待。String str只是定义了一个名为str的...new String(“abc”)为什么
  • 深入了解new String()

    千次阅读 多人点赞 2021-06-15 14:37:29
    String是否相等、new的时候创建了几个对象等问题详解
  • 先来看一个例子,代码如下: 1.public class Test { 2. public static void main(String[] args) { 3. String str = "abc"; 4. String str1 = "abc"; ...5. String str2 = new String("ab
  • 紧接着这段代码之后的往往是这个问题,那就是这行代码究竟创建了几个String对象呢? 相信大家对这道题并不陌生,答案也是众所周知的,2个。 接下来我们就从这道题展开,...String str只是定义了一个名str的String
  • 这是以前刚学Java那会经常被问到的问题,并且也会经常出现在...String s2 = new String("abc"); 首先,我们先看看以上两句分别做了什么String s1 = “abc” 做了什么 在栈中创建了一个名 s1 的变量...
  • String s=new String("abc") 创建了几个对象?

    万次阅读 热门讨论 2014-03-28 22:35:50
    答案是2个,大家肯定都知道。面试中经常出现的问题,今天认真分析一下。 ...4、 new String() 创建一个对象。 首先,总结一下java创建对象的方式:new、clone、反射、反序列化 再看一下 St
  • String s=new String("abc")创建了几个对象

    千次阅读 2013-12-04 22:01:21
    Stringstr=new String("abc");  紧接着这段代码之后的往往是这个问题,那就是这行代码究竟创建了几个String对象呢? 相信大家对这道题并不陌生,答案也是众所周知的,2个。 接下来我们就从这道题展开,一起回顾...
  • String s = new String("xyz");  创建了几个String Object? 这个问题自身就没有合理的答案,楼主所引用的“标准答案”自然也就不准确了:  引用 答案:两个(一个是“xyz”,一个是指向
  • // ==与equals的区别:// ==:/...// 3、比较的是地址,如果是具体的阿拉伯数字的比较,值相等则TRUE,如:// int a=10 与 long b=10L 与 double c=10.0都是相同的(true),因为他们都指向地址10的堆// equals:
  • String str2 = new String(“ABC”); String str1 = “ABC”; String str1 = “ABC”;可能创建一个或者不创建对象。 从JDK1.7版本之后,java String池设置在堆中; 如果”ABC”这个字符串在java String池里不存在,...
  • 例如String str=new String("hello");这两种方式到底有什么不同?程序执行的时候内存到底有几个实例?实例存在哪?字面量又存在了哪里?变量又存在哪?概念很容易搞混。下面我们一个个的讲。虚拟机内存...
  • String s=new String("abc")创建了几个对象? String str=new String("abc"); 紧接着这段代码之后的往往是这个问题,那就是这行代码究竟创建了几个String对象呢? 相信大家对这道题并不陌生,答案也是众所周知的,...
  • 不同于String类,String由于实现了...对于数组的定义,初始化时用new与不用new 没区别,只是两种方式罢了,因为数组是引用数据类型,建立对象时,无论用不用new,数组实体都是放在堆内存中,引用变量放在栈内存。...
  • Stringstr=new String("abc"); 紧接着这段代码之后的往往是这个问题,那就是这行代码究竟创建了几个String对象呢? 相信大家对这道题并不陌生,答案也是众所周知的,2个。 接下来我们就从这道题展开,一起回顾...
  • String str=new String("123"); 紧接着这段代码之后的往往是这个问题,那就是这行代码究竟创建了几个String对象呢? 相信大家对这道题并不陌生,答案也是众所周知的,2个。 接下来我们就从这道题展开,一起回顾...
  • String为什么是final

    万次阅读 2018-10-10 22:12:49
    最近在很多文章中看到很多人问:String为什么是final的,所以自己写下这篇文章,来深入了解下。 首先先了解两个问题: Java中 final的定义: Java的关键字final的含义存在着细微的区别,但是通常它是指"这是无法...
  • String的特性》 1、String类是final的,不可被继承。 2、String类是的本质是字符数组char[], 并且其值不可改变。 3、Java运行时会维护一个String Pool(String池),JavaDoc翻译很模糊“字符串缓冲区”。String池...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 640,429
精华内容 256,171
关键字:

为什么string不用new