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

云朵课堂网站开发怎么收费怎样申请一个网站

云朵课堂网站开发怎么收费,怎样申请一个网站,食品包装设计调研报告,wordpress 浮动导航插件来源 | 程序员 cxuan责编 | Carol封图 | CSDN 付费下载自视觉中国这是一道老生常谈的问题了#xff0c;字符串是不仅是 Java 中非常重要的一个对象#xff0c;它在其他语言中也存在。比如 C、Visual Basic、C# 等。字符串使用 String 来表示#xff0c;字符串一旦被创建出来… 来源 | 程序员 cxuan责编 | Carol封图 | CSDN 付费下载自视觉中国这是一道老生常谈的问题了字符串是不仅是 Java 中非常重要的一个对象它在其他语言中也存在。比如 C、Visual Basic、C# 等。字符串使用 String 来表示字符串一旦被创建出来就不会被修改当你想修改 StringBuffer 或者是 StringBuilder出于效率的考量虽然 String 可以通过 来创建多个对象达到字符串拼接的效果但是这种拼接的效率相比 StringBuffer 和 StringBuilder那就是心有余而力不足了。本篇文章我们一起来深入了解一下这三个对象。简单认识这三个对象 StringString 表示的就是 Java 中的字符串我们日常开发用到的使用  双引号包围的数都是字符串的实例。String 类其实是通过 char 数组来保存字符串的。下面是一个典型的字符串的声明。String s  abc;上面你创建了一个名为 abc 的字符串。字符串是恒定的一旦创建出来就不会被修改怎么理解这句话我们可以看下 String 源码的声明告诉我你看到了什么String 对象是由final 修饰的一旦使用 final 修饰的类不能被继承、方法不能被重写、属性不能被修改。而且 String 不只只有类是 final 的它其中的方法也是由 final 修饰的换句话说Sring 类就是一个典型的 Immutable 类。也由于 String ????的不可变性类似字符串拼接、字符串截取等操作都会产生新的 Strign 对象。所以请你告诉我下面String s1  aaa; String s2  bbb  ccc; String s3  s1  bbb; String s4  new String(aaa);分别创建了几个对象首先第一个问题s1 创建了几个对象。字符串在创建对象时会在常量池中看有没有 aaa 这个字符串如果没有此时还会在常量池中创建一个如果有则不创建。我们默认是没有的情况所以会创建一个对象。下同。那么 s2 创建了几个对象呢是两个对象还是一个对象我们可以使用 javap -c 看一下反汇编代码public class com.sendmessage.api.StringDemo {public com.sendmessage.api.StringDemo();Code:0: aload_01: invokespecial #1 // 执行对象的初始化方法4: returnpublic static void main(java.lang.String[]);Code:0: ldc #2 // 将 String aaa 执行入栈操作2: astore_1 # pop出栈引用值将其引用赋值给局部变量表中的变量 s13: ldc #3 // String bbbccc5: astore_26: return }编译器做了优化 String s2 bbb ccc 会直接被优化为 bbbccc。也就是直接创建了一个 bbbccc 对象。javap 是 jdk 自带的反汇编工具。它的作用就是根据 class 字节码文件反汇编出当前类对应的 code 区汇编指令、本地变量表、异常表和代码行偏移量映射表、常量池等等信息。javap -c 就是对代码进行反汇编操作。下面来看 s3s3 创建了几个对象呢是一个还是两个还是有其他选项我们使用 javap -c 来看一下我们可以看到s3 执行 操作会创建一个 StringBuilder 对象然后执行初始化。执行 号相当于是执行 new StringBuilder.append() 操作。所以String s3  s1  bbb;String s3  new StringBuilder().append(s1).append(bbb).toString();// Stringbuilder.toString() 方法也会创建一个 String public String toString() {// Create a copy, dont share the arrayreturn new String(value, 0, count); }所以 s3 执行完成后相当于创建了 3 个对象。下面来看 s4 创建了几个对象在创建这个对象时因为使用了 new 关键字所以肯定会在堆中创建一个对象。然后会在常量池中看有没有 aaa 这个字符串如果没有此时还会在常量池中创建一个如果有则不创建。所以可能是创建一个或者两个对象但是一定存在两个对象。说完了 String 对象我们再来说一下 StringBuilder 和 StringBuffer 对象。上面的 String 对象竟然和 StringBuilder 产生了千丝万缕的联系。不得不说 StringBuilder 是一个牛逼的对象。String 对象底层是使用了 StringBuilder 对象的 append 方法进行字符串拼接的不由得对 StringBuilder 心生敬意。不由得我们想要真正认识一下这个 StringBuilder 大佬但是在认识大佬前还有一个大 boss 就是 StringBuffer 对象这也是你不得不跨越的鸿沟。StringBufferStringBuffer 对象 代表一个可变的字符串序列当一个 StringBuffer 被创建以后通过 StringBuffer 的一系列方法可以实现字符串的拼接、截取等操作。一旦通过 StringBuffer 生成了最终想要的字符串后就可以调用其 toString 方法来生成一个新的字符串。例如StringBuffer b  new StringBuffer(111); b.append(222); System.out.println(b);我们上面提到  操作符连接两个字符串会自动执行 toString() 方法。那你猜 StringBuffer.append 方法会自动调用吗直接看一下反汇编代码不就完了么上图左边是手动调用 toString 方法的代码右图是没有调用 toString 方法的代码可以看到toString() 方法不像  一样自动被调用。StringBuffer 是线程安全的我们可以通过它的源码可以看出StringBuffer 在字符串拼接上面直接使用 synchronized 关键字加锁从而保证了线程安全性。StringBuilder最后来认识大佬了StringBuilder 其实是和 StringBuffer 几乎一样只不过 StringBuilder 是非线程安全的。并且为什么 号操作符使用 StringBuilder 作为拼接条件而不是使用 StringBuffer 呢我猜测原因是加锁是一个比较耗时的操作而加锁会影响性能所以 String 底层使用 StringBuilder 作为字符串拼接。 理解 String、StringBuilder、StringBuffer我们上面说到使用  连接符时JVM 会隐式创建 StringBuilder 对象这种方式在大部分情况下并不会造成效率的损失不过在进行大量循环拼接字符串时则需要注意。如下这段代码String s  aaaa; for (int i  0; i  100000; i) {s  bbb; }这是一段很普通的代码只不过对字符串 s 进行了 操作我们通过反编译代码来看一下。// 经过反编译后 String s  aaa; for(int i  0; i  10000; i) {s  (new StringBuilder()).append(s).append(bbb).toString();     }你能看出来需要注意的地方了吗在每次进行循环时都会创建一个 StringBuilder 对象每次都会把一个新的字符串元素 bbb 拼接到 aaa 的后面所以执行几次后的结果如下每次都会创建一个 StringBuilder 并把引用赋给 StringBuilder 对象因此每个 StringBuilder 对象都是强引用 这样在创建完毕后内存中就会多了很多 StringBuilder 的无用对象。了解更多关于引用的知识请看小心点别被当成垃圾回收了。这样由于大量 StringBuilder 创建在堆内存中肯定会造成效率的损失所以在这种情况下建议在循环体外创建一个 StringBuilder 对象调用 append()方法手动拼接。例如StringBuilder builder  new StringBuilder(aaa); for (int i  0; i  10000; i) {builder.append(bbb); } builder.toString();这段代码中只会创建一个 builder 对象每次循环都会使用这个 builder 对象进行拼接因此提高了拼接效率。从设计角度理解我们前面说过String 类是典型的 Immutable 不可变类实现保证了线程安全性所有对 String 字符串的修改都会构造出一个新的 String 对象由于 String 的不可变性不可变对象在拷贝时不需要额外的复制数据。String 在 JDK1.6 之后提供了 intern() 方法intern 方法是一个 native 方法它底层由 C/C 实现intern 方法的目的就是为了把字符串缓存起来在 JDK1.6 中却不推荐使用 intern 方法因为 JDK1.6 把方法区放到了永久代Java 堆的一部分永久代的空间是有限的除了 Fullgc 外其他收集并不会释放永久代的存储空间。JDK1.7 将字符串常量池移到了堆内存 中下面我们来看一段代码来认识一下 intern 方法public static void main(String[] args) {String a  new String(ab);String b  new String(ab);String c  ab;String d  a;String e  new String(b);String f  d  e;System.out.println(a.intern()  b);System.out.println(a.intern()  b.intern());System.out.println(a.intern()  c);System.out.println(a.intern()  f);}上述的执行结果是什么呢我们先把答案贴出来以防心急的同学想急于看到结果他们的答案是false true true false和你预想的一样吗为什么会这样呢我们先来看一下 intern 方法的官方解释这里你需要知道 JVM 的内存模型虚拟机栈 : Java 虚拟机栈是线程私有的数据区Java 虚拟机栈的生命周期与线程相同虚拟机栈也是局部变量的存储位置。方法在执行过程中会在虚拟机栈种创建一个 栈帧(stack frame)。本地方法栈: 本地方法栈也是线程私有的数据区本地方法栈存储的区域主要是 Java 中使用 native 关键字修饰的方法所存储的区域程序计数器程序计数器也是线程私有的数据区这部分区域用于存储线程的指令地址用于判断线程的分支、循环、跳转、异常、线程切换和恢复等功能这些都通过程序计数器来完成。方法区方法区是各个线程共享的内存区域它用于存储虚拟机加载的 类信息、常量、静态变量、即时编译器编译后的代码等数据。堆堆是线程共享的数据区堆是 JVM 中最大的一块存储区域所有的对象实例都会分配在堆上运行时常量池运行时常量池又被称为 Runtime Constant Pool这块区域是方法区的一部分它的名字非常有意思它并不要求常量一定只有在编译期才能产生也就是并非编译期间将常量放在常量池中运行期间也可以将新的常量放入常量池中String 的 intern 方法就是一个典型的例子。在 JDK 1.6 及之前的版本中常量池是分配在方法区中永久代(Parmanent Generation)内的而永久代和 Java 堆是两个完全分开的区域。如果字符串常量池中已经包含一个等于此 String 对象的字符串则返回常量池中这个字符串的 String 对象否则将此 String 对象包含的字符串添加到常量池中并且返回此 String 对象的引用。一些人把方法区称为永久代这种说法不准确仅仅是 Hotspot 虚拟机设计团队选择使用永久代来实现方法区而已。从JDK 1.7开始去永久代字符串常量池已经被转移至 Java 堆中开发人员也对 intern 方法做了一些修改。因为字符串常量池和 new 的对象都存于 Java 堆中为了优化性能和减少内存开销当调用 intern 方法时如果常量池中已经存在该字符串则返回池中字符串否则直接存储堆中的引用也就是字符串常量池中存储的是指向堆里的对象。所以我们对上面的结论进行分析String a  new String(ab); String b  new String(ab);System.out.println(a.intern()  b);输出什么false为什么呢画一张图你就明白了图画的有些问题栈应该是后入先出所以 b 应该在 a 上面不过不影响效果a.intern 返回的是常量池中的 ab而 b 是直接返回的是堆中的 ab。地址不一样肯定输出 false所以第二个System.out.println(a.intern()  b.intern());也就没问题了吧它们都返回的是字符串常量池中的 ab地址相同所以输出 true然后来看第三个System.out.println(a.intern()  c);图示如下a 不会变因为常量池中已经有了 ab 所以 c 不会再创建一个 ab 字符串这是编译器做的优化为了提高效率。下面来看最后一个System.out.println(a.intern()  f);String首先来看一下 String 类在继承树的什么位置、实现了什么接口、父类是谁这是源码分析的几大重要因素。String 没有继承任何接口不过实现了三个接口分别是 Serializable、Comparable、CharSequence 接口Serializable 这个序列化接口没有任何方法和域仅用于标识序列化的语意。Comparable实现了 Comparable 的接口可用于内部比较两个对象的大小CharSequence字符串序列接口CharSequence 是一个可读的 char 值序列提供了 length(), charAt(int index), subSequence(int start, int end) 等接口StringBuilder 和 StringBuffer 也继承了这个接口重要属性字符串是什么字符串你品你细品。你会发现它就是一连串字符组成的串。也就是说String str  abc; //  char data[]  {a, b, c}; String str  new String(data);原来这么回事啊害所以String 中有一个用于存储字符的 char 数组 value[]这个数组存储了每个字符。另外一个就是 hash 属性它用于缓存字符串的哈希码。因为 String 经常被用于比较比如在 HashMap 中。如果每次进行比较都重新计算其 hashcode 的值的话那无疑是比较麻烦的而保存一个 hashcode 的缓存无疑能优化这样的操作。String 可以通过许多途径创建也可以根据 Stringbuffer 和 StringBuilder 进行创建。毕竟我们本篇文章探讨的不是源码分析的文章所以涉及到的源码不会很多。除此之外String 还提供了一些其他方法charAt 返回指定位置上字符的值getChars: 复制 String 中的字符到指定的数组equals: 用于判断 String 对象的值是否相等indexOf : 用于检索字符串substring: 对字符串进行截取concat: 用于字符串拼接效率高于 replace用于字符串替换match正则表达式的字符串匹配contains: 是否包含指定字符序列split: 字符串分割join:  字符串拼接trim: 去掉多余空格toCharArray: 把 String 对象转换为字符数组valueOf: 把对象转换为字符串StringBuilderStringBuilder 类表示一个可变的字符序列我们知道StringBuilder 是非线程安全的容器一般适用于单线程场景中的字符串拼接操作下面我们就来从源码角度看一下 StringBuilder首先我们来看一下 StringBuilder 的定义public final class StringBuilderextends AbstractStringBuilderimplements java.io.Serializable, CharSequence {...}StringBuilder 被 final 修饰表示 StringBuilder 是不可被继承的StringBuilder 类继承于 AbstractStringBuilder类。实际上AbstractStringBuilder 类具体实现了可变字符序列的一系列操作比如append()、insert()、delete()、replace()、charAt() 方法等。StringBuilder 实现了 2 个接口Serializable 序列化接口表示对象可以被序列化。CharSequence 字符序列接口提供了几个对字符序列进行只读访问的方法例如 ength()、charAt()、subSequence()、toString() 方法等。StringBuilder 使用 AbstractStringBuilder 类中的两个变量作为元素char[] value; // 存储字符数组int count; // 字符串使用的计数StringBufferStringBuffer 也是继承于 AbstractStringBuilder 使用 value 和 count 分别表示存储的字符数组和字符串使用的计数StringBuffer 与 StringBuilder 最大的区别就是 StringBuffer 可以在多线程场景下使用StringBuffer 内部有大部分方法都加了 synchronized 锁。在单线程场景下效率比较低因为有锁的开销。StringBuilder 和 StringBuffer 的扩容问题我相信这个问题很多同学都没有注意到吧其实 StringBuilder 和 StringBuffer 存在扩容问题先从 StringBuilder 开始看起首先先注意一下 StringBuilder 的初始容量public StringBuilder() {super(16); }StringBuilder 的初始容量是 16当然也可以指定 StringBuilder 的初始容量。在调用 append 拼接字符串会调用 AbstractStringBuilder 中的 append 方法public AbstractStringBuilder append(String str) {if (str  null)return appendNull();int len  str.length();ensureCapacityInternal(count  len);str.getChars(0, len, value, count);count  len;return this; }上面代码中有一个 ensureCapacityInternal 方法这个就是扩容方法我们跟进去看一下private void ensureCapacityInternal(int minimumCapacity) {// overflow-conscious codeif (minimumCapacity - value.length  0) {value  Arrays.copyOf(value,newCapacity(minimumCapacity));} }这个方法会进行判断minimumCapacity 就是字符长度 要拼接的字符串长度如果拼接后的字符串要比当前字符长度大的话会进行数据的复制真正扩容的方法是在 newCapacity 中private int newCapacity(int minCapacity) {// overflow-conscious codeint newCapacity  (value.length  1)  2;if (newCapacity - minCapacity  0) {newCapacity  minCapacity;}return (newCapacity  0 || MAX_ARRAY_SIZE - newCapacity  0)? hugeCapacity(minCapacity): newCapacity; }扩容后的字符串长度会是原字符串长度增加一倍 2如果扩容后的长度还比拼接后的字符串长度小的话那就直接扩容到它需要的长度  newCapacity minCapacity然后再进行数组的拷贝。总结本篇文章主要描述了 String 、StringBuilder 和 StringBuffer 的主要特性String、StringBuilder 和 StringBuffer 的底层构造是怎样的以及 String 常量池的优化、StringBuilder 和 StringBuffer 的扩容特性等。如果有错误的地方还请大佬们提出宝贵意见。推荐阅读 干货 | 大白话彻底搞懂 HBase RowKey 详细设计那天我去逛街发现连大编程语言都摆起地摊了……研发的未来在哪里Serverless 云开发来了Facebook 公司如何清除 960 万句“脏话”Linux 之父怒删工程师提交的补丁称“太蠢了”网友怼得好干货3 个重要因素带你看透 AI 技术架构方案的可行性热评 | 警惕新基建热潮中的区块链项目烂尾真香朕在看了
http://www.zqtcl.cn/news/33810/

相关文章:

  • 太原云起时网站建设做网站要会什么
  • 国内知名网站建设排名it人力外包公司
  • 烟台市福山区住房和建设局网站建设网站建设多少钱
  • 朝阳双桥网站建设如何用虚拟主机做网站
  • 网站后台无法审核手机端企业网站模板
  • 上海高端网站建设服务器拉新推广平台有哪些
  • 直播视频网站如何做电商网站计划
  • vue门户网站模板wordpress表格编辑
  • 网站的建设过程做代销的网站
  • 网站服务器软件公司做网站找谁
  • 潍坊网站seo外包wordpress 菜单两列显示
  • 网站免费申请注册青海省建设局网站首页
  • 网站建设忄金手指专业wordpress 加广告
  • 网站域名绑定好处今天广州白云新闻
  • 企业网站建设推荐乐云seoapp研发过程
  • 宝塔网站做301重定向品牌推广语
  • 服装图案素材网站公司网站推广方式
  • 安徽城乡建设局网站宁波网站推广报价
  • 想用自己电脑做服务器做个网站用凡科建设的网站安全吗
  • 东莞建外贸企业网站律师事务所网站模板
  • 用ps怎么做网站导航条怎么做文案素材网站
  • 做网站如何用模板网站建设合同 英文范文
  • 公司网站建设精英培训班招生方案
  • 信用中国 网站截图怎么做阿里云网站备案入口
  • 网站定制站老酒街 wordpress
  • 网站费用属于哪个费用做亚马逊跨境电商要多少投资
  • 学院校园网网站建设情况wordpress多站点命名
  • 外贸生意做哪个网站好微站图片
  • 怎样做易支付网站制作一个app的完整流程
  • 妹妹强迫我和她做网站设计官网论坛