当前位置: 首页 > news >正文

网站建设中 模板素材上海建筑设计院招聘

网站建设中 模板素材,上海建筑设计院招聘,wordpress loren,湖北建设信息网站 联系方式字符串在Java生产开发中的使用频率是非常高的#xff0c;可见#xff0c;字符串对于我们而言非常关键。那么从C语言过来的同学会发现#xff0c;在C中是没有String类型的#xff0c;那么C语言要想实现字符串就必须使用char数组#xff0c;通过一个个的字符来组拼成字符串。…字符串在Java生产开发中的使用频率是非常高的可见字符串对于我们而言非常关键。那么从C语言过来的同学会发现在C中是没有String类型的那么C语言要想实现字符串就必须使用char数组通过一个个的字符来组拼成字符串。Java中是如何实现字符串的那其实在Java中关于字符串的实现其实用的也是char数组这可以从源码中得到体现。/** * Initializes a newly created {code String} object so that it represents * the same sequence of characters as the argument; in other words, the * newly created string is a copy of the argument string. Unless an * explicit copy of {code original} is needed, use of this constructor is * unnecessary since Strings are immutable. * * param original * A {code String} */ public String(String original) { this.value original.value; this.hash original.hash; }复制代码这是String类的构造方法而这个value实际上就是char数组。/** The value is used for character storage. */ private final char value[];复制代码字符串在内存中的保存方式我们都知道如何去创建一个字符串那么 字符串在内存中的保存方式是怎样的呢在内存中有一个区域叫做常量池而当我们以这样的方式去创建字符串String s1 abc;String s2 abc;复制代码这个字符串就一定会被保存到常量池中。而Java虚拟机如果发现常量池中已经存在需要创建的字符串中它就不会重复创建而是指向那个字符串即可。String s1 abc;String s2 abc;System.out.println(s1 s2);复制代码所以上述代码段的执行结果一定是true。但是如果使用new关键字区创建字符串过程就不太一样了。比如下面的声明String s3 new String(abc);String s4 new String(abc);复制代码过程是这样的首先将abc保存在常量池中此时并没有引用然后new关键字会去创建一个字符串对象就会在堆内存中创建abc然后s3变量指向abc。当执行第二句声明时因为常量池中已经存在abc所以不会重复创建而new关键字又会去堆内存开辟空间存放abc然后s4变量指向abc。String s3 new String(abc);String s4 new String(abc);System.out.println(s3 s4);复制代码所以上述代码段的执行结果一定是false。字符串驻留当相同的字符串常量被多次创建时注意是使用双引号( )显式声明时字符串常量对象会被保存在常量池中且只会创建一个对象这就是字符串驻留这个名词的产生就是为了提升性能。简单提一下字符串中有一个方法叫做intern()那么这个方法有什么作用呢 该方法会去常量池中寻找当前调用该方法的字符串常量若找到则直接返回该字符串对象若没有则将当前字符串放入常量池并返回总之该方法一定会返回字符串。String s3 new String(abc);String s4 new String(abc);System.out.println(s3.intern() s4.intern());复制代码所以上述代码段的执行结果一定是true因为字符串驻留只允许常量池中一个相同字符串的存在。JVM内存结构刚才一直在说常量池那么常量池具体在哪呢这就要来研究一下JVM的内存结构。JVM分为堆、栈、方法区栈又分为本地方法栈和Java栈。在Java7之前常量池就放在方法区里而从Java7开始常量池被移到了堆。这样说过于抽象我们可以通过代码来感受这一过程。String s1 new String(hello) new String(world);String s2 helloworld;System.out.println(s1 s2);复制代码上述程序段的执行结果一定是false。因为s1变量在堆中而s2变量在常量池中两者肯定不相同。那么看下面这段代码猜猜看结果是什么String s1 new String(hello) new String(world);System.out.println(s1.intern() s1);复制代码按照刚才的分析intern()返回的一定是常量池里的字符串而s1变量在堆中它们肯定是不一样的但运行结果竟然是true。那是不是就能解释常量池在堆中所以它们指向的是同一个对象呢其实还不完全是我们可以继续看一段代码。String s1 new String(hello) new String(world);System.out.println(s1.intern() s1);String s2 new String(hello) new String(world); System.out.println(s2.intern() s2);复制代码这段代码的运行结果truefalse复制代码感觉很神奇让人猜不透摸不着。别急下面我们来一起分析一下。通过这个图来理解一下首先第一行代码会在常量池中创建hello和world两个字符串接着在堆中开辟了一个空间存放组合后的字符串helloworld然后变量s1指向它。我们说intern()会返回常量池中的字符串那么在常量池中没有helloworld的情况下intern()方法会怎样处理呢其实它会将对堆中helloworld的引用放入常量池中此时s1.intern()和s1都指向的是同一个对象它们是相等的。但是s2在创建的过程中也会在堆中开辟一个空间存放helloworld使变量s2指向它而s2.intern()方法在执行的时候发现helloworld的引用已经存在所以直接返回但此时返回的其实是s1变量的引用那么s2.intern()与s2不相等相信大家能够理解了。String s1 new String(hello) new String(world);System.out.println(s1.intern() s1);String s2 new String(hello) new String(world);System.out.println(s2.intern() s1);复制代码那么这段程序的输出结果你若是能立马知晓那么恭喜你前面的知识点你已基本掌握。执行结果就是truetrue复制代码我们还可以通过一个极端的方法来判断常量池的位置。List list new ArrayList();String str boom;for(int i 0;i Integer.MAX_VALUE;i) { String temp str i; str temp; list.add(temp.intern()); }复制代码通过编写这一段程序能够让JVM去不停地将字符串变量存入常量池从而使其内存溢出内存溢出后控制台信息如下Exception in thread main java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOfRange(Arrays.java:2694) at java.lang.String.(String.java:203) at java.lang.StringBuilder.toString(StringBuilder.java:405) at com.itcast.test2.StringTest.main(StringTest.java:25)复制代码可以看到控制台信息提示堆内存溢出这也可以得出常量池的位置是在堆内。这是Java7及其以后版本的输出信息当我们将版本切换为Java7之前的版本同样的代码输出信息如下Exception in thread main java.lang.OutOfMemoryError: PermGen space at java.util.Arrays.copyOfRange(Arrays.java:2694) at java.lang.String.(String.java:203) at java.lang.StringBuilder.toString(StringBuilder.java:405) at com.itcast.test2.StringTest.main(StringTest.java:25)复制代码PermGen space其实就是方法区 那么其实在JVM中的堆一般分为三大部分新生代、老年代、永久代这个PermGen space就是永久代也就是方法区叫法不同而已。其它问题继续来探讨一下关于字符串常量的一些其它问题。String s1 hello world;String s2 helloworld;System.out.println(s1 s2); String temp hello;String s3 temp world;String s4 helloworld;System.out.println(s3 s4);复制代码那么这两个输出的结果是什么呢结果是truefalse复制代码第一个输出为true不难理解因为s1和s2指向的都是常量池中的helloworld字符串那么s3和s4难道就不是吗它还真就不是这样了。s3在创建过程中会将temp保存在堆内存中所以s3和s4指向的对象不是同一个。我们可以通过反编译来证实将这段代码的.class文件进行反编译结果如下String s1 helloworld;String s2 helloworld; System.out.println(s1 s2); String temp hello;String s3 String.valueOf(temp) world;String s4 helloworld;System.out.println(s3 s4);复制代码我们可以看到s1和s2的创建过程其实是一模一样的其实JVM为了优化速度当它确定是两个字符串常量进行拼接时它会在编译器就完成拼接而并不会去创建对象处理但是s3的创建要经过temp变量因为JVM无法在编译期就推测出temp所以它要通过String对象来进行处理将temp放入堆内存。所以并不是说只有出现new关键字变量才会放入堆内存中。希望这篇文章能够使你更加深入地理解字符串常量。
http://www.pierceye.com/news/722838/

相关文章:

  • 学习网站建设要报班吗中国建设银行晋中分行网站
  • 学校网站建设经验介绍西安建设网站公司
  • 江西营销网站建设公司的企业诚信建设分析
  • 生活家装饰官方网站动画设计考研
  • 网站内部的信息安全建设怎么才能在百度上做引流呢
  • 男男做的视频网站wordpress 系统
  • 网站建设合同 附件上海网站制作费用
  • 知名的环保行业网站开发开发一个app难吗
  • 律师网站建设方案网站企业制作
  • 基础建设期刊在哪个网站可以查做网站咨询
  • 万网个人网站备案查询甘肃建设银行网站
  • 网站建设有什么费用wordpress国外主题网站
  • 手机网站下拉菜单代码com域名代表什么
  • 网站右侧信息跟随左侧菜单栏变化好牛网站建设
  • 手机网站pc网站免费国外服务器租用
  • 商城网站建设服务wordpress手机导航三横拦
  • app设计欣赏网站长沙制作公园仿竹护栏
  • 景泰县做网站网站建设上市
  • 电子商务网站开发课题简介php mysql网站开发...
  • 如何提升网站alexa排名wordpress加联系方式
  • 餐厅网站模版wordpress linux
  • 网站seo优化怎么做mes系统
  • 江津网站建设公司做外贸去哪个网站找客户
  • 网站建设-部署与发布wordpress怎么代码高亮
  • 自己做的网站本地虚拟上传wordpress 不能评论
  • 百度贴吧网站开发需求分析怎么免费自己做推广
  • 网站怎么访问自己做的网页中国园林网
  • 郑州服装网站建设做营销型网站用那个cms好
  • 网站登录页面模板下载wordpress添加随机图片
  • 贵阳网站建设哪家便宜关键词林俊杰mp3在线听