
Java基本功
文章平均质量分 66
Java基本功
诗人不写诗
当你足够努力时,全世界都会给你让路
展开
-
Java类加载器和ClassLoader#getResource()和Class#getResource()和classpath
Java是具备解释特性的语言,拥有虚拟机,所以类加载是Java根本任务之一,类加载器从Java 1.0开始就出现了,类加载器将编译得到的class文件相关信息作为java.lang.Class的一个实例记录起来,这样就可以获取到类型的相关信息了,反射的实现也成为可能了。原创 2018-07-20 23:24:59 · 878 阅读 · 0 评论 -
Java操作文件|getResource
与操作文件相关的通常关系到Class#getResource()和ClassLoader#getResource()和ClassLoader#getResources()三个方法,这里我们先把这个作个了解,首先我们需要知道Class#getResource()是通过ClassLoader#getResource()实现的,但是做了预处理:如果入参路径以/开头,如/icon/sample.gif,从...原创 2018-11-06 23:19:31 · 778 阅读 · 0 评论 -
为什么ClassLoader里会有getResources方法
实际上,`ClassLoader` 的 `getResource` 方法和类信息的保存没有直接关系。`getResource` 方法的主要目的是定位和获取资源文件,而非类文件。资源文件可以是配置文件、图片、音频或其他任何非代码文件。`getResource` 方法能够定位资源是因为它会根据给定的资源名称在类路径(Classpath)中进行搜索。类路径是指定了类和资源存放位置的一个环境变量或配置选项,它可以包括文件系统的目录、JAR文件等。原创 2024-07-31 17:35:36 · 520 阅读 · 0 评论 -
JAVA类加载器
JAVA是一种解释型语言,也就是一种边解释边执行的语言。JAVA所有源代码在执行之前,先要被编译成class文件,然后类加载器加载解析class文件,最后才执行。JVM自带了几个类型的类加载器,JVM使用分层的软件架构方式设计类加载器,同时使用了双亲委派约束加载行为。需要注意的是,JAVA 9 开始,原来的Extension class loader已经被取消,替换成了Platform class loader。 我们用代码来看看实际加载的类加载器,在JAVA环境中,由于bootstrap class l原创 2022-11-27 16:06:24 · 619 阅读 · 0 评论 -
3 Java Object中hashCode()方法和equals()方法重写问题
hashCode()和equals()方法定义在Object类中,所以Java中所有对象都有这2个方法。public native int hashCode();public boolean equals(Object obj) { return (this == obj);}hashCode()方法返回的是一个对象的散列值,并不是唯一标识一个对象的ID,不同对象的hash...原创 2020-05-02 14:19:42 · 513 阅读 · 0 评论 -
有人在Java代码中大量使用this关键字?
写代码的关键要求就是简洁,多余的代码不要写,必要的代码不能少写。this关键字的使用就涉及到代码简洁性问题。在c/c++和Java中都有this关键字,用于在类型定义文件中表示运行时的某个实例,在Java中,this关键字通常有以下几个用途。原创 2022-08-24 22:53:15 · 566 阅读 · 0 评论 -
Java类和线程的关系理解
这种理解,如果代码写得多,思考得多,就会有自己的一套理解方式,而正确的理解往往都是相同的,不对的理解千奇百怪。在Java中,线程以类的形式展现给编程人员,所以编程人员可以通过类来创建线程,而线程执行又需要有类的方法作为执行代码,两者相互联系又相互独立。实际上线程是操作系统层次提供的能力,任何编程语言都是封装和使用操作系统提供的这种能力,Java也不例外,Java中,一切都是对象,线程也是以...原创 2018-07-04 18:05:09 · 4778 阅读 · 4 评论 -
String的intern()函数|JVM运行时数据区
这里会涉及到几个概念,先提出来:1、JVM规范认为Java虚拟机一般包含五个部分:堆、虚拟机栈、本地方法栈、程序计数器、方法区。运行时常量池是方法区的一部分。2、HotSpot中对方法区的实现称为永久代,分清楚规范和实现之间的概念差异。3、不同虚拟机版本实现有变化,Java7中存在永久代,但是永久代中运行时常量池已经迁出到堆中,Java8中已经没有永久代,新增Metaspace元空间,...原创 2018-07-28 15:37:03 · 223 阅读 · 0 评论 -
转义字符和正则
我们在写代码时,使用的是字符来表达,这些字符是编程语言定义的关键字或保留字,他们可以是单词或者单个字符。一段Java代码如下: public FileInputStream(File file) throws FileNotFoundException { String name = (file != null ? file.getPath() : null); SecurityManager security = System.getSecurityManage原创 2022-05-22 11:36:41 · 287 阅读 · 0 评论 -
Java序列化,何时需要实现Serializable?
Java中有一个接口是java.io.Serializable,实现这个接口,不用实现任何方法,这个接口就是一个标识作用,jvm在做某些操作的时候,会去检查目标类有没有实现java.io.Serializable接口,没有实现的话,根据情况抛出异常。这里我们需要明确的是那些操作会去检查是否实现java.io.Serializable接口,一般而言,在将对象转换成流时,会去检查。比如转换成流进行网络传输,转换成流持久化到磁盘。实际应用时,比如我们服务对外提供的接口时,返回的DTO对象需要实现java.原创 2022-05-15 18:46:52 · 1861 阅读 · 0 评论 -
java final关键字使用和原理
在使用内部类的时候,内部类有时会访问到外部类的变量,这时,如果被访问的外部变量如果不是final修饰的,就会报错。原因是因为内部内在引用外部类的变量时,是进行拷贝的,所以不是同一个引用了,内部类中的修改对外不可见,外部修改对内部类也不可见,这是不符合常规编程约定的,所以使用final修饰,直接规避了修改这个途径,杜绝了这个变量不同步的可能性。 但是其他语言的闭包却没有这个特性,其他语言没...原创 2018-09-04 23:14:13 · 307 阅读 · 0 评论 -
Java中环形依赖
1、成员变量初始化时环形依赖Java会将所有初始化动作集中到<init>()方法中,第一步是调用父类的<init>(),然后是初始化成员变量,最后是调用构造方法的初始化逻辑。这里很明显造成了<init>()的死循环,在执行A.<init>()时,里面有一个B需要初始化,然后去执行B.<init>,发现B中有A,然后去执行A.<init>,然后发现B需要初始化......,就这样形成了死循环。这不是语言的设计缺陷,而是代码的设计缺陷,原创 2021-07-17 18:51:11 · 359 阅读 · 0 评论 -
Java成员变量初始化和构造函数顺序
1、Java虚拟机会将所有的初始化动作手机到<init>()方法中,在分配内存后,就开始调用<init>()方法,其中,成员变量的初始化在构造函数里的初始化动作之前。public class Test { private String s = "1"; public Test() { s = "2"; } public static void main(String[] args) { Test t = ne原创 2021-07-17 17:31:08 · 2282 阅读 · 0 评论 -
1-Java的诞生和发展
一、Java由Sun公司发明,先来看看Sun公司1982年2月24日,安迪和维诺德·科斯拉(Vinod Khosla)、斯科特·麦克尼利(Scott McNearly)创建了Sun公司。不久之后比尔·乔伊(Bill Joy),一个伯克利大学的学生也很快作为创始人加盟了。比尔是著名的BSD系统的主要开发者,促成了Sun公司的操作系统Solaris的诞生。Sun公司最初的产品是一个Unix工作站 Sun-1。它是Sun公司的联合创始人安迪·贝克托斯海姆(Andy Bechtolsheim)在研究生时期给斯原创 2021-01-01 18:50:54 · 3204 阅读 · 0 评论 -
5 Java内部类|静态内部类|访问权限控制
Java是一门纯粹的面向对象编程语言,一般而言,一个类型就是一个java文件,如果将一个类型定义到另一个类型里面,那么两个类型就只有一个Java文件(仅限源代码,编译过后还是一个类型对应一个class文件)。使用内部类的很大一部分原因就是为了满足面向对象编程+封装思想,有时一个类型中还可以更细粒度的进行封装,这时如果我们将整个能力封装为一个独立的类型,是有过度封装的嫌疑的,那么将这个能力以类型的方...原创 2018-08-07 18:44:21 · 2048 阅读 · 0 评论 -
java泛型编程
1、关于泛型编程有一个核心需要记住:类型参数化,也即类型是一种可变的参数。2、泛型有三种使用方式:泛型类、泛型接口、泛型方法。3、原创 2020-03-27 09:17:13 · 805 阅读 · 0 评论 -
2 Java Lambda表达式写法和应用
Java中lambda表达式的基本语法包含三个部分:1、参数2、->3、功能体[1] 当只用一个参数,可以不需要括号 ()。 然而,这是一个特例。[2] 正常情况使用括号 () 包裹多个参数。 为了保持一致性,也可以使用括号 () 包裹单个参数,虽然这种情况并不常见。[3] 如果没有参数,则必须使用括号 () 表示空参数列表。[4]如果功能体是单行,表达式结果自动成为Lambd...原创 2019-11-14 22:56:03 · 656 阅读 · 0 评论 -
1 Java函数式编程
首先我们需要了解函数式接口,函数式接口就是只有一个抽象方法的接口,在Java中,接口中的方法都隐式添加了public abstract关键字,所以所有方法都是抽象的,我们可以使用@FunctionalInterface注解来规范函数式接口的定义,如果你在接口中再添加一个方法,那么编译器会报错,这就是@FunctionalInterface的作用。@FunctionalInterfacepu...原创 2019-02-22 11:06:03 · 175 阅读 · 0 评论 -
4 Java HashMap原理
jdk7和jdk8的实现是不一样的,jdk7采用数组+链表实现,jdk8采用数组+链表+红黑树实现。HashMap线程不安全,有线程安全需求的要用ConcurrentHashMap替代。HashMap允许key为null,不允许key重复。jdk1.7版主要成员变量static final int DEFAULT_INITIAL_CAPACITY = 1 << 4...原创 2020-05-02 20:19:44 · 264 阅读 · 0 评论 -
Java 强引用、软引用、弱引用、虚引用
下面我们先来了解下引用的分类,然后再去探究使用的场景。使用方式多了一层,但是也好理解,软引用引用力度仅次于强引用的一种引用,只有在虚拟机认为内存不够时,软引用的引用即使还在生命周期内,软引用指向的堆空间依然被强行回收,这时调用get()返回的就是null,所以正常情况下,软引用的表现和强引用无异,只有在虚拟机认为内存吃紧的时候,软引用才会体现出他的特性。形如上述的引用就是强引用了,只要引用还在有效生命周期内,GC就无法将引用对应的堆上的空间回收,当然引用本身也是无法回收的,强引用的使用和规则是不言而喻的。原创 2018-07-22 21:57:26 · 403 阅读 · 0 评论 -
ThreadLocal使用|内存泄漏
先来分析下类的聚合关系,每个Thread类中有一个ThreadLocalMap类,ThreadLocalMap维护着一个<ThreadLocal<?>, Object>类型的数组,你每次调用ThreadLocal的set()方法时,是将数据存入Thread的ThreadLocalMap中,每次调用ThreadLocal的get()方法,是从Thread的ThreadLoca...原创 2018-07-22 18:39:52 · 1776 阅读 · 0 评论