【Java基础知识 1】Java入门级概述-程序员宅基地

技术标签: java  Java基础教程系列  

作者简介:哪吒,CSDN2022博客之星Top1、CSDN2021博客之星Top2、多届新星计划导师、博客专家
,专注Java硬核干货分享,立志做到Java赛道全网Top N。

本文收录于,Java基础教程系列,目前已经700+订阅,CSDN最强Java专栏,包含全部Java基础知识点、Java8新特性、Java集合、Java多线程、Java代码实例,理论结合实战,实现Java的轻松学习。

姐妹篇,Java基础教程(入门篇),包含面向对象、基本数据类型、数组、继承和多态、泛型、枚举等Java基础知识点。

姐妹进阶篇,Java基础教程(进阶篇),包含Java高并发、Spring、MySQL等Java进阶技术栈。

全部订阅,可加入Java学习星球,完成Java从入门、实战、进阶全方位的Java知识体系学习。

 小编之前写过一期Java学习路线总结️搬砖工逆袭Java架构师️(全网最强,建议收藏) 

广受大家喜爱,有的粉丝问我,能不能出一期入门级别的博客,好吧,是我考虑不周了,今天我就将它补上。

目录 

一、Java成名史

二、JDK 与 JRE 

三、语言的五大特性

四、对象间的四种关系

1、依赖

2、关联

3、聚合

4、组合

五、封装、继承、多态

1、封装

2、继承

3、多态

六、我的第一个Java程序

1、先配置环境变量

2、hello world

七、八种基本数据类型

八、Java的重要概念

1、类

2、普通类和抽象类

3、接口和抽象类

4、成员变量和局部变量

5、对象的创建和声明周期

6、final 和 static 

7、final、finally、finalize

8、Java运算符

9、循环结构

10、条件表达式

11、super与this

12、方法的重写

13、在 Java 中,什么时候用重载,什么时候用重写?

14、抽象类和接口

15、克隆

16、javac

九、Java Character 类

十、String

十一、数组

1、概念

2、格式

3、初始化

4、遍历

5、常见异常

十二、数据保存在哪里

1、寄存器

2、堆与栈

3、常量存储

4、非RAM存储

十三、java异常

十四、序列化与反序列化

十五、Java IO流

十六、泛型

十七、枚举

十八、注解

十九、动态代理

二十、反射机制

二十一、Java注意事项


一、Java成名史

想要学好一门语言,一定要了解它的历史,了解它存在的价值和意义。 

1991年成立了一个称为Green的项目小组,帕特里克、詹姆斯·高斯林、麦克·舍林丹和其他几个工程师一起组成的工作小组在加利福尼亚州门洛帕克市沙丘路的一个小工作室里面研究开发新技术,专攻计算机在家电产品上的嵌入式应用。

由于C++所具有的优势,该项目组的研究人员首先考虑采用C++来编写程序。但对于硬件资源极其匮乏的单片式系统来说,C++程序过于复杂和庞大。

为了解决困难,他们首先着眼于语言的开发,    对于新语言的设计,Sun公司研发人员并没有开发一种全新的语言,而是根据嵌入式软件的要求,对C++进行了改造,去除了留在C++的一些不太实用及影响安全的成分,并结合嵌入式系统的实时性要求,开发了一种称为Oak的面向对象语言。

1994年将Oak语言更名为Java。

1996年1月,Sun公司发布了Java的第一个开发工具包(JDK 1.0),这是Java发展历程中的重要里程碑,标志着Java成为一种独立的开发工具。

1998年12月8日,第二代Java平台的企业版J2EE发布。

1999年4月27日,HotSpot虚拟机发布。
2005年6月,在Java One大会上,Sun公司发布了Java SE 6。此时,Java的各种版本已经更名,已取消其中的数字2,如J2EE更名为JavaEE,J2SE更名为JavaSE,J2ME更名为JavaME。

2009年,甲骨文公司宣布收购Sun。

2014年3月Oracle发布正式版JDK8,JDK8改进比较多,最大的改进是Lambda表达式(以及因之带来的函数式接口,很多原有类都做了变更,但能够与以往版本兼容,堪称奇功!),还有Stream API流式处理,joda-time等等一些新特性。

二、JDK 与 JRE 

49天精通Java,第8天,JDK 和 JRE 、final 与 static 、堆和栈

JDK:java development kit (java开发工具)

JRE:java runtime environment (java运行时环境)

JVM:Java Virtual Machine (java虚拟机)

1、jdk--开发环境(核心)

Java development kit的缩写,意思是Java开发工具,我们写文档做PPT需要office 办公软件,开发当然需要开发工具了,说到开发工具大家肯定会想到Eclipse,但是如果直接安装Eclipse你会发现它是运行不起来 是会报错的,只有安装了JDK,配置好了环境变量和path才可以运行成功。这点相信很多人都深有体会。

jdk主要包含三个部分:

第一部分是Java运行时环境,JVM

第二部分是Java的基础类库,这个类库的数量还是相当可观的

第三部分是Java的开发工具,它们都是辅助你更好地使用Java的利器jre--运行环境

2、jre--运行环境

① jdk中的jre

如下图:jdk中包含的jre,在jre的bin目录里有个jvm.dll,既然JRE是运行时环境,那么运行在哪?肯定是JVM虚拟机上了。另,jre的lib目录中放的是一些JAVA类库的class文件,已经打包成jar文件。

② 第二个JRE(独立出来的运行时环境)

如下图,不管是JDK中的JRE还是JRE既然是运行时环境必须有JVM。所以JVM也是有两个的。

3、JVM——转换环境

Java Virtual Machine (java虚拟机)的缩写。

大家一提到JAVA的优点就会想到:一次编译,随处运行,说白了就是跨平台性好,这点JVM功不可没。

Java的程序也就是我们编译的代码都会编译为class文件,class文件就是在jvm上运行的文件,只有JVM还不能完全支持class的执行,因为在解释class的时候JVM需要调用解释所需要的类库lib,而jre包含lib类库。

JVM屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改的运行。

JVM也是一门很深的学问,感兴趣的同学可以深入研究,只有好处,没有坏处。

其实有时候面试官问JDK和JRE的区别的目的不是想让你解释什么名词的,而是想看看你的基础和研究Java的深浅,还有另一方面就是你是不是经常喜欢问为什么。

三、语言的五大特性

  1. 万物皆对象
  2. 程序就是多个对象彼此调用方法的过程
  3. 从内存角度而言,每个对象都是由其它更基础的对象组成的
  4. 每一个对象都有类型,都可以进行实例化
  5. 同一类型的对象可以接收相同的消息

面向对象编程的最大挑战就是如何在问题空间的元素和解决方案空间的对象之间建立一对一的关联。

四、对象间的四种关系

1、依赖

依赖关系表示一个类依赖于另一个类的定义。例如,一个人(Person)可以买车(car)和房子(House),Person类依赖于Car类和House类的定义,因为Person类引用了Car和House。与关联不同的是,Person类里并没有Car和House类型的属性,Car和House的实例是以参量的方式传入到buy()方法中去的。一般而言,依赖关系在Java语言中体现为局域变量、方法的形参,或者对静态方法的调用。 

2、关联

关联(Association)关系是类与类之间的联接,它使一个类知道另一个类的属性和方法。关联可以是双向的,也可以是单向的。在Java语言中,关联关系一般使用成员变量来实现。

3、聚合

聚合(Aggregation) 关系是关联关系的一种,是强的关联关系。聚合是整体和个体之间的关系。例如,汽车类与引擎类、轮胎类,以及其它的零件类之间的关系便整体和个体的关系。与关联关系一样,聚合关系也是通过实例变量实现的。但是关联关系所涉及的两个类是处在同一层次上的,而在聚合关系中,两个类是处在不平等层次上的,一个代表整体,另一个代表部分。 

4、组合

组合(Composition) 关系是关联关系的一种,是比聚合关系强的关系。它要求普通的聚合关系中代表整体的对象负责代表部分对象的生命周期,组合关系是不能共享的。代表整体的对象需要负责保持部分对象和存活,在一些情况下将负责代表部分的对象湮灭掉。代表整体的对象可以将代表部分的对象传递给另一个对象,由后者负责此对象的生命周期。换言之,代表部分的对象在每一个时刻只能与一个对象发生组合关系,由后者排他地负责生命周期。部分和整体的生命周期一样。 

五、封装、继承、多态

49天精通Java,第10天,Java继承和多态

1、封装

封装就是把对象的属性和行为结合为一个独立的整体,并尽可能多的隐藏对象的内部实现细节。

2、继承

对象用来封装数据和功能,但我们要创建一个新类,然而它又与已存在的类具有部分相同的属性或功能,此时,为了代码复用原则,可以使用继承来实现。

继承通过基类和子类的概念来表达,基类的所有特征和行为都可以与子类共享。也就是说,你可以通过基类呈现核心思想,从基类继承的子类则为核心思想提供不同的实现方式。

有时基类和子类的方法都是一样的,这时你就可以直接用子类的对象代替基类的对象,这种纯替代关系通常叫做替换原则。

有时,子类会添加一些新的方法,此时就是不完美替换。

3、多态

通过将子类对象引用赋给父类对象引用来实现动态方法调用。

List<String> list = new ArrayList<String>();

六、我的第一个Java程序

1、先配置环境变量

【Java基础知识 3】为何要配置环境变量?

2、hello world

package com.guor;

public class Test{
    public static void main(String[] args) {
        System.out.println("hello world!");
    }
}

七、八种基本数据类型

数据类型 内存
byte 8位

short

16位

int

32位

long

64位

float

32位

double

64位

char

16位

boolean 1个字节或4个字节

【Java基础知识 5】装箱和拆箱

java中的方法可以传递参数,参数的传递方法就是值传递。

参数有形参和实参,定义方法时写的参数叫形参,真正调用方法时,传递的参数叫实参。

调用方法时,会把实参传递给形参,方法内部其实是在使用形参。

所谓值传递就是当参数是基本类型时,传递参数的值,比如传递i=10,真实传参时,把10赋值给了形参。

当参数是对象时,传递的是对象的值,也就是对象的首地址。就是把对象的地址赋值给形参。

八、Java的重要概念

1、类

类的创建者负责在创建新的类时,只暴露必要的接口给客户程序员,同时隐藏其它所有不必要的信息。

为什么这么做呢?

(1)因为如果这些信息对于客户程序员而言是不可见的,那么类的创建者就可以任意修改隐藏信息,而无需担心对其它任何人造成影响。隐藏的代码通常代表着一个对象内部脆弱的部分,如果轻易暴露给粗心或经验不足的客户程序员,就可能在顷刻之间被破坏殆尽。所以,隐藏代码的具体实现可以有效减少程序bug。

(2)让类库的设计者在改变类的内部工作机制时,不用担心影响到使用该类的客户程序员。

Java提供了三个显示关键字来控制访问权限。

2、普通类和抽象类

  1. 抽象类不能被实例化;
  2. 抽象类可以有抽象方法,只需申明,无须实现;
  3. 有抽象方法的类一定是抽象类;
  4. 抽象类的子类必须实现抽象类中的所有抽象方法,否则子类仍然是抽象类;
  5. 抽象方法不能声明为静态、不能被static、final修饰。

3、接口和抽象类

(1)接口

  1. 接口使用interface修饰;
  2. 接口不能实例化;
  3. 类可以实现多个接口;
  4. java8之前,接口中的方法都是抽象方法,省略了public abstract。②java8之后;接口中可以定义静态方法,静态方法必须有方法体,普通方法没有方法体,需要被实现;

(2)抽象类

  1. 抽象类使用abstract修饰;
  2. 抽象类不能被实例化;
  3. 抽象类只能单继承;
  4. 抽象类中可以包含抽象方法和非抽象方法,非抽象方法需要有方法体;
  5. 如果一个类继承了抽象类,①如果实现了所有的抽象方法,子类可以不是抽象类;②如果没有实现所有的抽象方法,子类仍然是抽象类。

4、成员变量和局部变量

(1)在类中的位置不同

成员变量:类中方法外;

局部变量:方法定义中或者方法声明上;

(2)在内存中的位置不同

成员变量:在堆中

局部变量:在栈中

(3)生命周期不同

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

局部变量:随着方法的调用而存在,随着方法的调用完毕而消失

(4)初始化值不同

成员变量:有默认值

局部变量:没有默认值,必须定义,赋值,然后才能使用

5、对象的创建和声明周期

对象的创建需要消耗一些资源,尤其是内存资源。

当我们不再需要一个对象时,就要及时清理它,这样占用的资源才能被释放并重复使用。

如果要最大化运行时效率,可以通过栈区(局部变量)来保存对象,或者将对象保存在静态区里,这样在编写程序时就可以明确的知道对象的内存分配和生命周期,这种做法会优先考虑分配和释放内存的速度。但是代价就是牺牲了灵活性,因为你必须在编写代码时就明确对象的数量、生命周期以及类型,但是这种写法的限制性很大。

还有一种方案是在内存池中动态创建对象,这个内存池也就堆。如果使用这个方案,直到运行时你才能知道需要多少对象,以及它们的生命周期和确切的类型是什么。如果需要创建一个新对象,可以直接通过堆来创建。因为堆是在运行时动态管理内存的,所以堆分配内存所花费的时间通常会比栈多一些。栈通常利用汇编指令向下或向上移动栈指针来管理内存,而堆何时分配内存则取决于内存机制的实现方式。

Java只允许动态分配内存,每当要创建一个对象时,都需要使用new来创建一个对象的动态实例。

如果在栈中创建对象,编译器会判断对象存在时间以及负责自动销毁该对象。

如果在堆中创建对象,编译器就无法得知对象的生命周期。

Java支持垃圾回收机制,它会自动找到没用的对象将其销毁。

6、final 和 static 

49天精通Java,第9天,java final关键字

Java 中的 static 关键字详解

都可以修饰类、方法、成员变量

static可以修饰类的代码块,final不可以

static不可以修饰方法内局部变量,final可以

static修饰表示静态或全局

static修饰的代码块表示静态代码块,当JVM加载类时,只会被创建一次

static修饰的变量可以重新赋值

static方法中不能用this和super关键字

因为this代表的是调用这个函数的对象的引用,而静态方法是属于类的,不属于对象,静态方法成功加载后, 对象还不一定存在。 this代表对本类对象的引用,指向本类已创建的对象。 super代表对父类对象的引用,指向父类对象。 静态优先于对象存在,方法被static修饰之后,方法先存在,所需的父类引用对象晚于该方法的出 现,也就是super所指向的对象还没出现,当然就会报错。

static方法必须被实现,而不能是抽象的abstract

static方法只能被static方法覆盖

final修饰表示常量、一旦创建不可被修改

final标记的成员变量必须在声明的同时赋值,或在该类的构造方法中赋值,不可重新赋值

final方法不能被子类重写

final类不能被继承,没有子类,final类中的方法默认是final的

final不能用于修饰构造方法

private类型的方法默认是final类型的

7、final、finally、finalize

final可以修饰类,变量,方法,修饰的类不能被继承,修饰的变量不能重新赋值,修饰的方法不能被重写

finally用于抛异常,finally代码块内语句无论是否发生异常,都会在执行finally,常用于一些流的关闭。

finalize方法用于垃圾回收。

一般情况下不需要我们实现finalize,当对象被回收的时候需要释放一些资源,比如socket链接,在对象初始化时创建,整个生命周期内有效,那么需要实现finalize方法,关闭这个链接。

但是当调用finalize方法后,并不意味着gc会立即回收该对象,所以有可能真正调用的时候,对象又不需要回收了,然后到了真正要回收的时候,因为之前调用过一次,这次又不会调用了,产生问题。所以,不推荐使用finalize方法。

8、Java运算符

  • 算术运算符
  • 关系运算符
  • 位运算符
  • 逻辑运算符
  • 赋值运算符
  • 其他运算符

9、循环结构

  1. for
  2. while
  3. do...while

10、条件表达式

  1. if...else...
  2. switch case

11、super与this

  1. super关键字可以在子类的构造方法中显示地调用父类的构造方法,super()必须为子类构造函数中的第一行。
  2. super可以用来访问父类的成员方法或变量,当子类成员变量或方法与父类有相同的名字时也会覆盖父类的成员变量或方法,这个时候要想访问父类的成员变量或方法只能通过super关键字来访问,子类方法中的super.方法名()不需要位于第一行。
  3. this关键字指向的是当前对象的引用,用来区分成员变量和局部变量(重名问题)
  4. this() 不能使用在普通方法中 只能写在构造方法中。
  5. 必须是构造方法中的第一条语句。

12、方法的重写

父类的功能无法满足子类的需求时,则需要用到重写;

重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。

重写的注意事项:

  1. 参数列表必须完全与被重写方法的相同;
  2. 返回类型必须完全与被重写方法的返回类型相同;
  3. 访问权限不能比父类中被重写的方法的访问权限更低;
  4. 声明为final的方法不能被重写;
  5. 声明为static的方法不能被重写,但是能够被再次声明;
  6. 构造方法不能被重写;
  7. 子类和父类在同一个包中,那么子类可以重写父类所有除了声明为private和final 的方法;
  8. 如果不能继承一个方法,则不能重写这个方;
  9. 子类和父类不在同一个包中,那么子类只能够重写父类的声明为public和 protected的非final方法;
  10. 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是, 重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性 异常,反之则可以。

13、在 Java 中,什么时候用重载,什么时候用重写?

(1)重载是多态的集中体现,在类中,要以统一的方式处理不同类型数据的时候,可以用重载。

(2)重写的使用是建立在继承关系上的,子类在继承父类的基础上,增加新的功能,可以用重写。

(3)简单总结:

  1. 重载是多样性,重写是增强剂;
  2. 目的是提高程序的多样性和健壮性,以适配不同场景使用时,使用重载进行扩展;
  3. 目的是在不修改原方法及源代码的基础上对方法进行扩展或增强时,使用重写;

14、抽象类和接口

49天精通Java,第11天,java接口和抽象类的异同,default关键字

接口和抽象类都遵循”面向接口而不是实现编码”设计原则,它可以增加代码的灵活性,可以适应不断变化的需求。下面有几个点可以帮助你回答这个问题:在 Java 中,你只能继承一个类,但可以实现多个接口。所以一旦你继承了一个类,你就失去了继承其他类的机会了。

接口通常被用来表示附属描述或行为如: Runnable 、 Clonable 、 Serializable 等等,因此当你使用抽象类来表示行为时,你的类就不能同时是 Runnable 和 Clonable( 注:这里的意思是指如果把 Runnable 等实现为抽象类的情况 ) ,因为在 Java 中你不能继承两个类,但当你使用接口时,你的类就可以同时拥有多个不同的行为。

在一些对时间要求比较高的应用中,倾向于使用抽象类,它会比接口稍快一点。如果希望把一系列行为都规范在类继承层次内,并且可以更好地在同一个地方进行编码,那么抽象类是一个更好的选择。有时,接口和抽象类可以一起使用,接口中定义函数,而在抽象类中定义默认的实现。

15、克隆

(1)什么要使用克隆?

想对一个对象进行复制,又想保留原有的对象进行接下来的操作,这个时候就需要克隆了。

(2)如何实现对象克隆?

实现Cloneable接口,重写clone方法;
实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深克隆。
BeanUtils,apache和Spring都提供了bean工具,只是这都是浅克隆。

(3)深拷贝和浅拷贝区别是什么?

浅拷贝:仅仅克隆基本类型变量,不克隆引用类型变量;
深克隆:既克隆基本类型变量,又克隆引用类型变量;

16、javac

Java是动态语言吗?从《Java核心编程》探索真知

(1)javac是什么

  1. javac是一种编译器,能够将一种语言规范转化成另外一种语言规范
  2. javac的任务就是将Java源代码转化成JVM能够识别的一种语言(Java字节码),这种字节码不是针对某种机器、某种平台的

(2)javac编译器编译程序的步骤

① 词法分析

首先是读取源代码,找出这些字节中哪些是我们定义的语法关键词,如Java中的if、else、for等关键词。

语法分析的结果:从源代码中找出一些规范化的token流。

注:token是一种认证机制

② 语法分析

检查关键词组合在一起是不是Java语言规范,如if后面是不是紧跟着一个布尔表达式。

语法分析的结果:形成一个符合Java语言规范的抽象语法树

③ 语义分析

把一些难懂的、复杂的语法转化为更加简单的语法。

语义分析的结果:完成复杂语法到简单语法的简化,如将foreach语句转化成for循环结果,还有注解等。最后形成一个注解过后的抽象语法树,这颗语法树更接近目标语言的语法规则。

④ 生成字节码

通过字节码生成器生成字节码,根据经过注解的抽象语法树生成字节码,也就是将一个数据结构转化成另一个数据结构。

代码生成器的结果:生成符合Java虚拟机规范的字节码。

注:抽象语法树

在计算机科学中,抽象语法树是源代码语法结构的一种抽象表示。它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构。

(3)javac编译器的基本结构

按照上述编译步骤来看,可以将javac编译器分为4个模块:词法分析器、语法分析器、语义分析器和代码生成器。

九、Java Character 类

【Java集合 4】Java.lang.Character类详解

十、String

【Java基础知识 7】toString()、String.valueOf、(String)强转

【Java基础知识 8】String、StringBuilder、StringBuffer详解

十一、数组

1、概念

同一种数据类型的集合,数组是一个容器。

数组能够对存储的元素进行自动排号,编号从0开始,方便操作。

2、格式

int[] arr = new int[10]; 

3、初始化

//方式1
int[] arr = { 1, 2, 3, 4, 5 };

//方式2
int[] arr3=new int[3];
arr3[0]=1;
arr3[1]=2;
arr3[2]=3;

4、遍历


public class Test{
    public static void main(String[] args) {
        String[] arr = new String[3];
        arr[0] = "CSDN";
        arr[1] = "哪吒";
        arr[2] = "博客专家";
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }

        for (String str:arr) {
            System.out.println(str);
        }
    }
}

5、常见异常

  1. NullPointerException 空指针异常
  2. ArrayIndexOutOfBoundsException 索引值越界

【Java基础知识 4】秒懂数组拷贝,感知新境界

十二、数据保存在哪里

1、寄存器

寄存器是速度最快的数据存储方式,数据直接保存在中央处理器,然而寄存器的数量是有限的,所以只能按需分配。

JVM中有4种常见的寄存器:

  1. pc程序寄存器
  2. optop操作数栈顶指针
  3. frame当前执行环境指针
  4. vars指向当前执行环境中第一个局部变量的指针

所有寄存器都为32位。

pc用于记录程序的执行,optop,frame和vars用于记录指向Java栈区的指针。

2、堆与栈

一文读懂JVM类加载机制过程及原理

(1)堆内存用于存放new创建的对象

在堆中分配的内存,由JVM自动垃圾回收器管理。

在堆中产生一个对象后,会在栈中定义一个特殊变量,这个变量的取值等于数组或对象在堆内存中的首地址,在栈中的这个特殊的变量就编程了数组或者对象的引用变量,以后就可以在程序中使用栈内存中的引用变量来访问堆中的对象。

对象在没有引用变量指向它的时候,才会编程垃圾,不能再被使用,但是仍然占着内存,在随后一个不确定的时间点被垃圾回收器释放掉。这也是Java程序比较占内存的主要原因,实际上,栈中的变量指向堆内存中的变量,这就是Java中的指针。

(2)在函数中定义的一些基本类型的变量和对象的引用变量都是在栈内存中分配的。

当一段代码定义一个变量时,java就在栈中分配一个内存,当超过变量的作用域后,java会自动释放掉该变量分配的内存空间。

简而言之,堆是用来存放对象的,栈是运行程序的。

堆:为成员分配和释放,由程序员自己申请、自己释放。否则发生内存泄露。典型为使用 new 申请的堆内容。

栈为编译器自动分配和释放,如函数参数、局部变量、临时变量等等。

如果想迅速进行垃圾回收,可以将对象置为null。

3、常量存储

常量通常会直接写在程序代码中,不可变。

4、非RAM存储

不保存在应用程序里的数据,最典型的例子就是序列化对象,它指的是转换为字节流并可以发送到其它机器的对象。另一个例子则是持久化对象,它指的是保存在磁盘上的对象。也支持使用数据库存储对象信息。

大多数微处理芯片有额外的缓存内存,只不过缓存内容使用的是传统的内存管理方式,而非寄存器。

一个例子是字符串常量池,所有字符串和字符串常量都会被自动放置到这个特殊的存储空间中。

特殊情况 -> 原始类型

原始类型是直接创建一个“自动变量”,不是引用,该变量直接在栈上保存它的值,运行效率更高。

十三、java异常

【Java基础知识 6】Java异常详解

十四、序列化与反序列化

Java序列化与反序列化详解

十五、Java IO流

【Java基础知识 10】Java IO流详解

十六、泛型

在Java5之前,JAVA语言的集合所支持的通用类型是Object。因为单根结构决定了所有对象都属于Object类型,所以一个持有Object的集合就可以持有任何对象,这就使得集合十分易于复用。

其实并不能保存原始数据类型,不过自动装箱机制在一定程度上解决了这个问题。

当集合中持有Object类型时,要添加一个对象到集合中,该对象会向上转型为Object,从而失去了原本的类型。当你需要将其取出时,会获得一个Object类型的对象引用,这就不是当初的类型了,需要进行向下转型。但除非明确知道对象的具体类型,否则向下转型是不安全的,转型失败会抛出异常。

这个问题的解决方式是“参数化类型”,一个被参数化的类型是一种特殊的类,可以让编译器自动适配特定的类型,参数化类型也叫泛型,通过尖括号中间加上类名来定义泛型,比如List<String>。

【Java 基础知识 11】Java泛型详解

十七、枚举

【Java基础知识 12】Java枚举详解

十八、注解

【Java基础知识 13】Java注解详解

十九、动态代理

【Java基础知识 14】Java动态代理

二十、反射机制

【Java基础知识 15】Java反射机制

二十一、Java高并发编程

Java高并发编程实战1,那些年学过的锁

二十二、Java注意事项

  1. ​尽量使用final修饰符
  2. 尽量重用对象
  3. 尽可能使用局部变量
  4. 及时关闭流
  5. 尽量减少对变量的重复计算
  6. 尽量采用懒加载的策略,即在需要的时候才创建
  7. 慎用异常
  8. 不要在循环中使用trycatch,应该把其放在最外层
  9. 尽量能估计到待添加的内容的长度,为底层以数组方式实现的集合、工具类指定初始长度
  10. 当复制大量数据时,使用system.arraycopy命令
  11. 乘法和除法使用移位操作
  12. 循环内不要不断创建对象引用
  13. 基于效率和类型检查的考虑,应该尽可能使用array,无法确定数组大小时才使用ArrayList
  14. 尽量使用hashmap、ArrayList、stringbuilder,除非线程安全需要,否则不建议使用hashtable、vector、stringbuffer,后三者由于使用同步机制而导致了性能开销。
  15. 不要讲数组声明为public static final
  16. 尽量在合适的场合使用单例模式
  17. 尽量避免使用静态变量
  18. 及时清除不再需要的会话
  19. 实现RandomAccess接口的集合比如ArrayList,应当使用最普通的for循环而不是foreach循环
  20. 使用同步代码块代替同步方法
  21. 将常量声明为static final,并以大写命名
  22. 不要创建一些不使用的对象,不要导入一些不使用的类
  23. 程序运行过程中避免使用反射
  24. 使用数据库连接池和线程池
  25. 使用带缓冲的输入输出流进行IO操作
  26. 顺序插入和随机访问比较多的场景用ArrayList,元素删除和中间插入比较多的场景使用LinkedList
  27. 不要让public方法中有太多的参数
  28. 字符串变量和字符串常量equals的时候将字符串常量写在前面
  29. 请知道,在java中if (i == 1)和if (1 == i)是没有区别的,但从阅读习惯上讲,建议使用前者
  30. 不要对数组使用toString方法
  31. 不要对超出范围的基础数据类型做向下强制类型转型
  32. 公用的集合类中不使用的数据一定要及时的remove掉
  33. 把一个基本类型转为字符串,toString最快,String.valueOf次之,数据+“”最慢
  34. 使用最有效率的方法去遍历map
  35. 对资源的close()建议分开操作

作者简介:哪吒,CSDN2022博客之星Top1、CSDN2021博客之星Top2、多届新星计划导师、博客专家
,专注Java硬核干货分享,立志做到Java赛道全网Top N。

本文收录于,Java基础教程系列,目前已经700+订阅,CSDN最强Java专栏,包含全部Java基础知识点、Java8新特性、Java集合、Java多线程、Java代码实例,理论结合实战,实现Java的轻松学习。

姐妹篇,Java基础教程(入门篇),包含面向对象、基本数据类型、数组、继承和多态、泛型、枚举等Java基础知识点。

姐妹进阶篇,Java基础教程(进阶篇),包含Java高并发、Spring、MySQL等Java进阶技术栈。

全部订阅,可加入Java学习星球,完成Java从入门、实战、进阶全方位的Java知识体系学习。

上一篇:Java学习路线总结(思维导图篇)

下一篇:【Java基础知识 2】配置java环境变量

 关注公众号,备注1024,获取Java学习路线思维导图、加入万粉计划交流群 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/guorui_java/article/details/120432267

智能推荐

IntelliJ IDEA 2021.2 : 更新Docker 和 Kubernetes_idea中docker-compose有个x-程序员宅基地

文章浏览阅读810次。除了我们在 EAP 期间描述的其他有用功能外,IntelliJ IDEA 2021.2还包含一些对 Kubernetes 和 Docker 有用的更新。下载IntelliJ IDEA最新版本以下功能概述将帮助您浏览众多更改。Docker 撰写服务同步以前,您的 IDE 仅在“服务”工具窗口中显示正在运行的服务。从这个 EAP 开始,你可以让你的所有 Docker Compose 应用程序出现在那里,即使它们没有运行。要显示它们,您可以单击编辑器窗口右侧的循环箭头图标。服务状态的._idea中docker-compose有个x

程序员必须掌握的核心算法有哪些?_程序的核心算法有什么-程序员宅基地

文章浏览阅读126次。From:https://blog.csdn.net/m0_37907797/article/details/102661778?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task ..._程序的核心算法有什么

pm2 常用命令_pm2 删除进程-程序员宅基地

文章浏览阅读2.6k次。先说一些废话之前学习Nodejs项目的时候使用了pm2作为生产环境的进程管理工具,最近服务器崩了需要重启一些服务,发现有些命令记得不是特别清楚,所以这里写一篇文章帮助自己记忆整理一下pm2的常用命令,后续有需要查阅一下即可~常用命令进入bin目录启动:pm2 start www / pm2 start app.jspm2 start app.js --name="fx67ll" 启动并命名为fx67ll,没有命名的话后续可以用id替代namepm2 start app.js --watch 当_pm2 删除进程

【C语言】do-while()循环_do while循环语句什么时候结束循环-程序员宅基地

文章浏览阅读2.1k次。C语言中的do—while()循环,nreak和continue在其中的应用。_do while循环语句什么时候结束循环

ECCV 2020 | 史上最强二值化网络ReActNet,精度首超ResNet-程序员宅基地

文章浏览阅读1k次。在众多卷积神经网络(CNN)压缩算法中,二值化网络(BNN)作为网络量化的极端情况,一直拥有着高压缩比,高加速比的性能优势,但是 BNN 的精度不高也一直饱受诟病,阻碍了 BNN 在实际..._reactnet

(CVE-2020-21224)浪潮ClusterEngineV4.0 远程命令执行漏洞复现-程序员宅基地

文章浏览阅读3.3k次,点赞3次,收藏3次。简介浪潮 Inspur ClusterEngine是中国浪潮公司的一个应用软件。提供管理集群系统中软硬件提交的作业。漏洞描述浪潮服务器群集管理系统存在危险字符未过滤,导致远程命令执行影响版本浪潮ClusterEngineV4.0FOFAtitle="TSCEV4.0"复现过程FOFA搜索:登录页面:输入账号密码,进行抓包:页面不存在验证码,且存在用户名枚举,进行暴力破解:通过fuzz,发现在用户名或密码任意一处添加 ’ ,会报错:正常输入:添加单引号:添加分号,_cve-2020-21224

随便推点

JJwt生成Token-程序员宅基地

文章浏览阅读646次。JJwt生成tokenjava中通过jjwt生成tokenpackage com.zom.statistics.tools;import com.zom.statistics.DTO.JwtParams;import com.zom.statistics.DTO.RtvConsoleUser;import com.zom.statistics.exception.LogonException;import io.jsonwebtoken.*;import org.slf4j.Logger_jjwt生成token

电池充电方案总结-程序员宅基地

文章浏览阅读1.3w次。锂离子电池低电压充电(12V以下):多种化学成分电池充电器电路+源码+上位机等http://www.cirmall.com/circuit/3673/%E5%A4%9A%E7%A7%8D%E5%8C%96%E5%AD%A6%E6%88%90%E5%88%86%E7%94%B5%E6%B1%A0%E5%85%85%E7%94%B5%E5%99%A8%E7%94%B5%E8%B7%AF%2B%..._stm32单片机支持13种快冲协议的充电器源码和原理图

如何替换Citrix XenDesktop中使用的vCenter server地址-程序员宅基地

文章浏览阅读477次。一、问题描述:客户重装Vcenter之后(Hostname与之前保持一致)出现如下报错:1.计算机目录显示无法联系到vCenter server2.VM电源状态未知3.测试connection出现如下错误:Attempting to connect to the VCenter server failed due to a certificate error. Check ..._citrix vcenter替换

Android Studio Lint 工具看完这一篇还不够-程序员宅基地

文章浏览阅读6.5k次,点赞12次,收藏24次。前言以前对下面的问题,我的态度是,不报错就是没问题,报错就用快捷键,根据Android Studio提示修复问题,从来不去问个为什么?现在代码洁癖症越来越严重的我,忍不住想看清什么东西在搞鬼。认真看完本文,一定可以学到最新的知识。就算看不下去,也要点个赞收藏,绝对不亏。本文并不是吐槽Lint的不好,而是在学习Lint过程碰到问题,心态是奔溃的,以及解决每个问题带来的喜感。不知道大家有没有注意..._android studio lint

CDH激活分发parcel时因为意外错误卡住不能修改问题解决方案_cdh parcel激活一直卡住-程序员宅基地

文章浏览阅读2.7k次。问题背景:今天因为业务需求需要在CDH集群上安装StreamSets,结果因为权限的原因,之前我把这个parcel文件的权限变更为cloudera-scm,结果后面遇到这个问题了,问了之前部署CDH的人才知道他那时候用的权限是Root用户,所以现在卡在这里,也没有地方可以直接暂停:然后我点进去看详细的信息:可以看到cluster2-1这个结点因为权限的问题,导致不能激活。解决方案:Cloudera并没有在控制台开发Cancel或者回滚的入口,此时服务状态就是卡住页面无法操作。通过_cdh parcel激活一直卡住

TinyRayTracer 用256行C++代码构建一个可理解的光线追踪器(1)_understandable raytracing in 256 lines of bare c++-程序员宅基地

文章浏览阅读1.6k次,点赞7次,收藏13次。网上有大量的光线追踪相关的文章,然而问题在于几乎所有的这些文章都在展示那些成熟的非常难以理解程序。举个例子,非常著名的 明信片光线追踪器 挑战。这段简洁的程序令人印象深刻,但却很难让人理解它是怎么工作的。我想详细地教你怎样实现,而不是向你展示我能完成图像渲染。_understandable raytracing in 256 lines of bare c++

推荐文章

热门文章

相关标签