需要时常回顾的java基础知识

2024-06-09 16:38

本文主要是介绍需要时常回顾的java基础知识,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Java装载和编译原则

1.      Java的装载过程为:先装载类,然后初始化静态变量

2.      Java编译器要保证所有静态成员在使用前都分配好自己的内存空间,而非静态成员只有在使用的时候才能分配内存。(静态内部类中定义了静态成员,那么该类就一定是静态的)

3.      如果内部类不是静态的,则按照1,2条,非静态内部类只有在外部类被实现之后才能初始化

4.      按照3,只有非静态内部类初始化之后,内部类中的静态变量才能被初始化。

5.      这样的话4与2相悖,因为java编译器要保证所有静态变量在使用前都被初始化,并分配内存

6.      这样,要保证java编译器原则,如果要在内部类中定义静态成员,内部类也应该定义成静态,保证外部类一加载所有静态成员全部初始化,并拥有自己的内存空间,以备使用

JVM的流程:

加载 -- 连接 -- 初始化 -- 使用 -- 卸载

在卸载时:
在类使用完之后可能会被卸载,可能性如下:
如果有下面的情况,类就会被卸载:

1.      该类所有的实例都已经被回收,也就是java堆中不存在该类的任何实例。

2.      加载该类的ClassLoader已经被回收。

3.      该类对应的java.lang.Class对象没有任何地方被引用,无法在任何地方通过反射访问该类的方法。

如果以上三个条件全部满足,jvm就会在方法区垃圾回收的时候对类进行卸载,类的卸载过程其实就是在方法区中清空类信息,java类的整个生命周期就结束了。

 

java中几个常见的存储区域:

1.      方法区:在java的虚拟机中有一块专门用来存放已经加载的类信息、常量、静态变量以及方法代码的内存区域,叫做方法区。

2.      常量池:常量池是方法区的一部分,主要用来存放常量和类中的符号引用等信息。

3.      堆区:用于存放类的对象实例。

4.      栈区:也叫java虚拟机栈,是由一个一个的栈帧组成的后进先出的栈式结构,栈桢中存放方法运行时产生的局部变量、方法出口等信息。当调用一个方法时,虚拟机栈中就会创建一个栈帧存放这些数据,当方法调用完成时,栈帧消失,如果方法中调用了其他方法,则继续在栈顶创建新的栈桢。

创建person.class对象的整个流程

Person p;

加载类阶段

1.      加载class文件:因为new用到person.class,所以会先找到person.class文件并加载到内存中(方法区);

2.      执行静态代码块:执行该类中的static代码块,给person.class类进行初始化;

3.      开辟类内存:在堆中开辟空间,分配内存地址(堆区)。

4.      初始化静态属性:开辟空间存储静态变量并对静态数据进行初始化(方法区)

5.      存储静态函数:在内存中为静态函数开辟空间(方法区)。

存储对象阶段

6.      为属性开辟空间:在存中建立对象的特有属性,并对其进行默认初始化初始化(堆区)

7.      初始化属性:对属性进行显示地初始化(堆区)

8.      执行构造代码块:对对象进行构造代码块初始化:执行构造代码块(堆区)

9.      执行构造函数:对对象进行构造函数初始化。(堆区)

10.   将地址赋给对象:将内存地址赋给栈内存中的变量p

单例设计模式

单例模式:希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。

应用:一个系统只能有一个窗口管理器或文件系统;一个系统只能有一个计时工具或ID(序号)生成器。

注意点:如何保证一个类只有一个实例并且这个实例易于被访问呢?定义一个全局变量可以确保对象随时都可以被访问,但不能防止我们实例化多个对象。一个更好的解决办法是让类自身负责保存它的唯一实例。这个类可以保证没有其他实例被创建,并且它可以提供一个访问该实例的方法。

1.      饿汉模式

Single类一进内存就已经初始化了对象


1)      为了保证让类自己负责保存自己的实例,类中的变量都为private,并且构造函数也为private,不让外界创建;

2)      为了保证对象随时都可以被访问,以及其唯一性,因此将对象定义为static 并在内部自己创建

3)      为了能使外部得到该对象,我们暴露了获得对象的方法。

2.      懒汉模式


Single类进入内存,对象还未存在,只有当调用方法时才建立对象

 

模板类方法设计模式:

定义功能时,功能的一部分是确定的,而确定的部分在使用不确定的部分时,那么就需要将不确定的部分暴露出去,由子类去完成。即:去外面建立一个类,等子类去复写。

优点:降低了具体链接和程序的耦合性,提高了功能扩展性,提供了规则。


里面的final防止该函数被复写。

 

对象可访问状态:

状态

Public

Protected

Default

Private

同一包中

OK

OK

OK

NO

同一类中

OK

OK

OK

OK

子类间

OK

OK

OK

NO

不同包中

OK

OK

NO

NO

 

线程执行状态图:


死锁:

Eg:一人一支筷子,相互请求吃饭。

原因:同步中嵌套同步,锁却不同。

程序例子


这里的锁为了好区分,定义了MyLock对象。在完美情况下,t1拿到执行权在21行等待t2。这时t2获取执行权执行接下来的代码。如果运气差的话,t1拿到执行权,去等待锁b,而这时t2也刚刚建立,执行到32行等待锁a,于是两个就互相等,形成死锁。归结到底是执行权的问题;

多线程间通信

在对线程通信过程中,每个对象都要用到同一个资源库,而Synchrinizied则是为资源库上锁,防止一个资源在同一时间被多个用户使用。资源库需要自带标志,以表明自己此时是否被使用。而在唤醒线程之前需要循环查看此标志。

 

集合继承关系


集合容器并发访问错误:

不能对同一元素进行不同方式的操作:

Eg:Iterator  it = a1.iterator(); // 并发访问错误。

          a1.add(“java001”);

分析:既用了迭代器有用到了原对象,从而引发并发修改异常。

 

并发访问错误的原因:

Iterator 是工作在一个独立的线程中,并且拥有一个 mutex 锁。 Iterator 被创建之后会建立一个指向原来对象的单链索引表,当原来的对象数量发生变化时,这个索引表的内容不会同步改变,所以当索引指针往后移动的时候就找不到要迭代的对象,所以按照 fail-fast 原则 Iterator 会马上抛出 java.util.ConcurrentModificationException 异常。

在使用迭代器时,不能通过集合对象方法操作集合中的元素。可是iterator方法有限,只能对元素进行判断,取出,删除操作。若要想进行其他操作eg添加、修改。就需要使用其子接口:ListIterator;

 

 


 

这篇关于需要时常回顾的java基础知识的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1045723

相关文章

Java实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

Java中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满

Java判断多个时间段是否重合的方法小结

《Java判断多个时间段是否重合的方法小结》这篇文章主要为大家详细介绍了Java中判断多个时间段是否重合的方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录判断多个时间段是否有间隔判断时间段集合是否与某时间段重合判断多个时间段是否有间隔实体类内容public class D

IDEA编译报错“java: 常量字符串过长”的原因及解决方法

《IDEA编译报错“java:常量字符串过长”的原因及解决方法》今天在开发过程中,由于尝试将一个文件的Base64字符串设置为常量,结果导致IDEA编译的时候出现了如下报错java:常量字符串过长,... 目录一、问题描述二、问题原因2.1 理论角度2.2 源码角度三、解决方案解决方案①:StringBui

Java覆盖第三方jar包中的某一个类的实现方法

《Java覆盖第三方jar包中的某一个类的实现方法》在我们日常的开发中,经常需要使用第三方的jar包,有时候我们会发现第三方的jar包中的某一个类有问题,或者我们需要定制化修改其中的逻辑,那么应该如何... 目录一、需求描述二、示例描述三、操作步骤四、验证结果五、实现原理一、需求描述需求描述如下:需要在

Java中ArrayList和LinkedList有什么区别举例详解

《Java中ArrayList和LinkedList有什么区别举例详解》:本文主要介绍Java中ArrayList和LinkedList区别的相关资料,包括数据结构特性、核心操作性能、内存与GC影... 目录一、底层数据结构二、核心操作性能对比三、内存与 GC 影响四、扩容机制五、线程安全与并发方案六、工程

JavaScript中的reduce方法执行过程、使用场景及进阶用法

《JavaScript中的reduce方法执行过程、使用场景及进阶用法》:本文主要介绍JavaScript中的reduce方法执行过程、使用场景及进阶用法的相关资料,reduce是JavaScri... 目录1. 什么是reduce2. reduce语法2.1 语法2.2 参数说明3. reduce执行过程

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

Java调用DeepSeek API的最佳实践及详细代码示例

《Java调用DeepSeekAPI的最佳实践及详细代码示例》:本文主要介绍如何使用Java调用DeepSeekAPI,包括获取API密钥、添加HTTP客户端依赖、创建HTTP请求、处理响应、... 目录1. 获取API密钥2. 添加HTTP客户端依赖3. 创建HTTP请求4. 处理响应5. 错误处理6.

Spring AI集成DeepSeek的详细步骤

《SpringAI集成DeepSeek的详细步骤》DeepSeek作为一款卓越的国产AI模型,越来越多的公司考虑在自己的应用中集成,对于Java应用来说,我们可以借助SpringAI集成DeepSe... 目录DeepSeek 介绍Spring AI 是什么?1、环境准备2、构建项目2.1、pom依赖2.2