![](https://img-blog.csdnimg.cn/20201014180756922.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
Java
文章平均质量分 69
Java
CODER-V
全栈干货博主
展开
-
【最佳实践之性能篇】编码惯例与作用域意识
尊重对象所有权就意味着不要修改不属于你的对象。简单来说就是,如果你不负责创建和维护某个对象及其构造函数或方法,就不应该对其进行任何修改。具体来说就是遵循以下惯例:- 不要给实例或原型添加属性- 不要给实例或原型添加方法- 不要重定义已有的方法问题在于,假如有一个stopEvent()的方法用于取消某个事件的默认行为,你将其修改了,除了取消事件的默认行为还添加了其他行为,别人对于你添加的副作用并不知情,也使用了这个方法,就会导致别人出现错误或损失。原创 2023-03-14 20:42:14 · 188 阅读 · 0 评论 -
【Java代码与架构之完美优化】篇1:代码质量优化通用准则
long类型的变量定义,都需要在后边跟上小写l或大写L,而小写l与数字1十分形似,难以分辨,者大大降低了程序的可读性,因而在定义long类型变量的时候,统一使用大写的L来标识变量。原创 2023-03-08 19:49:49 · 494 阅读 · 0 评论 -
【JDK 17 新特性】jdk8~jdk17新特性
局部变量的显示类型声明,常常被认为是不必须的,因而JDK10允许开发人员省略通常不必要的局部变量类型声明,以增强Java语言的体验性、可读性,使用对变量进行。有了该功能,可以减少Java程序中显式强制转换的数量,实现更精确、简洁的类型安全的代码。直接在 switch 上支持 Object 类型,这就等于同时支持多种类型,使用模式匹配得到具体类型,大大简化了语法量,这个功能很实用。JDK13中引入了yield关键字,用于返回值并结束循环,而break只能结束switch循环,不能有返回值。原创 2023-03-08 15:29:29 · 999 阅读 · 0 评论 -
【JDK15 新特性】密封类
在 Java 中如果想让一个类不能被继承和修改,这时我们应该使用 final 关键字对类进行修饰。不过这种要么可以继承,要么不能继承的机制不够灵活,有些时候我们可能想让某个类可以被某些类型继承,但是又不能随意继承,是做不到的。Java 15 尝试解决这个问题,引入了 sealed 类,被 sealed 修饰的类可以指定子类。这样这个类就只能被指定的类继承。通过密封的类和接口来限制超类的使用,密封的类和接口限制其它可能继承或实现它们的其它类或接口。原创 2023-03-08 15:30:36 · 215 阅读 · 0 评论 -
【JDK14 新特性】Record
record的设计目标是提供一种将数据建模为数据的好方法。它也不是 JavaBeans 的直接替代品,因为record的方法不符合 JavaBeans 的 get 标准。另外 JavaBeans 通常是可变的,而记录是不可变的。尽管它们的用途有点像,但记录并不会以某种方式取代 JavaBean。原创 2023-03-08 15:17:39 · 660 阅读 · 0 评论 -
【JDK1.8 新特性】Stream API
① Stream 自己不会存储元素。② Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream。③ Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。即一旦执行终止操作,就执行中间操作链,并产生结果。④ Stream一旦执行了终止操作,就不能再调用其它中间操作或终止操作了。原创 2023-03-08 11:35:55 · 327 阅读 · 0 评论 -
【JDK1.8 新特性】方法引用,构造器引用
针对情况1:函数式接口中的抽象方法a在被重写时使用了某一个对象的方法b。如果方法a的形参列表、返回值类型与方法b的形参列表、返回值类型都相同,则我们可以使用方法b实现对方法a的重写、替换。注意: 此方法是实例方法,需要对象调用!针对情况2:函数式接口中的抽象方法a在被重写时使用了某一个类的静态方法b。如果方法a的形参列表、返回值类型与方法b的形参列表、返回值类型都相同,则我们可以使用方法b实现对方法a的重写、替换。注意: 此方法是静态方法,需要类调用!针对情况3:函数式接口中的抽象方法a在被重写原创 2023-03-07 17:55:21 · 419 阅读 · 0 评论 -
【JDK1.8 新特性】Lambda表达式
只包含一个抽象方法(Single Abstract Method,简称SAM)的接口,称为函数式接口。当然该接口可以包含其他非抽象方法。你可以通过 Lambda 表达式来创建该接口的对象。(若 Lambda 表达式抛出一个受检异常(即:非运行时异常),那么该异常需要在目标接口的抽象方法上进行声明)。我们可以在一个接口上使用 @FunctionalInterface 注解,这样做可以检查它是否是一个函数式接口。同时 javadoc 也会包含一条声明,说明这个接口是一个函数式接口。在java.util.f原创 2023-03-07 11:28:39 · 349 阅读 · 0 评论 -
【Java】类的加载过程
过程1:类的装载(Loading)将类的class文件读入内存,并为之创建一个java.lang.Class的实例对象,此过程由类加载器完成。 过程2:链接(Linking)1. 验证(Verify):确保加载的类的信息符合JVM规范,例如:每一个class文件都以cafebabe开头,没有安全方面的问题。2. 准备(Prepare):正式为类中的(static)静态变量分配内存,并设置默认初始化值的阶段。这些内存都在方法区中进行分配。3. 解析(Resolve):虚拟机常量池内得符原创 2023-03-06 16:38:48 · 542 阅读 · 0 评论 -
【Java】序列化与反序列化
自定义类需要实现接口:Serializable(标识接口:无任何属性或抽象方法),否则会报NotSerializableException 异常要求自定义类声明一个全局常量:static long serialVersionUID = 42234234L;该常量必须是:static long 类型的,对权限修饰符没有要求该常量用于唯一标识该类,所以每个类的常量值都一样保持不一致要求自定义类的各个属性也必须是可以序列化的:对于基本数据类型:默认就可以序列化,因为底层已经实现类了Serializabl原创 2023-03-06 11:27:40 · 307 阅读 · 0 评论 -
【Java集合框架】篇六:Collections工具类
Collections 中提供了一系列静态的方法对集合元素进行排序、查询和修改等操作,还提供了对集合对象设置不可变、对集合对象实现同步控制等方法(均为static方法):原创 2023-03-03 20:52:49 · 623 阅读 · 0 评论 -
【Java集合框架】篇五:HashMap、LinkedHashMap源码解析
jdk8中,我们调用空参构造器,创建实例时,底层没用立即初始化数组容量,在我们第一次put元素时,才初始化一个容量为16的数组table,并将元素添加到table(类似懒汉式)jdk8中,将内部类Entry改名为Node(名称合理化),意味着我们创建的数组式Node[],不再是Entry[]。jdk8中,key1和key2的哈希值和内容不同,则(key1,value1)与(key2,value3)构成单向链表,(key2,value2)指向(key1,value1)(尾插法)。因为头插法在多线程的情况下原创 2023-03-03 20:48:23 · 823 阅读 · 0 评论 -
【Java集合框架】篇四:HashSet、LinkedHashSet源码解析
无序性:Set底层存储元素不是从前往后依次存储的,而是通过元素的哈希值,计算元素的存储位置并保存,而遍历操作都是从前往后依次遍历的,进而导致遍历出来的数据和添加的数据的顺序不一致,体现为无序性!不可重复性:添加到Set中的元素不能相同,底层会通过元素的hashCode()和equals()进行判断,若二者都相同,则该元素一存在,不会重复添加原创 2023-03-03 17:18:30 · 519 阅读 · 0 评论 -
【Java集合框架】篇三:ArrayList、LinkedList源码解析
List:有序、可重复(“动态”数组);因而常常使用List替换数组,因为List 的容量是动态的。ArrayList:底层使用Object[]存储线程不安全,追加(尾部添加)、查找效率高。时间复杂度O(1)。删除、插入效率低。时间复杂度O(n)。默认容量10,自动扩容1.5倍。使用该类时,若数组容量确定尽量使用new ArrayList(int capacity)构造器,避免扩容操作。原创 2023-03-03 16:32:26 · 558 阅读 · 0 评论 -
【Java】迭代器(Iterator)与增强for循环(forEach)
针对于集合来讲,forEach底层任然使用的时迭代器forEach执行过程:将集合或数组中的元素依次取出来赋值给临时变量。注意:循环体中对临时变量的修改,可能不会导致原有集合或数组中元素的修改。原创 2023-03-03 11:31:24 · 490 阅读 · 0 评论 -
【Java集合框架】篇二:Collection接口方法
JDK不提供此接口的任何直接实现类,而是提供更具体的子接口(如:Set和List)去实现。Collection 接口是 List和Set接口的父接口,该接口里定义的方法既可用于操作 Set 集合,也可用于操作 List 集合。原创 2023-03-03 11:12:15 · 483 阅读 · 0 评论 -
【Java集合框架】篇一:概述
1. 数组一旦初始化,器长度就不可变了;集合长度可变2. 数组中存储数据类型单一性、有序性、可重复性,对于无序的、不可重复的场景就无能为力了;集合不会,需要通过泛型限制元素类型3. 数组中可用的方法、属性很少(尽管继承Object类),具体的需求还要自己声明逻辑代码4. 对于数组元素的删除、插入操作,性能较差原创 2023-03-03 10:04:38 · 90 阅读 · 0 评论 -
一文彻底搞懂cookie、session、token、jwt!
角度一:是否有状态Cookie、Storage、Session 是有状态的,都用于存储用户信息。Token、JWT 是无状态的,用于户身份验证的,不存储用户信息,实际上Token还是有状态的,因为需要在服务器保存一些属性用于验证Token,JWT真正做到了无状态。角度二:存储位置Cookie、Storage是浏览器存储数据方案Session是服务器存储数据方案角度三:创建者Cookie、Sessin、Token、JWT都是由服务器生成角度四:传输方式通过HTTP请求头或请求参数传输原创 2023-03-02 17:16:11 · 1123 阅读 · 0 评论 -
【Java】重写equals方法
1. 判断实参对象和当前对象地址释放相同,若相同则是同一个对象2. 判断实参对象是否,当前对象所在类,或子类,3. 若是则强转,声明比较规则4. 比较属性是否相同原创 2023-03-02 09:27:01 · 176 阅读 · 0 评论 -
【Java】比较器(对象比较大小)
在Java中经常会涉及到对象数组的排序问题,那么就涉及到对象之间的比较问题。 Java实现对象排序的方式有两种: 自然排序:java.lang.Comparable定制排序:java.util.Comparator规则:需要我们自定义根据对象的某个或某些属性进行排序原创 2023-03-02 09:14:44 · 1020 阅读 · 0 评论 -
【Java】StringBuffer、StringBuilder
当我们new StringBuilder()调用无参构造器时,底层创建了一个默认长度为16的数组。一旦append超出了容量,就会扩容为原来的 2倍+2。新建一个容量为原来 2倍+2 的数组,并将原数组元素赋值过来。原创 2023-03-01 16:57:00 · 357 阅读 · 0 评论 -
【Java】String类
`private final byte[] value;`,为节省内存空间而优化- final:指明数组一旦初始化,其地址就不能改变- 将char换成byte是为了节省空间,因为国外代码都是拉丁系列(**英文**)的文字,**1byte保存一个character**。- 但是使用的是utf-16(**中文**)的话,使用**2byte保存1character**。原创 2023-03-01 11:27:39 · 285 阅读 · 0 评论 -
【Java】线程通信
比如:线程A用来生产包子的,线程B用来吃包子的,包子可以理解为同一资源,线程A与线程B处理的动作,一个是生产,一个是消费,此时B线程必须等到A线程完成后才能执行,那么线程A与线程B之间就需要线程通信,即——当我们需要多个线程来共同完成同一个任务,并且我们希望他们有规律的执行,那么多线程之间久需要一些通信机制。可以协调他们的工作,以此实现多线程之间。一旦执行,都会进入阻塞状态。原创 2023-02-28 10:31:57 · 167 阅读 · 0 评论 -
【Java】创建多线程的四种方式
每个线程都有一定的优先级,同优先级线程组成先进先出队列(先到先服务),使用分时调度策略。优先级高的线程采用抢占式策略,获得较多的执行机会。每个线程默认的优先级都与创建它的父线程具有相同的优先级。当多个线程同时操作同一个共享数据时,就会出现线程的安全问题。原创 2023-02-27 21:02:54 · 3178 阅读 · 0 评论 -
Java代码块
1. 可以有输出语句。 2. 可以对类的属性、类的声明进行初始化操作。3. 代码块的执行优先于构造器,因而可以在代码块中进行初始化操作,在构造器中调用。4. 若有多个代码块,按声明顺序执行 - 静态代码块随着类的加载而加载,且只执行一次。 - 静态代码块的执行要先于非静态代码块。 - 不可以对非静态的属性初始化。即:不可以调用非静态的属性和方法。 - 每次创建对象的时候,都会执行一次。原创 2023-02-23 04:59:05 · 87 阅读 · 0 评论 -
Java main()方法剖析
由于JVM需要调用类的main()方法,所以该方法的访问权限必须是`public`,又因为JVM在执行main()方法时不必创建对象,所以该方法必须是`static`的, 该方法接收一个String类型的数组`参数`,该数组中保存执行Java命令时传递给所运行的类的参数。又因为main() 方法是`静态的`,我们不能直接访问该类中的非静态成员,必须创建该类的一个实例对象后,才能通过这个对象去访问类中的非静态成员。原创 2023-02-23 04:09:11 · 184 阅读 · 0 评论 -
【GoF 23】篇1:单例模式及指令重排问题
在Java中单例设计模式准确来说是,类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法。原创 2023-02-23 03:51:12 · 292 阅读 · 0 评论 -
Object类常用方法
- == 既可以比较基本类型也可以比较引用类型。对于基本类型就是比较值,对于引用类型就是比较内存地址- equals的话,它是属于java.lang.Object类里面的方法,如果该方法没有被重写过默认也是==;我们可以看到String、File、Date等类的equals方法是被重写过的,而且String类在日常开发中用的比较多,久而久之,形成了equals是比较值的错误观点。- 具体要看自定义类里有没有重写Object的equals方法来判断。- 通常情况下,重写equals方法,会比较类中的相应原创 2023-02-22 06:09:45 · 134 阅读 · 0 评论 -
为什么需要强制类型转换
因为多态的存在,就一定会有把子类对象赋值给父类变量的时候,这个时候,在编译期间,就会出现类型转换的现象。但是,使用父类变量接收了子类对象之后,我们就不能调用子类拥有,而父类没有的方法了。这也是多态给我们带来的一点"小麻烦"。所以,想要调用子类特有的方法,必须做类型转换,使得编译通过。总结:因为将子类对象赋值给父类引用,是不能使用子类中的属性或方法的,但是我们又需要使用,因而我们需要将父类强制向下转型为子类类型,从而可以使用子类的属性或方法。原创 2023-02-22 04:55:52 · 881 阅读 · 2 评论 -
子类实例化对象全过程
1. 从结果的角度看:体现为类的继承性- 当我们创建子类对象时,子类就获取了父类中声明的所有属性和方法,- 在权限允许的情况下,可以直接调用父类的属性和方法。 2. 从过程角度来看:- 当我们通过子类构造器创建对象时,子类的构造器一定会直接或间接的调用到其父类的构造器,- 子类的子类同样会直接或间接的调用父类的父类的构造器,- 直到调用了Object类中的构造器为止。问题1:在创建子类对象的过程中,一定会调用父类中的构造器吗? yes只有调用构造器,创建了实例才能调用到父类原创 2023-02-22 04:43:29 · 160 阅读 · 0 评论 -
this关键字的理解
在方法中使用,this指向当前对象(已经创建好的对象)。在构造器中使用,this指向当前正在创建的对像。一般情况下我们不会使用this关键字,只有特殊情况才会使用。- this调用属性:`this.属性` - 当 方法/构造器 形参和属性重名时使用- this调用方法:`this.方法名()`- this调用构造器:`this.()`或`this.(参数列表)` - 不能再当前构造器中调用当前构造器(递归)。 - this调用其他构造原创 2023-02-22 04:18:53 · 51 阅读 · 0 评论 -
import和package关键字的使用与注意点
- 一个源文件只能有一个声明包的package语句。- package语句作为Java源文件的第一条语句出现。若缺省该语句,则指定为无名包。- 包名,属于标识符,满足标识符命名的规则和规范(全部小写)、见名知意 - 包通常使用所在公司域名的倒置:com.xxx.xxx。 - 大家取包名时不要使用"java.xx"包- 包对应于文件系统的目录,package语句中用 “.” 来指明包(目录)的层次,每.一次就表示一层文件目录。- 同一个包下可以声明多个结构(类、接口),但是不能定义同名的结构(原创 2023-02-22 03:28:24 · 198 阅读 · 0 评论 -
Java Arrarys工具类
static void sort(int[] a) 将a数组按照从小到大进行排序static void sort(int[] a, int fromIndex, int toIndex) 将a数组的[fromIndex, toIndex)部分按照升序排列static void sort(Object[] a) 根据元素的自然顺序对指定对象数组按升序进行排序。static void sort(T[] a, Comparator原创 2023-02-21 00:54:44 · 146 阅读 · 0 评论 -
Java——数据类型默认初始化值
数组是引用类型,当我们使用动态初始化方式创建数组时,元素值只是默认值。对于引用数据类型而言,默认初始化值为null(注意与0不同!对于基本数据类型而言,默认初始化值各有不同。原创 2023-02-20 06:27:41 · 438 阅读 · 0 评论 -
Java之——自动类型提升、强制类型转换
Java各整数类型有固定的表数范围和字段长度,不受具体操作系统的影响,以保证Java程序的可移植性定义long类型的变量,赋值时需要以"l"或"L"作为后缀。Java程序中变量通常声明为int型,除非不足以表示较大的数,才使用long。Java的整型常量默认为 int 型。原创 2023-02-19 22:09:07 · 311 阅读 · 0 评论