
Java
文章平均质量分 92
Java
Schuyler_yuan
静听魔筝看花落,
穿着拖鞋抱着黄瓜啃
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
这就是AOP
举个例子,一个业务系统的很多模块都需要记录操作日志,这是一个能从业务逻辑中分离出来的横切关注点,完全不用交织在每个模块的代码中,可以作为一个单独的模块存在。AOP(Aspect Oriented Programming,面向切面编程)是一种编程范式,它的目的是通过分离横切关注点(cross-cutting concerns)来提升代码的模块化程度,AOP 的概念最早是由 Xerox PARC 提出的,它并非站在 OOP 的对立面,而是对 OOP 的一个很好的补充。,它定义了切面中能够采取的动作。原创 2024-12-04 21:09:19 · 407 阅读 · 0 评论 -
这就是IoC容器
IoC(Inversion of Control,控制反转),也叫依赖注入(Dependency Injection),是一种决定容器如何装配组件的模式。使用 Spring 来实现 IoC,意味着将设计好的对象交给 Spring 容器控制,而不是直接在对象内部控制。控制反转不能很好地描述这个模式,依赖注入却能更好地描述它的特点,所以才经常看到这两个词一同出现。只要遵循这种模式,按照一定规则,容器就能将组件组装起来。这里的容器就是用来创建组件并对它们进行管理的地方。原创 2024-12-04 21:03:38 · 766 阅读 · 0 评论 -
Spring 容器管理 Bean
Bean 是指 Java 中的可重用软件组件,容器会根据提供的元数据来创建和管理这些 Bean,也包括它们之间的依赖关系。Spring 容器对 Bean 并没有太多的要求,无须实现特定接口或依赖特定库,只要是最普通的 Java 对象即可,这类对象也被称为 POJO(Plain Old Java Object)。JavaBeans 是 Java 中一种特殊的类,可以将多个对象封装到一个对象(Bean)中。特点是可序列化,提供无参构造器,提供 Getter 方法和 Setter 方法访问对象的属性。原创 2024-12-04 20:46:26 · 1262 阅读 · 0 评论 -
Spring入园须知
这不是 Java 的黑历史,而是 Java 的来时路原创 2024-12-03 23:40:59 · 390 阅读 · 0 评论 -
Java注解原理
典型的就是 @Override 注解,一旦编译器检测到某个方法被 @Override 注解修饰了,编译器就会检查当前方法的方法签名是否真正重写了父类的某个方法,也就是比较父类中是否具有一个同样的方法签名。这种情况只适用于那些编译器已经熟知的注解类,比如 JDK 内置的几个注解,而自定义的注解,编译器是不知道注解作用的,当然也不知道该如何处理,往往只是会根据该注解的作用范围来选择是否编译进字节码文件。注解可以提供更大的便捷性,易于维护修改,但耦合度高,XML 相对于注解则是相反的。原创 2024-12-03 11:59:09 · 390 阅读 · 0 评论 -
Java 泛型
擦除时使用 Object 或者界定类型替代泛型,同时在要调用具体类型方法或者成员变量时插入强转代码,为了保证多态特性,Java 编译器还会为泛型类的子类生成桥接方法。Java泛型是一种类型参数化范式,有三种表现形式(分别是泛型方法,泛型类,泛型接口),允许开发者使用类型参数替代明确类型,实例化时再指明具体类型,达到了代码重用的目的,类似 C++ 模板的概念,但 Java 泛型是一种伪泛型。Java 编译器对泛型应用了强大的类型检测,如果代码违反了类型安全就会报错,可以在编译时暴露大多数泛型的编码错误。原创 2024-12-01 18:16:27 · 267 阅读 · 0 评论 -
反射和动态代理
否则被认为是不合法操作。从性能角度看,有 benchmark 表示 JDK Proxy 比 cglib 或者 Javassist 慢几十倍,暂且先不谈具体 benchmark 细节,在主流 JDK 版本中,JDK Proxy 在典型场景可以提供对等的性能水平,数量级的差距基本上不是广泛存在的。在选型中,性能未必是唯一考量,可靠性、可维护性、编程工作量等往往是更主要的考虑因素,毕竟标准类库和反射编程的门槛要低得多,代码量也是更加可控的,如果比较下不同开源项目在动态代理开发上的投入,也能看到这一点。原创 2024-12-01 17:35:49 · 867 阅读 · 0 评论 -
Java OOP
Default method 提供了一种二进制兼容扩展已有接口的办法,比如 java.util.Collection,它是 collection 体系的 root interface,在 Java 8 中添加了一系列 default method,主要是增加 Lambda、Stream 相关的功能。是对行为的抽象,它是抽象方法的集合(声明性的),方法定义和实现分离。特别说明的一点,方法名称和参数一致,但返回值不同,不是有效的重载,这点Java和C++一致,编译都会报错。实践中过度滥用继承可能会起到反效果。原创 2024-12-01 11:57:15 · 924 阅读 · 0 评论 -
ConcurrentHashMap
初始化在 initTable 实现,这是一个典型的 CAS 使用场景,volatile 的 sizeCtl 作为互斥手段,如果发现竞争性的初始化,就 spin 在那里,等待条件恢复;数据一致性是怎么保证的?HashEntry内部使用 volatile 的 value 字段来保证可见性,也利用了不可变对象的机制改进利用 Unsafe 提供的底层能力(比如 volatile access)去直接完成部分操作,以最优化性能,毕竟 Unsafe 中的很多操作都是 JVM intrinsic 优化过的。原创 2024-11-29 21:08:26 · 286 阅读 · 0 评论 -
Java Map
这种行为适用于一些特定场景,比如构建一个空间占用敏感的资源池,希望可以自动将最不常被访问的对象释放掉,就可以利用LinkedHashMap提供的机制来实现。TreeMap则是基于红黑树的一种提供顺序访问的Map,和HashMap不同,它的get、put、remove操作都是O(log(n))的时间复杂度,具体顺序可以由指定的Comparator来决定,或者根据键的自然顺序。大部分使用Map的场景,通常是放入、访问、删除,对顺序没有特别要求,HashMap在这种情况下基本是最好的选择。原创 2024-11-29 17:40:06 · 201 阅读 · 0 评论 -
Java Collection
它不需要考虑扩容,空间上更加紧凑等。Collection集合类都不是线程安全的,但并不代表这些集合完全不能支持并发编程的场景,在Collections工具类中提供了一系列的synchronized方法,但平常不推荐使用,同步控制粒度太大,不适合对性能要求较高的场景。Queue/Deque,Java提供的标准队列结构的实现,除了集合的基本功能,它还支持类似先入先出(FIFO, First-in-First-Out)或者后入先出(LIFO,Last-In-First-Out)等特定行为。原创 2024-11-29 16:46:40 · 989 阅读 · 0 评论 -
Java原始数据类型和包装类
对于应用移植,存在一些底层实现的差异,比如64位HotSpot JVM里的对象要比32位HotSpot JVM大(具体区别取决于不同JVM实现的选择),但总体来说并没有行为差异,应用移植还是可以做到“一次书写,到处执行”,开发者更多需要考虑的是容量、能力等方面的差异。Java对象是引用类型,内建了多态、线程安全等方面的支持,一个原始数据类型数组在内存里是一段连续的内存,而对象数组存储的是引用,对象分散地存储在堆的不同位置。各种转换方法(比如转换为不同进制的字符串,如8进制),或者反过来的解析方法等。原创 2024-11-29 15:36:13 · 655 阅读 · 0 评论 -
Java String设计思想
为了能修改字符序列,StringBuffer和StringBuilder底层都是利用可修改的(char,JDK 9以后是byte)数组,二者都继承了AbstractStringBuilder,里面包含了基本操作,区别仅在于最终的方法是否加了synchronized。在运行时,字符串的一些基础操作会直接利用JVM内部的Intrinsic机制,往往运行的就是特殊优化的本地代码,根本就不是Java代码生成的字节码。我们如果确定拼接会发生非常多次,而且大概是可预计的,就可以指定合适的大小,避免很多次扩容的开销。原创 2024-11-29 00:38:04 · 670 阅读 · 0 评论 -
聊聊Exception和Error
聊聊Exception和Error原创 2024-11-28 21:10:55 · 232 阅读 · 0 评论