目录
2.3.2 StringBuffer VS StringBuilder
1.Java平台
1.1面向对象
面向对象编程也叫OOP,有两个重要的概念,类和对象
什么是对象?
万物皆对象
对象由什么组成?
属性和方法组成
对象是类的实例
什么是类?
类是对象共性的抽象
类是对象的模板
什么是面向对象编程?
从对象入手,把需求相关的对象抽取出来,借助对象间的相互配合完成需求
面向对象编程是一种代码规范、代码风格。以类和对象作为组织代码的基本单元,使用封装、继承、多态的特性进行代码的设计和实现
1.1.1 面向对象的三大特性
封装:暴露有限的接口,提供函数访问内部的数据
继承:首先Java是单继承,多实现,提高代码的复用性,把公共代码抽取到父类中,减少重复代码
多态: 父类型的引用指向子类的对象,提升代码扩展性和复用性
1.1.2 面向对象和面向过程
面向对象:以类为组织代码的基本单元
面向过程:以方法作为组织代码的基本单元
面向对象编程的优势:
1、适合复杂项目的开发
2、更加容易扩展、复用、维护
3、更加人性化、更加高级、更加智能
4、面向过程编程的性能更加高
1.2 概述
java的两大能力:
1、跨平台能力
2、Java垃圾收集机制
为什么需要JVM
JVM上承开发语音,下接操作系统,使用字节码实现
JVM是实现跨平台必不可少的中介角色。通过安装不同平台上的JVM去实跨平台性。
1.3 Java代码是如何运行的
1、首先使用javac HelloWord.java编译成HelloWord.class字节码文件
2、JVM通过解析这些字节码文件来完成程序的执行,当我们使用java命令运行.class文件的时候,实际上就相当于启动了一个JVM线程
3、然后JVM就会翻译这些字节码文件对其进行解释执行
2.数据类型
2.1基本类型
八种基本数据类型byte,short,int,long,float,double,boolean,char
2.2包装类型
java为八种基本数据类型提供了包装类,使它们具有对象的能力
2.2.1 自动装箱/拆箱
建议避免无意中的装箱、拆箱行为,这是非常耗费性能的,因为你要创建对象,占用内存空间等
2.2.2局限性
Java的对象都是引用类型,基本类型都是连续的存储,而引用类型是散列的分布,这种设计带来了灵活性,但是数据的操作性能很低,无法充分利用我们的CPU
2.3 字符串
2.3.1 String
被声明成为final class,所有的属性也都是final的,所以它的不可变性,类似类的拼接,裁剪字符串等操作,都会产生新的String对象。字符串的操作太普遍了,所以String的相关操作效率是非常低的,性能很差。
不可变的优势:
安全性 类无法被继承,变量的内容不能被修改
常量池的基石
数据结构
原来的char数组会导致无法被GC,造成内存泄露
java9使用byte数组节省了一半的空间
2.3.2 StringBuffer VS StringBuilder
1、StringBuffer线程安全的,方法都是使用synchronized实现同步的,线程安全会导致额外的开销,所以性能差
2、StringBuilder不是线程安全的,字符串拼接的首选
3、底层都是数组实现,二者都继承了AbstractStringBuilder
能看到concat1字符串拼接操作转化成了StringBuilder的append操作
2.3.3 字符串缓存
String str = new String(“abc”) 这种⽅式,首先在编译的时候,“abc”常量字符串在类加载的时候,会放入常量池中;在调用new时,堆里面会创建一个String对象,同时引用常量池中的“abc”字符串,最后将str引用指向String对象
java6提供了intern()方法,如果已经 有缓存里面的字符串,就会返回缓存里面的字符串,否则将其缓存起来。
2.3.4常见面试题
String str1= "abc";
String str2= new String("abc");
String str3= str2.intern();
assertSame(str1==str2);
assertSame(str2==str3);
assertSame(str1==str3)
String a =new String("abc").intern();
String b = new String("abc").intern();
assertTrue(a==b);
1、String str1= "abc"; 通过字面量的方式创建,abc存储于字符串常量中
2、会创建两个对象,一个abc对象存储在字符串常量池中,new会创建一个String对象存储在堆中,st2指向的是堆中的对象,所以str1 == str2 ? false
3、String str3= str2.intern();调用intern()方法直接返回常量池中的abc,所以str3指向常量池中的对象,str2指向的是堆中的对象,所以str2 == str3 ? false。 str1 == str3
4、在类加载的时候会在常量池中创建一个“abc”对象,还会创建一个String对象。调用intern方法时,会把常量池中的"abc“赋值给a,b.但是两个String对象就没有被引用了,会被GC回收掉。a,b都指向常量池中的同一个字符串。所以a==b.