java

java内部类

java静态内部类及非静态内部类 在非静态内部类中不可以声明静态成员变量及方法,静态内部类可声明静态及非静态成员变量及方法 非静态内部类,可以随意的访问外部类中的成员变量与成员方法,即使这些成员方法被修饰为private 不能够从静态内部类的对象中访问外部类的非静态成员(包括成员变量与成员方法) 创建静态内部类时不需要将静态内部类的实例绑定在外部类的实例上,而非静态内部类必须绑定在外部类的实例上 内部类的声明关键字同其它成员变量的声明关键字,如若内部类声明为protected,则当前类,同包,子类可创建及使用该内部类,而其它类则不可访问;内部类中的声明同理 // 非静态内部类 Student s = new Student(); Child c = s.new Child(); // 静态内部类 Student s = new Student(); Child

  • developer
1 min read
java

如何开发一个starter

参考 starter的概念 starter是一种对依赖的synthesize(合成) 进行一些默认的初始化,并且这些初始化操作,都可以在spring.yaml配置文件中覆盖 进行一些实例的初始化,比如之前如果要实例化某类 配置spring 扫描某包 手动通过config创建bean 而starter可通过spring.factories文件实例化对象 传统的做法 在没有starter之前,假如我想要在Spring中使用jpa,那我可能需要做以下操作: 在Maven中引入使用的数据库的依赖(即JDBC的jar) 引入jpa的依赖 在xxx.xml中配置一些属性信息 反复的调试直到可以正常运行 需要注意的是,这里操作在我们每次新建一个需要用到jpa的项目的时候都需要重复的做一次。也许你在第一次自己建立项目的时候是在Google上自己搜索了一番,花了半天时间解决掉了各种奇怪的问题之后,jpa终于能正常运行了。有些有经验的人会在OneNote上面把这次建立项目的过程给记录下来,包括操作的步骤以及需要用到的配置文件的内容,在下一次再创建jpa项目的时候,

  • 凯文
8 min read
java

7.3 jvm之nio之基本概念及基本操作

一. io与nio的区别 io 与 nio介绍 io:io是对流的操作,分input及output两种流。 nio:nio是对缓冲区的操作,该缓冲区为双向的,即可输入又可输出 Java NIO提供了与标准IO不同的IO工作方式: Channels and Buffers(通道和缓冲区):标准的IO基于字节流和字符流进行操作的,而NIO是基于通道(Channel)和缓冲区(Buffer)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。 Asynchronous IO(异步IO):Java NIO可以让你异步的使用IO,例如:当线程从通道读取数据到缓冲区时,

  • developer
4 min read
java

7.2 jvm之io字节流

字节输入流 字节输入流概括 值得注意的地方有: Level 2的输入流,大多数都会指明数据源的形式:例如ByteArray,File,Piped Level 3的输入流,则不会出现具体的数据源名字,而是以功能取代:例如Buffered,LineNumber 所以说Level 3的输入流是对Level 2输入流的“封装和过滤”。实际上Level 3的输入流,都继承于FilterInputStream的输入流。 input stream介绍 ByteArrayInputStream 从内存中每次读取一个字节的数据,然后保存到内置的缓冲区中。维持一个计数器用来记录从数据源中读入的字节数目。 调用该输入流的close()方法不会产生任何实际的作用。因为它“关闭”的对象是---内存。

  • developer
4 min read
java

7.1 jvm之io字符流

字符输入流 字符输入流概括 Level 2的输入流,大多数都会指明数据源的形式:例如CharArray,String,File Level 3的输入流,则不会在出现具体的数据源名字,而是以功能取代。例如:Buffered,LineNumber 但是和基于字节的输入流结构不同,FileInputStream是直接继承于InputStream类(基础类)的。但是FileReader却是继承于InputStreamReader的。看看下面的结构: java.io.Reader (implements java.io.Closeable, java.lang.Readable) java.io.

  • developer
5 min read
java

JVM8调优

在JVM里的内存空间,从大的层面划分,主要有新生代空间(Young)和老年代空间(Old),其中Young空间,又被分为2个部分和3个板块,分别是1个Egen区,和2个Survivor区 Eden区域是用来存放使用new或者newInstance等方式创建的对象,默认都是存放在Eden区,除非这个对象太大,或者超过了设定的阈值-XX:PretenureSizeThresold,这样的对象会被直接分配到Old区域 2个Survivor(幸存)区,一般称S0,S1,理论上他们是一样大的 在不断创建对象的过程中,Eden区会满,这时候会开始做Young GC也叫Minor GC,而Young空间的第一次GC就是找出Eden区中,幸存活着的对象,然后将这些对象,放到S0,或S1区中的其中一个,假设第一次选择了S0,

  • 凯文
2 min read
java

java之AQS

AQS概述 AQS(AbstractQueuedSynchronizer),类如其名,抽象的队列式的同步器,AQS定义了一套多线程访问共享资源的同步器框架,许多同步类实现都依赖于它,如常用的ReentrantLock/Semaphore/CountDownLatch...。 在AQS中维护了一个volatile int state(代表共享资源)和一个FIFO线程等待队列(多线程争用资源被阻塞时会进入此队列) AQS在重入锁中的使用 以ReentrantLock为例,state初始化为0,表示未锁定状态 在ReentrantLock中lock()方法,实际上调用的是AQS的acquire(1)方法;而在acquire(1)中实际上会调用tryAcquire()方法,tryAcquire()方法在AQS中是无方法体的,需要自己实现; unlock(

  • developer
7 min read
java

JVM垃圾回收器

JVM回收器概述 垃圾收集器是垃圾回收算法(标记-清除算法、复制算法、标记-整理算法、分代算法)的具体实现,不同商家、不同版本的JVM所提供的垃圾收集器可能会有很在差别,本文主要介绍HotSpot虚拟机中的垃圾收集器。 垃圾收集器组合 图中展示了7种不同分代的收集器:Serial、ParNew、Parallel Scavenge、Serial Old、Parallel Old、CMS、G1; 而它们所处区域,则表明其是属于新生代收集器还是老年代收集器: 新生代收集器:Serial、ParNew、Parallel Scavenge; 老年代收集器:Serial Old、Parallel

  • 凯文
22 min read
java

java垃圾回收算法

标记-清除算法 算法概述 分为标记和清除两个阶段:首先标记出所有需要回收的对象,标记完成后统一回收所有被标记的对象;是最基础的收集算法,其它的收集算法都是基于这种思路并对其不足进行改进而得到的。 不足 效率问题,标记和清除两个过程的效率都不高; 空间问题,标记清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致以后再程序运行过程中需要分配较大对象时,无法找到足够的连续内存二不得不提前触发另一次垃圾收集动作。 复制算法 算法概述 为了解决效率问题,复制收集算法出现了,他将可用的内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块内存用完了,就将还存活的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉 不足 这种算法的代价是将内存缩小为原来的一般,代价太高 用途 存活区采用这种算法。因为新生代中的对象98%是“朝生夕死”,所以并不需要按照1:1的比例来划分内存空间,

  • developer
3 min read
java

jvm之Unsafe.CAS

CAS概述 Unsafe 是 java 留给开发者的后门,用于直接操作系统内存且不受 jvm 管辖,实现类似 C++ 风格的操作。 Oracle 官方一般不建议开发者使用 Unsafe 类,因为正如这个类的类名一样,它并不安全,使用不当会造成内存泄露。 在平时的业务开发中,这个类基本是不会有接触到的,但是在 java 的并发包和众多偏向底层的框架中,都有大量应用。 值得一提的是,该类的大部分方法均为 native 修饰,即为直接调用的其它语言(大多为 C++)编写的方法来进行操作,很多细节无法追溯,

  • developer
2 min read
java

JDK动态代理与Cglib动态代理

Cglib与JDK动态代理的区别 JDK代理只能针对实现了接口的类以反射的方式生成代理,而不能针对类 CGLIB是针对类实现代理的,主要对指定的类以字节码转换的方式(ASM框架)生成一个子类,并重写其中的方法。    因为是创建目标类的子类,所以目标类必须要有无参构造函数(子类的有参构造函数会调用父类无参),否则报错 另外因为是继承,所以我们的目标类最好不要使用Final声明 Spring如何切换不同的代理 1、如果目标对象实现了接口,默认会采用JDK的动态代理机制实现AOP,但是可以强制使用CGLIB实现AOP ;     缺点:必须实现接口,并且生成的代理对象也只能声明成为其中一个接口,其他接口的方法和自己的方法访问不到。 2、如果目标对象没有实现接口,必须使用CGLIB生成代理,spring会自动在CGLIB和JDK动态代理之间切换 。 通过注解 @EnableAspectJAutoProxy(proxyTargetClass=true, exposeProxy=true)

  • developer
4 min read
java

7. jvm之io之字符流与字节流总括

1、Java IO 流 io是java中实现输入输出的基础,它可以很方便的完成数据的输入输出操作,Java把不同的输入输出抽象为流,通过流的方式允许Java程序使用相同的方式来访问不同的输入、输出。 2、流的分类 输入流、输出流 A、输入流:只能从中读取数据,而不能向里面写数据 B、 输出流:只能向里面写数据,而不能读数据 可以这样理解,数据从内存到硬盘,通常认为是输出流,即写操作;相反,从硬盘到内存,通常认为是输入流,即读操作;这里的输入、输出是从内存的角度划分的。 Java的输入流主要有InputStream和Reader作为基类,而输出流则主要由OutputStream和Writer作为基类;

  • developer
4 min read
java

18. jvm之关键字

transient:实现Serilizable接口,接口的类均可被实例化,若类的属性以transient标识,则序列化对象的时候,这个属性就不会序列化到指定的目的地中。 native: 调用原生的c语言代码 (4. jvm之native方法和JNI基础中有详细说明) instanceof: instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例。 public static void test(Inter t){   System.err.println(t instanceof InterImpl);   } 注:类 InterImpl必须为Inter的子类(也可以是Inter及其父类,但是对象肯定是Inter及其父类的对象,所以无意义) volatile: http:

  • developer
1 min read
java

17. JVM之性能调优工具

jmap 命令介绍 得到运行java程序的内存分配的详细情况。例如实例个数,大小等 格式 jmap [ option ] pid pid为java进程号 -dump:[live,]format=b,file=<filename> 使用hprof二进制形式,输出jvm的heap内容到文件=. live子选项是可选的,假如指定live选项,那么只输出活的对象到文件. -finalizerinfo 打印正等候回收的对象的信息. -heap 打印heap的概要信息,GC使用的算法,heap的配置及wise heap的使用情况. -histo[:live] 打印每个class的实例数目,

  • developer
8 min read
java

16. jvm之数组

基本数据类型的数组无法自动封装为对象数据类型的数组 数组同样可获取到class对象,通过is.getClass().isArray()判断是否为数组 如果为数组,需要通过args instanceof Object[] 或者 args instanceof int[] 判断是哪种数据类型的数组,之后再进行转换,否则会转换异常 数组包括基本数据类型的数组均通过Object(注意非Object [])入参接收,确定该数组的数据类型后,可转为该类型的数组 Arrays的asList方法只对数据类型为对象类型的数组有效,基本数据类型的数组无效;基本数据类型调用该方法时,会把整个数组当作object放入list中返回 数组的打印结果为[Ljava.lang.String;@5387f9e0,L数组类型;@地址

  • developer
3 min read
java

13. jvm之动态代理

java的动态代理机制详解 在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的我们的功能,我们更需要学习的是其底层是怎么样的一个原理,而AOP的原理就是java的动态代理机制,所以本篇随笔就是对java的动态机制进行一个回顾。 在java的动态代理机制中,有两个重要的类或接口,一个是接口InvocationHandler、另一个则是类 Proxy,这一个类和接口是实现我们动态代理所必须用到的。首先我们先来看看java的API帮助文档是怎么样对这两个类进行描述的: InvocationHandler: InvocationHandler is the interface implemented by the invocation handler of a proxy instance.

  • developer
8 min read