Java基础

  • Post author:
  • Post category:java




一 Java概述

​ Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程



1. JVM、JRE和JDK的关系

JVM

Java Virtual Machine是Java虚拟机,Java程序需要运行在虚拟机上,不同的平台有自己的虚拟机,因此Java语言可以实现跨平台。

JRE

Java Runtime Environment包括Java虚拟机和Java程序所需的核心类库等。核心类库主要是java.lang包:包含了运行Java程序必不可少的系统类,如基本数据类型、基本数学函数、字符串处理、线程、异常处理类等,系统缺省加载这个包

​ 如果想要运行一个开发好的Java程序,计算机中只需要安装JRE即可。

JDK

Java Development Kit是提供给Java开发人员使用的,其中包含了Java的开发工具,也包括了JRE。所以安装了JDK,就无需再单独安装JRE了。其中的开发工具:编译工具(javac.exe),打包工具(jar.exe)等

JVM&JRE&JDK关系图

img



2. Java和C++的区别

  • 都是面向对象的语言,都支持封装、继承和多态
  • Java不提供指针来直接访问内存,程序内存更加安全
  • Java的类是单继承的,C++支持多重继承;虽然Java的类不可以多继承,但是接口可以多继承。
  • Java有自动内存管理机制,不需要程序员手动释放无用内存



二 基础语法



1. 数据类型

  • 基本数据类型

    • 数值型

      • 整数类型(byte,short,int,long)

      • 浮点类型(float,double)

    • 字符型(char)

    • 布尔型(boolean)

  • 引用数据类型

    • 类(class)
    • 接口(interface)
    • 数组([])

Java基本数据类型图

img



2. 访问修饰符

​ private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)

​ default (即缺省,什么也不写,不使用任何关键字): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。

​ protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。

​ public : 对所有类可见。使用对象:类、接口、变量、方法

img



3. 运算符


&和&&的区别?

​ &运算符有两种用法:(1)按位与;(2)逻辑与。

​ &&运算符是短路与运算。逻辑与跟短路与的差别是非常巨大的,虽然二者都要求运算符左右两端的布尔值都是true 整个表达式的值才是 true。&&之所以称为短路运算,是因为如果&&左边的表达式的值是 false,右边的表达式会被直接短路掉,不会进行运算。

​ 注意:逻辑或运算符(|)和短路或运算符(||)的差别也是如此。



4. 关键字


Java 有没有 goto

​ goto 是 Java 中的保留字,在目前版本的 Java 中没有使用。


final 有什么用

​ 修饰变量,变量不能改变

​ 修饰方法,方法不能被重写,可以被重载

​ 修饰类,该类不能被继承


final finally finalize的区别

  • final可以修饰类、变量、方法,修饰类表示该类不能被继承、修饰方法表示该方法不能被重写、修饰变量表

    示该变量是一个常量不能被重新赋值。
  • finally一般作用在try-catch代码块中,在处理异常的时候,通常我们将一定要执行的代码方法finally代码块

    中,表示不管是否出现异常,该代码块都会执行,一般用来存放一些关闭资源的代码。
  • finalize是一个方法,属于Object类的一个方法,而Object类是所有类的父类,该方法一般由垃圾回收器来调

    用,当我们调用System.gc() 方法的时候,由垃圾回收器调用finalize(),回收垃圾,一个对象是否可回收的

    最后判断。


this和super的区别

​ this是自身的一个对象,代表对象本身,可以理解为:指向对象本身的一个指针。

​ super可以理解为是指向自己超(父)类对象的一个指针,而这个超类指的是离自己最近的一个父类。

​ 区别:

  • super: 它引用当前对象的直接父类中的成员(用来访问直接父类中被隐藏的父类中成员数据或函数,基类与派生类中有相同成员定义时如:super.变量名 super.成员函数据名(实参)
  • this:它代表当前对象名(在程序中易产生二义性之处,应使用this来指明当前对象;如果函数的形参与类中的成员数据同名,这时需用this来指明成员变量名)
  • super()和this()类似,区别是,super()在子类中调用父类的构造方法,this()在本类内调用本类的其它构造方法。
  • super()和this()均需放在构造方法内第一行。
  • 尽管可以用this调用一个构造器,但却不能调用两个。
  • this和super不能同时出现在一个构造函数里面,因为this必然会调用其它的构造函数,其它的构造函数必然也会有super语句的存在,所以在同一个构造函数里面有相同的语句,就失去了语句的意义,编译器也不会通过。
  • this()和super()都指的是对象,所以,均不可以在static环境中使用。包括:static变量,static方法,static语句块。
  • 从本质上讲,this是一个指向本对象的指针, 然而super是一个Java关键字。


static 静态

​ 修饰成员变量:称为静态变量,不属于对象,属于类,常常通过类名点来访问,存在方法区中,只有一份。当所有对象的数据都一样时使用

​ 修饰方法:称为静态方法,没有隐式的this传递,不能直接访问实例成员,只能直接访问静态成员,通过类名点来访问,存在方法区。方法的执行只与参数有关,与对象无关时使用

​ static块:属于类的代码块,在类加载期间执行的代码块,只执行一次,可以用来加载静态资源



5. 流程控制语句


break ,continue ,return 的区别及作用

​ break 跳出上一层循环,不再执行循环(结束当前的循环体)

​ continue 跳出本次循环,继续执行下次循环(结束正在执行的循环 进入下一个循环条件)

​ return 程序返回,不再执行下面的代码(结束当前的方法 直接返回)



三 面向对象



1. 特性

封装:将数据和操作过程封装成一个整体,对数据的访问只能通过已定义界面,使实现细节不可见

继承:java是单继承语言,继承允许和鼓励类的重用,一个父类可以有多个子类,一个子类只能有一个父类

多态:允许不同类的对象对同一消息做出响应.具体表现在重载和重写


多态的实现?

Java实现多态有三个必要条件:继承、重写、向上转型。

​ 继承:在多态中必须存在有继承关系的子类和父类。

​ 重写:子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法。

​ 向上转型:在多态中需要将子类的引用赋给父类对象,只有这样该引用才能够具备技能调用父类的方法和子类的方法。

​ 只有满足了上述三个条件,我们才能够在同一个继承结构中使用统一的逻辑实现代码处理不同的对象,从而达到执行不同的行为。



2. 抽象类与接口


interface:接口

​ 接口中只能出现3种成员:

​ 1.公共的静态常量(public final static )

​ 2.公共的抽象方法(public abstract )

​ 3.静态内部类(static class)


abstract:抽象

​ abstract修饰的方法为抽象方法,抽象方法只有方法的定义,没有方法的具体实现,用一个分号结尾。

​ 一个类中如果包含抽象方法,该类必须为抽象类,如果一个类继承了抽象类,必须重写其抽象方法。

​ 抽象类的意义在于为其子类提供一个公共类型,封装子类中重复的内容(成员变量和方法)。抽象类不可以实例化。

​ abstract和final不可以同时修饰一个类。


抽象类与接口的区别

​ 抽象类:abstract修饰,不可以实例化,抽象类中可以包含抽象方法(没有方法体,以分号结尾)也可包含非抽象方法,可以包含构造器,可以被继承,有两种继承方式:子类重写父类的抽象方法,变不完整为完整;子类也为抽象类。抽象类的意义在于为其子类提供一个公共类型,封装子类中重复的内容(成员变量和方法)。抽象类不可以实例化。abstract和final不可以同时修饰一个类。

​ 接口:由Interface定义,只能包含常量和抽象方法,属于完全抽象的抽象类,不可被实例化,接口和接口之间可以继承,可多继承,用逗号隔开,类和接口之间是实现(implements),类实现接口后,必须实现接口中所有的抽象方法,一个类可以实现多个接口,用逗号隔开,若继承又实现,先继承再实现,接口中不包含构造器



3. 变量与方法

​ 成员变量:方法外部,类内部定义的变量

​ 局部变量:类的方法中的变量


成员变量与局部变量的区别

​ 作用域:

​ 成员变量:针对整个类有效

​ 局部变量:只在某个范围内有效(一般指的就是方法,语句体内)

​ 存储位置:

​ 成员变量:随着对象的创建而存在,随着对象的消失而消失,存储在堆内存中

​ 局部变量:在方法被调用,或者语句被执行的时候存在,存储在栈内存中。当方法调用完,或者语句结束后,就自动释放。

​ 生命周期:

​ 成员变量:随着对象的创建而存在,随着对象的消失而消失

​ 局部变量:当方法调用完,或者语句结束后,就自动释放

​ 初始值:

​ 成员变量:有默认初始值。

​ 局部变量:没有默认初始值,使用前必须赋值

​ 使用原则:

​ 在使用变量时需要遵循的原则为:就近原则

​ 首先在局部范围找,有就使用;接着在成员位置找


构造方法

​ 与类同名,没有返回值类型,也不能写void

​ 常常给成员变量初始化(作用)

​ 构造方法在创建对象时被自动调用

​ 若不写构造,编译器默认提供一个无参构造

​ 构造方法可以重载 ,一个方法可以通过this调用另一个构造方法

​ 如在类声明时写了有参构造,但在实例化时需要使用无参构造,必须把无参构造写出来



4. 内部类

​ 一般情况下,内部类的对象会在其外部类对象中创建,内部类对象中会有一个隐式的引用指向创建它的外部类对象。


匿名内部类:


​ 如果一段程序中需要创建一个类的对象,而且对象创建这个类的价值就不存在了,那么就可以用一个不需要命名的内部类来创建对象

​ 如:A a=new A(匿名内部类的构造方法参数){匿名内部类的成员变量或方法}; A是匿名类所实现的接口或继承的父类



5. 重写与重载

​ 重载:一个类中方法名相同,参数列表不同

​ 重写:子类可以重写(覆盖)继承自父类的方法,即方法名和参数列表(方法签名)与父类的相同,但方法体不同


重写要遵循“两同两小一大”原则:


两同:子类的方法名和参数列表与父类相同;

两小:子类的返回值类型比父类方法返回值类型小或者相等;

子类抛出的异常比父类抛出的异常类小或相等

一大:子类访问控制权限比父类控制权限大或相等



构造器不能被继承,因此不能被重写,但可以被重载。



在构造子类之前必须先构造父类,子类构造方法中,默认有super()调用父类的无参构造,并且只能位于子类构造方法的第一行。若自己调了,则编译器不再默认提供



重载发生在编译期,看引用的类型;重写发生在运行期,看对象的类型



6. 对象相等判断


== 和 equals 的区别



==

: 它的作用是判断两个对象的地址是不是相等。即,判断两个对象是不是同一个对象。(基本数据类型 == 比较的是值,引用数据类型 == 比较的是内存地址)



equals()

: 它的作用也是判断两个对象是否相等。但它一般有两种使用情况:

​ 情况1:类没有覆盖 equals() 方法。则通过 equals() 比较该类的两个对象时,等价于通过“==”比较这两个对象。

​ 情况2:类覆盖了 equals() 方法。一般,我们都覆盖 equals() 方法来比较两个对象的内容相等;若它们的内容相等,则返回 true (即,认为这两个对象相等)。


hashCode 与 equals (重要)


hashCode()介绍

​ hashCode() 的作用是获取哈希码,也称为散列码;它实际上是返回一个int整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。hashCode() 定义在JDK的Object.java中,这就意味着Java中的任何类都包含有hashCode()函数。

​ 散列表存储的是键值对(key-value),它的特点是:能根据“键”快速的检索出对应的“值”。这其中就利用到了散列码!(可以快速找到所需要的对象)


hashCode()与equals()的相关规定

​ 如果两个对象相等,则hashcode一定也是相同的

​ 两个对象相等,对两个对象分别调用equals方法都返回true

​ 两个对象有相同的hashcode值,它们也不一定是相等的


因此,equals 方法被覆盖过,则 hashCode 方法也必须被覆盖

​ hashCode() 的默认行为是对堆上的对象产生独特值。如果没有重写 hashCode(),则该class的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)


对象的相等与指向他们的引用相等,两者有什么不同?

​ 对象的相等 比的是内存中存放的内容是否相等

​ 引用相等 比较的是他们指向的内存地址是否相等。



7. Java包


JDK 中常用的包有哪些

  • java.lang:这个是系统的基础类;
  • java.io:这里面是所有输入输出有关的类,比如文件操作等;
  • java.nio:为了完善 io 包中的功能,提高 io 包中性能而写的一个新包;
  • java.net:这里面是与网络有关的类;
  • java.util:这个是系统辅助类,特别是集合类;
  • java.sql:这个是数据库操作的类。


import java和javax有什么区别

​ 刚开始的时候 JavaAPI 所必需的包是 java 开头的包,javax 当时只是扩展 API 包来说使用。然而随着时间的推移,javax 逐渐的扩展成为 Java API 的组成部分。但是,将扩展从 javax 包移动到 java 包将是太麻烦了,最终会破坏一堆现有的代码。因此,最终决定 javax 包将成为标准API的一部分。

​ 所以,实际上java和javax没有区别。这都是一个名字。



四 Collection与Map



1. 集合和数组的区别?

  • 数组是固定长度的;集合可变长度的。
  • 数组可以存储基本数据类型,也可以存储引用数据类型;集合只能存储引用数据类型。
  • 数组存储的元素必须是同一个数据类型;集合存储的对象可以是不同数据类型。



2. Map接口和Collection接口是所有集合框架的父接口

  1. Collection接口的子接口包括:Set接口和List接口
  2. Map接口的实现类主要有:HashMap、TreeMap、Hashtable、ConcurrentHashMap以及Properties等
  3. Set接口的实现类主要有:HashSet、TreeSet、LinkedHashSet等
  4. List接口的实现类主要有:ArrayList、LinkedList、Stack以及Vector等

关系图:
img



3. 常用类及特点

  • Collection

    • List 有序可重复(元素存入集合的顺序和取出的顺序一致),可以插入多个null元素,元素都有索引。

      • ArrayList 底层是可变数组,线程不安全,有序可重复,查询快增删慢
      • LinkedList 底层是链表,线程不安全,有序可重复,查询慢增删快
      • Vector 底层是可变数组,线程安全,有序可重复,查询快增删慢
    • Set 无序不可以重复(存入和取出顺序有可能不一致),只允许存入一个null元素,必须保证元素唯一性。

      • HashSet 底层是哈希表,线程不安全,无序不可重复

        • LinkedHashSet 底层是基于链表的哈希表,链表有序,哈希表唯一,线程不安全
      • TreeSet 底层是红黑树(自平衡的二叉树),线程不安全,可以排序,不可重复
  • Map

    • HashMap 底层是映射哈希表,无序,键唯一,值可以重复,允许null键null值,线程不安全

      • LinkedHashMap 底层是基于链表的映射哈希表,有序,唯一,线程不安全
    • TreeMap 底层是红黑树(自平衡的二叉树),可以排序,无序,唯一,线程不安全
    • HashTable 底层是映射哈希表,无序,键唯一,值可以重复,不允许null键null值,线程安全

      • properties 底层是映射哈希表,可以喝io流结合使用的Map集合



4. 迭代器 Iterator与ListIterator

​ Iterator 接口提供遍历任何 Collection 的接口。允许调用者在迭代过程中移除元素。特点是只能单向遍历,但是更加安全,因为它可以确保在当前遍历的集合元素被更改的时候,就会抛出ConcurrentModificationException 异常。

​ ListIterator只能遍历 List。可以双向遍历(向前/后遍历)。实现了 Iterator 接口,然后添加了一些额外的功能,比如添加一个元素、替换一个元素、获取前面或后面元素的索引位置。



5. Arrays数组工具类和Collections集合工具类

​ Arrays是针对数组惊醒操作的工具类。

​ Collections则是集合类的一个工具类/帮助类,其中提供了一系列静态方法,用于对集合中元素进行排序、搜索以及线程安全等各种操作。



如何实现 Array 和 List 之间的转换?

​ Array 转 List: Arrays. asList(array)

​ List 转 Array:List 的 toArray()



6. Comparable 和 Comparator的区别?

  • comparable接口实际上是出自java.lang包,它有一个 compareTo(Object obj)方法用来排序
  • comparator接口实际上是出自 java.util 包,它有一个compare(Object obj1, Object obj2)方法用来排序

一般我们需要对一个集合使用自定义排序时,我们就要重写compareTo方法或compare方法,当我们需要对某一个集合实现两种排序方式,比如一个song对象中的歌名和歌手名分别采用一种排序方法的话,我们可以重写compareTo方法和使用自制的Comparator方法或者以两个Comparator来实现歌名排序和歌星名排序,第二种代表我们只能使用两个参数版的Collections.sort().



五 IO流



1. Java 中 IO 流分为几种?

  • 按照流的流向分,可以分为输入流和输出流;

  • 按照操作单元划分,可以划分为字节流和字符流;

  • 按照流的角色划分为节点流和处理流。

    Java IO流共涉及40多个类,这些类看上去很杂乱,但实际上很有规则,而且彼此之间存在非常紧密的联系, Java IO流的40多个类都是从如下4个抽象类基类中派生出来的。

  • InputStream/Reader: 所有的输入流的基类,前者是字节输入流,后者是字符输入流。

  • OutputStream/Writer: 所有输出流的基类,前者是字节输出流,后者是字符输出流。

按操作方式分类结构图:
IO-操作方式分类

按操作对象分类结构图:
IO-操作对象分类



2. BIO,NIO,AIO 有什么区别?

简答

  • BIO:Block IO 同步阻塞式 IO,就是我们平常使用的传统 IO,它的特点是模式简单使用方便,并发处理能力低。
  • NIO:Non IO 同步非阻塞 IO,是传统 IO 的升级,客户端和服务器端通过 Channel(通道)通讯,实现了多路复用。
  • AIO:Asynchronous IO 是 NIO 的升级,也叫 NIO2,实现了异步非堵塞 IO ,异步 IO 的操作基于事件和回调机制。

详细回答


  • BIO (Blocking I/O):

    同步阻塞I/O模式,数据的读取写入必须阻塞在一个线程内等待其完成。在活动连接数不是特别高(小于单机1000)的情况下,这种模型是比较不错的,可以让每一个连接专注于自己的 I/O 并且编程模型简单,也不用过多考虑系统的过载、限流等问题。线程池本身就是一个天然的漏斗,可以缓冲一些系统处理不了的连接或请求。但是,当面对十万甚至百万级连接的时候,传统的 BIO 模型是无能为力的。因此,我们需要一种更高效的 I/O 处理模型来应对更高的并发量。

  • NIO (New I/O):

    NIO是一种同步非阻塞的I/O模型,在Java 1.4 中引入了NIO框架,对应 java.nio 包,提供了 Channel , Selector,Buffer等抽象。NIO中的N可以理解为Non-blocking,不单纯是New。它支持面向缓冲的,基于通道的I/O操作方法。 NIO提供了与传统BIO模型中的

    Socket



    ServerSocket

    相对应的

    SocketChannel



    ServerSocketChannel

    两种不同的套接字通道实现,两种通道都支持阻塞和非阻塞两种模式。阻塞模式使用就像传统中的支持一样,比较简单,但是性能和可靠性都不好;非阻塞模式正好与之相反。对于低负载、低并发的应用程序,可以使用同步阻塞I/O来提升开发速率和更好的维护性;对于高负载、高并发的(网络)应用,应使用 NIO 的非阻塞模式来开发

  • AIO (Asynchronous I/O):

    AIO 也就是 NIO 2。在 Java 7 中引入了 NIO 的改进版 NIO 2,它是异步非阻塞的IO模型。异步 IO 是基于事件和回调机制实现的,也就是应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程进行后续的操作。AIO 是异步IO的缩写,虽然 NIO 在网络操作中,提供了非阻塞的方法,但是 NIO 的 IO 行为还是同步的。对于 NIO 来说,我们的业务线程是在 IO 操作准备好时,得到通知,接着就由这个线程自行进行 IO 操作,IO操作本身是同步的。查阅网上相关资料,我发现就目前来说 AIO 的应用还不是很广泛,Netty 之前也尝试使用过 AIO,不过又放弃了。



3. Files的常用方法都有哪些?

  • Files. exists():检测文件路径是否存在。
  • Files. createFile():创建文件。
  • Files. createDirectory():创建文件夹。
  • Files. delete():删除一个文件或目录。
  • Files. copy():复制文件。
  • Files. move():移动文件。
  • Files. size():查看文件个数。
  • Files. read():读取文件。
  • Files. write():写入文件。



六 反射



1. 什么是反射机制?

​ JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

​ 静态编译和动态编译

  • **静态编译:**在编译时确定类型,绑定对象
  • **动态编译:**运行时确定类型,绑定对象



2. 反射机制优缺点


  • 优点:

    运行期类型的判断,动态加载类,提高代码灵活度。

  • 缺点:

    性能瓶颈:反射相当于一系列解释操作,通知 JVM 要做的事情,性能比直接的java代码要慢很多。



3. 反射机制的应用场景有哪些?

​ 反射是框架设计的灵魂。

​ 在我们平时的项目开发过程中,基本上很少会直接使用到反射机制,但这不能说明反射机制没有用,实际上有很多设计、开发都与反射机制有关,例如模块化的开发,通过反射去调用对应的字节码;动态代理设计模式也采用了反射机制,还有我们日常使用的 Spring/Hibernate 等框架也大量使用到了反射机制。



4. Java获取反射的三种方法

​ 1.通过new对象实现反射机制

​ 2.通过路径实现反射机制

​ 3.通过类名实现反射机制



七 常用API



1. String相关


什么是字符串常量池?

​ 字符串常量池位于堆内存中,专门用来存储字符串常量,可以提高内存的使用率,避免开辟多块空间存储相同的字符串,在创建字符串时 JVM 会首先检查字符串常量池,如果该字符串已经存在池中,则返回它的引用,如果不存在,则实例化一个字符串放到池中,并返回其引用。


String有哪些特性?

  • 不变性:String 是只读字符串,是一个典型的 immutable 对象,对它进行任何操作,其实都是创建一个新的对象,再把引用指向该对象。不变模式的主要作用在于当一个对象需要被多线程共享并频繁访问时,可以保证数据的一致性。
  • 常量池优化:String 对象创建之后,会在字符串常量池中进行缓存,如果下次创建同样的对象时,会直接返回缓存的引用。
  • final:使用 final 来定义 String 类,表示 String 类不能被继承,提高了系统的安全性。


String为什么是不可变的?

​ 简单来说就是String类利用了final修饰的char类型数组存储字符,源码如下所以:

/** The value is used for character storage. */
private final char value[];


是否可以继承 String 类?

​ String 类是 final 类,不可以被继承。


String str=”i”与 String str=new String(“i”)一样吗?

​ 不一样,因为内存的分配方式不一样。String str=”i”的方式,java 虚拟机会将其分配到常量池中;而 String str=new String(“i”) 则会被分到堆内存中。


String s = new String(“xyz”);创建了几个字符串对象?

​ 两个对象,一个是静态区的”xyz”,一个是用new创建在堆上的对象。


String 类的常用方法都有那些?

  • indexOf():返回指定字符的索引。
  • charAt():返回指定索引处的字符。
  • replace():字符串替换。
  • trim():去除字符串两端空白。
  • split():分割字符串,返回一个分割后的字符串数组。
  • getBytes():返回字符串的 byte 类型数组。
  • length():返回字符串长度。
  • toLowerCase():将字符串转成小写字母。
  • toUpperCase():将字符串转成大写字符。
  • substring():截取字符串。
  • equals():字符串比较。


String和StringBuffer、StringBuilder的区别是什么?String为什么是不可变的?



可变性

​ String类中使用字符数组保存字符串,private final char value[],所以string对象是不可变的。StringBuilder与StringBuffer都继承自AbstractStringBuilder类,在AbstractStringBuilder中也是使用字符数组保存字符串,char[] value,这两种对象都是可变的。



线程安全性

​ String中的对象是不可变的,也就可以理解为常量,线程安全。AbstractStringBuilder是StringBuilder与StringBuffer的公共父类,定义了一些字符串的基本操作,如expandCapacity、append、insert、indexOf等公共方法。StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。StringBuilder并没有对方法进行加同步锁,所以是非线程安全的。



性能

​ 每次对String 类型进行改变的时候,都会生成一个新的String对象,然后将指针指向新的String 对象。StringBuffer每次都会对StringBuffer对象本身进行操作,而不是生成新的对象并改变对象引用。相同情况下使用StirngBuilder 相比使用StringBuffer 仅能获得10%~15% 左右的性能提升,但却要冒多线程不安全的风险。



对于三者使用的总结

​ 如果要操作少量的数据用 = String

​ 单线程操作字符串缓冲区 下操作大量数据 = StringBuilder

​ 多线程操作字符串缓冲区 下操作大量数据 = StringBuffer



2. Date相关



3. 包装类相关

​ Java 为了能够将基本数据类型当成对象操作,为每一个基本数据类型都引入了对应的包装类型(wrapper class)。

​ Java 为每个原始类型提供了包装类型:

​ 原始类型:boolean,char, byte,short,int, long, float,double

​ 包装类型:Boolean,Character,Byte,Short,Integer,Long,Float,Double


自动装箱与拆箱

​ 装箱:将基本类型用它们对应的引用类型包装起来;

​ 拆箱:将包装类型转换为基本数据类型;


Integer a= 127 与 Integer b = 127相等吗?

​ 对于对象引用类型:==比较的是对象的内存地址。

​ 对于基本数据类型:==比较的是值。

​ 如果整型字面量的值在-128到127之间,那么自动装箱时不会new新的Integer对象,而是直接引用常量池中的Integer对象,超过范围 a1==b1的结果是false



八 网络编程



九 常用工具类库



十 单元测试



十一 异常



十二 日志



版权声明:本文为Sple_xiaom原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。