最全Java知识点总结归纳

news2024/9/21 21:51:45

一、流

Java所有的流类位于http://java.io包中,都分别继承字以下四种抽象流类型。

继承自InputStream/OutputStream的流都是用于向程序中输入/输出数据,且数据的单位都是字节(byte=8bit)。

继承自Reader/Writer的流都是用于向程序中输入/输出数据,且数据的单位都是字符(2byte=16bit)。

二、异常

Java的异常(包括Exception和Error)分为:

可查的异常(checked exceptions)

除了RuntimeException及其子类以外,其他的Exception类及其子类都属于可查异常。这种异常的特点是Java编译器会检查它,也就是说,当程序中可能出现这类异常,要么用try-catch语句捕获它,要么用throws子句声明抛出它,否则编译不会通过。

不可查的异常(unchecked exceptions)

包括运行时异常(RuntimeException与其子类)和错误(Error)。

运行时异常和非运行时异常:

RuntimeException

NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)等这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。运行时异常的特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕获它,也没有用throws子句声明抛出它,也会编译通过。

RuntimeException以外的Exception

从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常。

三、注解

Java SE5内置了三种标准注解:

 @Override,表示当前的方法定义将覆盖超类中的方法。

 @Deprecated,使用了注解为它的元素编译器将发出警告,因为注解@Deprecated是不赞成使用的代码,被弃用的代码。

 @SuppressWarnings,关闭不当编译器警告信息。

Java还提供了4中注解,专门负责新注解的创建:

@Target:

表示该注解可以用于什么地方,可能的ElementType参数有:

CONSTRUCTOR:构造器的声明

FIELD:域声明(包括enum实例)

LOCAL_VARIABLE:局部变量声明

METHOD:方法声明

PACKAGE:包声明

PARAMETER:参数声明

TYPE:类、接口(包括注解类型)或enum声明

@Retention

表示需要在什么级别保存该注解信息。可选的RetentionPolicy参数包括:

SOURCE:注解将被编译器丢弃

CLASS:注解在class文件中可用,但会被VM丢弃

RUNTIME:VM将在运行期间保留注解,因此可以通过反射机制读取注解的信息

@Document

将注解包含在Javadoc中

@Inherited

允许子类继承父类中的注解

Example

定义注解:

@Target(ElementType.METHOD)

@Retention(RetentionPolicy.RUNTIME)

public @interface UseCase {

    public String id();

    public String description() default "no description";

}

使用注解:

public class PasswordUtils {

     @UseCase(id = 47, description = "Passwords must contain at least one numeric")

     public boolean validatePassword(String password) {

         return (password.matches("\\w*\\d\\w*"));

     }

     @UseCase(id = 48)

     public String encryptPassword(String password) {

         return new StringBuilder(password).reverse().toString();

     }

 }

解析注解:

public static void main(String[] args) {

     List<Integer> useCases = new ArrayList<Integer>();

     Collections.addAll(useCases, 47, 48, 49, 50);

     trackUseCases(useCases, PasswordUtils.class);

 }

 public static void trackUseCases(List<Integer> useCases, Class<?> cl) {

     for (Method m : cl.getDeclaredMethods()) {

         UseCase uc = m.getAnnotation(UseCase.class);

         if (uc != null) {

             System.out.println("Found Use Case:" + uc.id() + " "

                         + uc.description());

             useCases.remove(new Integer(uc.id()));

         }

     }

     for (int i : useCases) {

         System.out.println("Warning: Missing use case-" + i);

     }

 }

 // Found Use Case:47 Passwords must contain at least one numeric

 // Found Use Case:48 no description

 // Warning: Missing use case-49

 // Warning: Missing use case-50

四、安全性

严格遵循面向对象的规范。这样封装了数据细节,只提供接口给用户。增加了数据级的安全性。

无指针运算。java中的操作,除了基本类型都是引用的操作。引用是不能进行增减运算,不能被直接赋予内存地址的,从而增加了内存级的安全性。

数组边界检查。这样就不会出现C/C++中的缓存溢出等安全漏洞。

强制类型转换。非同类型的对象之间不能进行转换,否则会抛出ClassCastException

语言对线程安全的支持。java从语言级支持线程。从而从语法和语言本身做了很多对线程的控制和支持。

垃圾回收。

Exception。

五、类加载

1. 原理

ClassLoader使用的是双亲委托模型来搜索类的,每个ClassLoader实例都有一个父类加载器的引用(不是继承的关系,是一个包含的关系),虚拟机内置的类加载器(Bootstrap ClassLoader)本身没有父类加载器,但可以用作其它ClassLoader实例的的父类加载器。

当一个ClassLoader实例需要加载某个类时,它会试图亲自搜索某个类之前,先把这个任务委托给它的父类加载器,这个过程是由上至下依次检查的,首先由最顶层的类加载器Bootstrap ClassLoader试图加载,如果没加载到,则把任务转交给Extension ClassLoader试图加载,如果也没加载到,则转交给App ClassLoader 进行加载,如果它也没有加载得到的话,则返回给委托的发起者,由它到指定的文件系统或网络等URL中加载该类。

如果它们都没有加载到这个类时,则抛出ClassNotFoundException异常。否则将这个找到的类生成一个类的定义,并将它加载到内存当中,最后返回这个类在内存中的Class实例对象。

JVM在判定两个class是否相同时,不仅要判断两个类名是否相同,而且要判断是否由同一个类加载器实例加载的。只有两者同时满足的情况下,JVM才认为这两个class是相同的。

2. 加载器

BootStrap ClassLoader

启动类加载器,是Java类加载层次中最顶层的类加载器,负责加载JDK中的核心类库,如:rt.jar、resources.jar、charsets.jar等。

   URL[] urls = sun.misc.Launcher.getBootstrapClassPath().getURLs();

   for (int i = 0; i < urls.length; i++) {

       System.out.println(urls[i].toExternalForm()); 

   }

   // 也可以通过sun.boot.class.path获取

   System.out.println(System.getProperty("sun.boot.class.path"))

Extension ClassLoader

扩展类加载器,负责加载Java的扩展类库,默认加载JAVA_HOME/jre/lib/ext/目下的所有jar。

App ClassLoader

系统类加载器,负责加载应用程序classpath目录下的所有jar和class文件

注意:

除了Java默认提供的三个ClassLoader之外,用户还可以根据需要定义自已的ClassLoader,而这些自定义的ClassLoader都必须继承自java.lang.ClassLoader类,也包括Java提供的另外二个ClassLoader(Extension ClassLoader和App ClassLoader)在内。Bootstrap ClassLoader不继承自ClassLoader,因为它不是一个普通的Java类,底层由C++编写,已嵌入到了JVM内核当中,当JVM启动后,Bootstrap ClassLoader也随着启动,负责加载完核心类库后,并构造Extension ClassLoader和App ClassLoader类加载器。

1

六、关键字

strictfp(strict float point)

strictfp 关键字可应用于类、接口或方法。使用strictfp关键字声明一个方法时,该方法中所有的float和double表达式都严格遵守FP-strict的限制,符合IEEE-754规范。当对一个类或接口使用strictfp关键字时,该类中的所有代码,包括嵌套类型中的初始设定值和代码,都将严格地进行计算。严格约束意味着所有表达式的结果都必须是 IEEE 754算法对操作数预期的结果,以单精度和双精度格式表示。

如果你想让你的浮点运算更加精确,而且不会因为不同的硬件平台所执行的结果不一致的话,可以用关键字strictfp。

transiant

变量修饰符,如果用transient声明一个实例变量,当对象存储时,它的值不需要维持。

volatile

作为指令关键字,确保本条指令不会因编译器的优化而省略,修饰变量,保证变量每次都是从内存中重新读取。

final

修饰基础数据成员(as const)

修饰类或对象的引用

修饰方法的final(cannot overwrite)

修饰类或者参数

七、初始化

父静态->子静态

父变量->父初始化区->父构造

子变量->子初始化区->子构造

八、多线程

JAVA多线程实现方式主要有三种:继承Thread类、实现Runnable接口、使用ExecutorService、Callable、Future实现有返回结果的多线程。其中前两种方式线程执行完后都没有返回值,只有最后一种是带返回值的。

1. 线程池

concurrent下的线程池:

newSingleThreadExecutorExecutors

创建一个单线程的线程池。这个线程池只有一个线程在工作,也就是相当于单线程串行执行所有任务。如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。

newFixedThreadPool

创建固定大小的线程池。每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。

newCachedThreadPool

创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程,那么就会回收部分空闲(60秒不执行任务)的线程,当任务数增加时,此线程池又可以智能的添加新线程来处理任务。此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。

newScheduledThreadPool

创建一个大小无限的线程池。此线程池支持定时以及周期性执行任务的需求。

2. 线程安全

线程安全是一个很大的问题,Java 最常见的 HttpServlet 就是单实例多线程,解决这样的问题,有多种方式:

ThreadLocal

ThreadLocal 看下一节的内存图就很好理解,每个线程都有自己的工作内存,ThreadLocal 就是将变量存到线程自己的工作内存中,所以不会有并发问题。

Synchronized

synchronized锁住的是括号里的对象,而不是代码。对于非 static 的 synchronized 方法,锁的就是对象本身也就是 this。该关键字可以加到:

实例方法

静态方法

实例方法中的同步块

静态方法中的同步块

ReentrantLock / Condition

synchronized 不够灵活,例如读写文件,读和读之间不应该互斥,这个时候就可以使用 ReentrantLock 增加并发能力。Condition 是绑定到 Lock 上的,可以用于线程间通信,例如这个面试题,就可以使用 Condition 唤起线程写自己的name 。

有四个线程1、2、3、4。线程1的功能就是输出1,线程2的功能就是输出2,以此类推…现在有四个文件ABCD。初始都为空。现要让四个文件呈如下格式:A:1 2 3 4 1 2… B:2 3 4 1 2 3… C:3 4 1 2 3 4… D:4 1 2 3 4 1…

并发容器

常见的 ConcurrentHashMap CopyOnWriteArrayList 用于多线程下存放数据,Queue BlockingQueue 用于排队消费。

Atomic 包在 Atomic 包里一共有 12 个类,四种原子更新方式,分别是原子更新基本类型,原子更新数组,原子更新引用和原子更新字段。某些并发问题,需要无锁解决时,就可以考虑使用原子方法。

九、内存模型

Java内存模型规定,对于多个线程共享的变量,存储在主内存当中,每个线程都有自己独立的工作内存,线程只能访问自己的工作内存,不可以访问其它线程的 工作内存。工作内存中保存了主内存共享变量的副本,线程要操作这些共享变量,只能通过操作工作内存中的副本来实现,操作完毕之后再同步回到主内存当中。

如何保证多个线程操作主内存的数据完整性是一个难题,Java内存模型也规定了工作内存与主内存之间交互的协议,首先是定义了8种原子操作:

lock:将主内存中的变量锁定,为一个线程所独占

unclock:将lock加的锁定解除,此时其它的线程可以有机会访问此变量

read:将主内存中的变量值读到工作内存当中

load:将read读取的值保存到工作内存中的变量副本中。

use:将值传递给线程的代码执行引擎

assign:将执行引擎处理返回的值重新赋值给变量副本

store:将变量副本的值存储到主内存中。

write:将store存储的值写入到主内存的共享变量当中。

内存组成

堆(Heap)

运行时数据区域,所有类实例和数组的内存均从此处分配。Java虚拟机启动时创建。对象的堆内存由称为垃圾回收器 的自动内存管理系统回收。

News Generation(Young Generation即图中的Eden + From Space + To Space)

Eden 存放新生的对象

Survivor Space 两个 存放每次垃圾回收后存活的对象

Old Generation(Tenured Generation 即图中的Old Space) 主要存放应用程序中生命周期长的存活对象

非堆内存

JVM具有一个由所有线程共享的方法区。方法区属于非堆内存。它存储每个类结构,如运行时常数池、字段和方法数据,以及方法和构造方法的代码。它是在Java虚拟机启动时创建的。除了方法区外,Java虚拟机实现可能需要用于内部处理或优化的内存,这种内存也是非堆内存。例如,JIT编译器需要内存来存储从Java虚拟机代码转换而来的本机代码,从而获得高性能。

Permanent Generation (图中的Permanent Space)存放JVM自己的反射对象,比如类对象和方法对象

native heap

十、写到最后

如果觉得本文对你有帮助的话,请你也不要吝啬你的赞,你们的支持是对我最大的鼓励。今天的Java知识分享就到这里!点关注,不迷路,关注程序员曾曾,每天分享不同的Java基础知识,想要知道更多Java基础知识的我这边整理了一个我自己的GitHub仓库:Java小白修炼手册,大家如果有需要可以自行查看

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/69579.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

黄佳《零基础学机器学习》chap3笔记

黄佳 《零基础学机器学习》 chap3笔记 第3课 线性回归——预测网店的销售额 文章目录黄佳 《零基础学机器学习》 chap3笔记第3课 线性回归——预测网店的销售额3.1 问题定义&#xff1a;小冰的网店广告该如何投放3.2 数据的收集和预处理3.2.1 收集网店销售额数据3.2.2 数据读取…

功能测试(五)—— web项目抓包操作与测试报告

目录 目标 一、网络相关知识介绍 1.1 请求 1.2 响应 二、抓包工具的应用 2.1 过滤 2.2 删除数据 2.3 查看数据包内容 2.4 定位Bug 2.5 弱网测试 2.6 设置断点&#xff08;请求之前&#xff09; 2.7 设置断点&#xff08;响应之后&#xff09; 三、测试报告 目标 …

Java 多线程ThreadLocal使用

前面文章多线程间的同步控制和通信&#xff0c;是为了保证多个线程对共享数据争用时的正确性的。那如果一个操作本身不涉及对共享数据的使用&#xff0c;相反&#xff0c;只是希望变量只能由创建它的线程使用&#xff08;即线程隔离&#xff09;就需要到线程本地存储了。 Java…

Spring学习:三、Spring IoC 容器配置-注解方式

5. Spring IoC 容器配置-注解方式 5.1 注解定义Bean对象 在Bean class 添加 注解 Spring2.5 提供 Component 效果相当于 <bean> 元素 配置包扫描&#xff0c;通知spring 注解Bean 在哪个包下面 使用 <context> 命名空间 ,在spring的配置文件中添加context命令空…

【图】认识与表达

文章目录一、图的基本构成二、图的表达方式1&#xff09;邻接矩阵2&#xff09;邻接表3&#xff09;数组4&#xff09;综合一、图的基本构成 地图上有很多的建筑&#xff0c;每个建筑之间有着四通八达的道路连接着&#xff0c;如果想要使用数据结构来表示建筑和建筑之间的道路…

知识图谱-KGE-语义匹配-双线性模型-2019:CrossE

【paper】 Interaction Embeddings for Prediction and Explanation in Knowledge Graphs【简介】 本文是浙大和苏黎世大学的学者联合发表于 WSDM 2019 上的工作&#xff0c;文章提出了 CrossE&#xff0c;模型的思想也没有很高端&#xff0c;就是引入了一个矩阵C&#xff0c;用…

List——顺序表链表OJ

文章目录前言一、合并两个有序链表二、使用顺序表实现“杨辉三角”三、环形链表四、环形链表Ⅱ总结前言 上两篇内容&#xff0c;对链表和顺序表进行了讲解并手动实现了自己的顺序表和链表&#xff0c;本篇文章将结合LeetCode上的OJ题&#xff0c;进行具体的使用以熟悉其中的方…

Spring注解式缓存redis

一、Spring 整合redis 导入依赖 <redis.version>2.9.0</redis.version> <redis.spring.version>1.7.1.RELEASE</redis.spring.version><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId>&l…

Qt中操作SQLite数据库

0.前言 SQLite是一款开源、轻量级、跨平台的数据库&#xff0c;无需server&#xff0c;无需安装和管理配置。它的设计目标是嵌入式的&#xff0c;所以很适合小型应用&#xff0c;也是Qt应用开发种常用的一种数据库。 1.驱动 Qt SQL模块使用驱动程序插件&#xff08;plugins&am…

多线程与高并发(一)

【前言】&#xff1a; 多线程、JVM、操作系统。 【概述】&#xff1a; 基础概念 JUC同步工具 同步容器 Disruptor //一个MQ框架&#xff0c;公认的单机环境下效率最高。 线程池 【线程的概念】&#xff1a; 【纤程】&#xff1a; 【 run和start的区别 】&#xff1a; //n…

[附源码]Python计算机毕业设计SSM家用饰品在线销售系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【面试问题】进程和线程的区别——通俗易懂

1. ”进程“是什么1.2 管理进程1.3 内存管理1.4 进程间通信2. 线程是什么3.进程和线程的区别1. ”进程“是什么 在对比"进程"和"线程"两者之间的区别前,我们需要先了解什么是"进程"?什么是"线程"? **“进程”(process)也叫"任…

HIFI测序揭示拟南芥MSH1参与介导的细胞器基因组重组与变异积累规律

近日&#xff0c;中国农业科学院农业基因组所武志强课题组在《The Plant Journal》在线发表了题为“Long-read sequencing characterizes mitochondrial and plastid genome variants in Arabidopsis msh1 mutants”的研究论文&#xff0c;该研究通过高精度的长读长测序&#x…

安卓APP源码和设计报告——仿淘宝水果商城

项目名称 仿淘宝水果商城项目概述 随着互联网技术地高速发展&#xff0c;计算机进入到每一个人的生活里&#xff0c;从人们的生活方式到整个社会的运转都产生了巨大的变革&#xff0c;而在信息技术发达的今天&#xff0c;互联网的各种娱乐方式都在渗透到人们的生活方式之中&…

Procreate绘画教程

Procreate绘画教程 从 30 多年的设计师/插画家那里彻底有效地学习 Procreate&#xff01;已更新至 Procreate 5.2&#xff01; 课程英文名&#xff1a;Procreate Solid Foundations 此视频教程共10.0小时&#xff0c;中英双语字幕&#xff0c;画质清晰无水印&#xff0c;源码…

三条建议!让您在世界杯期间确保网络安全!

2022年11月&#xff0c;全球的目光都聚焦在依旧“夏日炎炎”的卡塔尔。随着人们观看、分享赛事的习惯从传统的电视转为网络&#xff0c;世界杯必将成为整个2022年的“流量王”。在我国&#xff0c;仅仅德国与日本的一场比赛在微博平台就带来了13.8亿次阅读。 据估计&#xff0…

细粒度图像分类论文研读-2020

文章目录Filtration and Distillation: Enhancing RegionAttention for Fine-Grained Visual Categorization(by localization- classification subnetwork)AbstractIntroductionApproachDiscriminative Regions ProposingFeature Learning and Recognition EnsembleFiltration…

Spring源码深度解析:十一、Spring的循环依赖

一、前言 文章目录&#xff1a;Spring源码深度解析&#xff1a;文章目录 这篇文章是接着 Spring源码深度解析&#xff1a;七、bean的加载① - doGetBean 的继续分析过程。 二、什么是循环依赖 循环依赖&#xff0c;其实就是循环引用&#xff0c;就是两个或者两个以上的 bea…

【MySQL】数据处理函数

只有当你开始相信自己时&#xff0c;你才拥有真正的人生。——《洛奇》 前言&#xff1a; 大家好&#xff0c;我是爱打拳的程序猿。今天给大家展示是数据处理函数的用法&#xff0c;分为单行处理函数和分组函数。数据处理函数主要是为了更方便解决数据的各种问题。文章以代码和…

2023年Unity UI教程

2023年Unity UI教程 Unity 新 UI 系统 UI 工具包的完整概述 课程英文名&#xff1a;Modern Unity UI with UI Toolkit 此视频教程共10.0小时&#xff0c;中英双语字幕&#xff0c;画质清晰无水印&#xff0c;源码附件全 下载地址 课程编号&#xff1a;336 百度网盘地址&am…