Java
文章平均质量分 59
司青-已停止更新
本博客已停更;
展开
-
Maven中如何跳过不支持skip参数的插件执行
我们知道,很多maven官方插件都支持skip参数,命令行指定skip=true即可跳过此插件的执行,非常方便。但是很多第三方的插件根本就不支持skip参数,无法通过命令行传参的方式跳过插件的执行。我们可以用一些非官方的方式绕过这个限制。总体思路为,将你想要跳过的插件的phase参数指定为一个不存在的phase,这样maven在执行的时候就会忽略这个插件。例如: <properties> <mvn.jarvis.skip>package</mvn.jarvis.s原创 2022-03-09 17:52:33 · 1954 阅读 · 1 评论 -
快速彻底理解字符集和字符集编码的区别
很多文章搞长篇大论大讲特讲人类为了让计算机能够准确表示各种字符的演化历史,这完全是没有必要的,几句话就能说明白。"字符集"和"字符集编码"是两回事字符集(Charset Set),仅仅是一套从【字符】到【数字】的映射字典,它只规定了应该用什么数字来标识字符,仅此而已,至于计算机在存储的时候应该用什么字节来标识,字符集是根本不管这事的。Unicode, GB2312, ASCII都属于字符集。字符集编码(Character Encoding),专门规定了字符集中的字符在计算机中应该如何存储,说白了就是怎原创 2021-11-07 18:35:10 · 516 阅读 · 0 评论 -
如何手动编译Apple Silicon M1版本的JavaFX SceneBuilder
用JavaFX写GUI的朋友肯定少不了SceneBuilder这个神器,拖拖拽拽就能完成窗口布局。但是对于Mac M1的用户来说, SceneBuilder 并没有提供M1版本,官方的intel版本能用但是很卡,用起来很难受。下面我们来看看如何直接从源码构造M1版本的SceneBuilder。准备工作首先我们要下载M1版本的Zulu OpenJDK 16, 用来编译源码,然后要去Gluon的官网下载M1版本的JavaFX SDK, 如下:JavaFX Mac OS X AArch64 SDK:htt原创 2021-07-03 13:15:14 · 705 阅读 · 1 评论 -
[Golang实现JVM第七篇]实现invokevirtual和虚方法表
本篇我们专注invokevirtual这一条指令,先通过简单粗暴的方式实现指令的功能,然后探究如何通过著名的虚方法表(Virtual Method Table)来进行一些优化。指令含义invokevirtual用于调用除静态方法、构造方法、私有方法、接口方法外的所有方法。其指令的格式为:invokevirtual = 182 (0xb6)Format:invokevirtual indexbyte1 indexbyte2Operand Stack:..., objectref, [arg1原创 2020-10-09 20:12:02 · 872 阅读 · 0 评论 -
从JVM角度看为什么final字段可以“延迟“到构造方法中初始化
我们都知道在Java中final字段都是要在定义时完成初始化工作的,否则通不过编译。但是有一处例外,那就是对于对象的字段来说final字段可以"延迟"到构造方法,或者static {}语句块中初始化,例如下面的代码public class FinalTest { private static final Object staticObj; private final Object noneStatic; static { staticObj = new Objec原创 2020-09-01 19:42:04 · 492 阅读 · 0 评论 -
[Golang实现JVM第六篇]实现Native方法
首先需要明确几个问题。没有Native方法JVM什么也做不了可能很多人认为native方法是Java里的禁区,使用本地方法会牺牲可移植性,而且还会有额外开销,貌似几乎没有程序员会在实际项目中写本地方法,这玩意就是个很冷门的东西。其实这种看法是错误的,哪怕一个Hello Word程序都是要严重依赖于本地方法的。在JDK中,你会发现任何涉及到I/O、线程操作的类,层层追踪源码后最终都能找到一个对应的native调用,真正把Hello World打印到控制台的正是这些native方法。而用于启动线程的Thre原创 2020-08-24 16:39:45 · 871 阅读 · 0 评论 -
[Golang实现JVM第五篇]静态方法调用的实现
一直以来又长又臭的调用链简直就是Java语言的标志性特色,方法调用可谓是Java世界里表达一切逻辑的基石。现在我们终于具备了实现它的基础。JVM中的5条方法调用指令在JVM中触发方法调用的指令有5条,分别是:invokestatic调用静态方法invokespecial调用构造方法invokeinterface调用接口方法invokevirtual调用对象方法invokedynamicjdk1.7中引入,给动态语言预留的调用指令。指令的第一个参数不再是代表方法符号原创 2020-07-08 15:50:47 · 585 阅读 · 2 评论 -
[Golang实现JVM第四篇] 整数加法和条件判断指令的实现
在上一篇中我们实现了一个能跑的解释器,支持了一些基本的栈操作指令。现在我们就可以开始实现"有点用"的数学运算和条件判断了。github: https://github.com/wanghongfei/mini-jvm局部变量表、程序计数器由于JVM字节码是基于栈的指令集,因此一切操作都是以栈为基础的,也就是说计算1+1,那需要先在栈中压入两个1然后进行计算,如果是对象方法调用,那么对象的引用、方法参数都会事先被压入栈中。除栈外还有一个跟执行相关的重要结构就是局部变量表(Local Variable T原创 2020-07-02 14:11:37 · 372 阅读 · 0 评论 -
[Golang实现JVM第三篇] 解释器雏形
在上一篇中我们已经完成了class文件的解析工作,虽然没有解析所有的属性,但是已经足够支持一些基本的算法题Java代码编译生成的class文件了。有了这一步,日后如果遇到新的特性需要支持,只需缺哪补哪,补上对应属性的解析逻辑就可以了。下一步就是实现一个基本的执行引擎,即解释器,并且支持基本的栈操作相关的指令,比如iconst_x, istore_x, bipush等。基于栈的指令集和基于寄存器的指令集JVM字节码是一套基于栈的指令集,也就是说操作数栈是一切计算的基本容器,大部分指令都是围绕着操作数栈展开原创 2020-06-15 16:43:35 · 479 阅读 · 0 评论 -
使用Kafka时一定要注意防止消费速度过慢触发rebalance而导致的重复消费
在Java应用中,我们往往会使用spring-kafka组件简单的设置一下group_id, topic就开始消费消息了,其实这样会埋下巨大的安全隐患,即当消费速度过慢时有可能会触发rebalance, 这批消息被分配到另一个消费者,然后新的消费者还会消费过慢,再次rebalance, 这样一直恶性循环下去。发生这种情况最明显的标志就是日志里能看到CommitFailedException异常,然...原创 2020-04-02 22:26:06 · 7388 阅读 · 1 评论 -
业务系统如何正确实现防重名功能
常见但是错误的实现在业务系统中防重名是一个非常普遍的需求,例如用户注册时不允许用户名重复、已登录用户不可以在自己的账号范围内创建同名的某种实体等。很多人在实现的时候都是简单的先判断名字是否重复,如果没有则执行插入操作,如下: public void register(User user) { // 判断是否重复 (1) if (userMapper.sel...原创 2020-03-09 00:25:17 · 2204 阅读 · 1 评论 -
Netty对零拷贝(Zero Copy)三个层次的实现
首先我们来看一下维基百科对零拷贝给出的定义:零拷贝描述了一种计算机中的操作,即CPU在执行某项任务时不需要先将数据从内存中的一个位置移动到另一个位置就可以完成操作,从而节省了CPU时钟周期和内存带宽。从上面的描述可以看出,其实只要是节省了一次或多次数据的复制就可以称之为零拷贝了,这其实是一种广义的定义。在Netty中对于零拷贝有三个层次的实现,我们就一条条分析一下。避免数据流经用户空间...原创 2019-10-26 14:13:47 · 853 阅读 · 1 评论 -
Java中对象的销毁
Java中的基本数据类型变量和对象的名称引用变量如定义在方法中,都为局部变量。但对象本身不一定是局部生命周期。如函数外存在其他对该对象的引用变量,则该对象的生命周期延伸至该其他引用变量所在的块。如从被调用函数参数引用传值或返回值到主调用函数所在的对象类型变量中,则该对象都仍存在(但被调用函数的该对象的引用变量生命周期结束,因此引用变量是局部变量),此时对象突破了局部变量的局部生命期。原创 2013-03-05 14:43:15 · 2691 阅读 · 0 评论 -
Java - 简易记事本
没有自己以前用Windows API写的好看了。。。JDK Version : 1.7.0Source Code :import java.io.*;import java.awt.*;import java.awt.event.*;/** * The Main Window * @author Neo Smith */class Pad原创 2013-03-15 09:24:45 · 1684 阅读 · 0 评论 -
Java性能优化技巧
Java性能优化技巧参考了些书籍,网络资源整理出来,适合于大多数Java应用在JAVA程序中,性能问题的大部分原因并不在于JAVA语言,而是程序本身。养成良好的编码习惯非常重要,能够显著地提升程序性能。1.尽量使用final修饰符。带有final修饰符的类是不可派生的。在JAVA核心API中,有许多应用final的例子,例如java.lang.String。为Strin转载 2013-03-15 17:06:51 · 1203 阅读 · 0 评论 -
C#, C++, Java性能对比
C# vs C++ vs Java性能对比C#, Java 和C++对比性能常常是引发争议的一个话题。那些不熟悉JIT的人常常声称JIT上运行的任何程序跟C++比速度都不行。而那些使用Java和C#的人则常常声称性能差别甚小,几乎可以忽略不计。这里有一个测试对比结果图,来自freenode IRC服务器,不知道谁测试的,但是结果似乎很真实。对于我来说,因为性能原因选择C++似乎转载 2013-03-16 20:47:50 · 8024 阅读 · 1 评论 -
Java的IO操作(二) - 带缓冲区的流对象、写入基本数据类型、实现命令行中的copy命令
在上一节中,我们使用FileInputStream类和FileOutputStream类来实现了一个可以自由拷贝文件的功能。为了提高效率,我们人为地定义一个缓冲区byte[] 数组。其实,我们可以使用BufferedInputStream类和BufferedOutputStream类来重写这个功能。5、BufferedInputStream、BufferedOutputStream原创 2013-03-30 11:26:57 · 3500 阅读 · 2 评论 -
Java的IO操作(一) - File类,RandomAccessFile类,FileInputStream、FileOutputStream类
在Java中,所有的输入、输出问题都会被抽象成流(Stream)对象来解决。下面介绍一下常用的输入、输出流对象的使用方法。1、 File类File类是文件的抽象代表。一个文件(包括目录)就是一个File类的实例。java.io.File类为我们提供了一个抽象的、系统独立的文件表示,我们不必纠结于因为不同的操作系统文件路径的表示方法不同而造成的差异,File会将传进去的路径自动转换为原创 2013-03-28 20:28:01 · 5333 阅读 · 0 评论 -
Java对泛型的支持(二)- 高级语法
JAVA中基本的泛型语法元素大致有三种:限制泛型可用类型、使得类型通配符,以及泛型的继承。下面将分别对这三种语法进行介绍。1、限制泛型可用类型我们在定义泛型类时,默认的是可以使用任何类型来实例化泛型类中的类型持有者。我们也可以指定某种类型,使得此泛型类只能通过这种类型或其子类,或实现这个接口的类来实例化类型持有者。我们在定义类型持有者时,使用extends关键字来进行限制,例如原创 2013-03-27 14:10:05 · 2490 阅读 · 0 评论 -
Java对泛型的支持(一) - 基本语法
题外话:前几天我的笔记本电脑硬盘坏了,本子送到售后进行维修,需要2到3个工作日才能搞定。。现在木有本本用了,无奈就借了女朋友的本子先用着了。。现装的JDK,UltraEdit。。所以下面的图片中编译器的报错信息就变成了中文。。哎,脆弱的硬盘啊。。。Java在J2SE 5.0后开始增加了泛型(Generics)功能,并且许多API都根据这个新的功能被重新改写了,例如List、Map、Se原创 2013-03-25 21:48:02 · 2512 阅读 · 2 评论 -
对象容器 - Java对数据结构的封装 - List, ArrayList, LinkedList, Set, SortedSet, HashSet, Map, TreeMap
在实际编程当中,很多时候我们要把数据暂时储存起来,以便实现某种特定的功能。在纯C语言中,我们需要自己去实现一个数据结构(如链表、队列等)来进行元素的存取,不仅繁琐,而且效率也不高(类库对数据结构的封装往往都是优化过的,有着较好的性能)。在Java中,我们可以使用对象容器(Container)来方便地存取数据。1、List接口(List interface)List接口是java.u原创 2013-03-22 11:23:43 · 3178 阅读 · 0 评论 -
Java中的字符串
字符串的本质是char类型的数组,但在java中,所有用双引号""声明的字符串都是一个String类的对象。这也正体现了Java完全面向对象的语言特点。String 类1、String类对象表示的是一个常量字符串。它是不可变长度的。也就是说,一旦创建了一个String类的实例,那么这个实例所表示的串是不可改变的。类似于str = str + "Hello";这样的操作,实质上是原创 2013-03-18 19:31:56 · 1742 阅读 · 0 评论 -
Java的IO操作(三) - 对象的序列化、ObjectInputStream和ObjectOutputStream类
由于Java是一种完全面向对象的高级语言,所以在编写程序的时候数据大都存放在对象当中。我们有时会需要将内存中的整个对象都写入到文件中去,然后在适当的时候再从文件中将对象还原至内存。我们可以使用java.io.ObjectInputStream和java.io.ObjectOutputStream类来完成这个任务。1、对象的序列化(Serialize)序列化是指将对象的状态信息转换为原创 2013-04-01 10:18:00 · 2714 阅读 · 2 评论 -
Java中的多态
多态,是面向对象的程序设计语言最核心的特征。封装性、继承性都比较简单,所以这里只对多态做一个小小的笔记。。。1、什么是多态?多态意味着一个对象可以多重特征,可以在特定的情况下,表现出不同的状态,从而应对不同的属性和方法。在Java中,多态的实现指的是使用同一个实现接口,以实现不同的对象实例。例如,我们定义一个Parent类,再定义一个getName()方法返回一个字符串,定义一原创 2013-03-18 23:19:32 · 3279 阅读 · 0 评论 -
Java的异常处理
Java的异常处理机制可以帮助我们避开或者处理程序可能发生的错误,从而使得程序在遇到一些可恢复的错误的时候不会意外终止,而是去处理这些错误,也使得我们在写程序的时候不必写大量的代码来检查错误情况,增强了代码的可读性和逻辑性。在Java中,异常代表一个错误的实体对象。异常可分为两类;一类是严重错误,如硬件错误、内存不足等,它们对应着java.lang包下的Error类及其子类。通常这类错原创 2013-03-21 16:23:05 · 1765 阅读 · 1 评论 -
Java的IO操作(四) - SequenceInputStream类,实例:一个文件分割、合并工具
SequenceInputStream可以看做是多个InputStream对象的有序集合。当一个InputStream对象的数据读取完后,它会自动取出下一个InputStream对象进行读取,直到所有的InputStream对象都读取完为止。利用这个特点,我们来编写一个文件分割、合并工具。使用说明:SequenceDemo [Option] [filePath] [number原创 2013-04-02 21:00:44 · 3401 阅读 · 2 评论 -
管理Java类文件
在java中,每一个定义好的类,在编译的时候,都会对应地产生一个.class文件。如果程序的规模越来越大,那么类文件也会越来越多,管理起来也会越来越麻烦,很容易发生命名的冲突。因此,java中引入了"包"(package)的概念。一、内部类在类中还可以再定义类,这种类叫做内部类(Inner Class)。使用内部类主要有三个好处:一是可以任意地访问对应的外部类的私有(private原创 2013-03-20 20:29:33 · 1739 阅读 · 0 评论 -
Java对多线程的支持(二) - 线程死锁
我们知道,当线程A由于某种原因(如等待IO操作完成、调用了sleep函数等)放弃了执行权时,操作系统就会调度另一个处于就绪状态(Runnable) 的线程B来执行。只有当线程A所等待的事件发生(如IO操作完成,睡眠时间结束)后,线程A才会被设置成就绪状态,等待操作系统的调度。然而有时候可能会出现这样一种情况:线程A为了等待线程B而处于阻塞状态(blocked),此时线程B恰好又在等待线程A而处原创 2013-04-10 01:22:57 · 1942 阅读 · 2 评论 -
Java对多线程的支持(一) - Thread类、Runnable接口、Daemon线程、线程同步
Java是第一个在语言级提供了对多线程程序设计支持的语言。语言级支持是啥意思呢,就是抛开操作系统,只使用Java内置的语句就能实现多线程。一般来讲,多线程会依赖操作系统,我们要高用与系统相关的API才能创建多个线程,如在Windows中的CreateThread()函数。但JAVA就不用了。JAVA运行时系统实现了一个用于调用线程执行的线程调度器,用来决定在某一时刻哪个线程在CPU上运行。原创 2013-04-05 23:49:23 · 5135 阅读 · 3 评论 -
Java网络编程(一)- 一个简单的服务端/客户端应用程序
在Java中,我们使用java.net.Socket及其相关类来完成有关网络的相关功能。Socket类非常简单易用,因为Java技术隐藏了建立网络连接和通过连接发送数据的复杂过程。下面所说的内容只适用于TCP协议。一、连接到服务器我们可以使用Socket类的构造函数来打开一个套接字,如Socket sk = new Socket("210.0.235.14",13);其中,原创 2013-05-04 23:22:33 · 3698 阅读 · 0 评论 -
基于AWT、Swing的GUI程序 - 改变观感
本程序通用调用UIManager.getInstalledLookAndFeels()方法来获取本机已安装的所有观感,然后分别创建相应数量的Button,用来动态改变观感。相关API :static voidsetLookAndFeel(LookAndFeel newLookAndFeel)设置观感static voidupdateComponentTreeUI(C原创 2013-05-10 00:05:35 · 1746 阅读 · 0 评论 -
基于AWT、Swing的GUI编程 - 多个命令共享同一个监听器类
用户点击窗口中的yellow按钮、用户按下Ctrl + Y 键,都会改变背景颜色至黄色。多个事件源调用的都是同一个类的actionPerformed()方法.Ctrl + Y 黄Ctrl + B 绿Ctrl + L 黑相关类:public class KeyStrokeextends AWTKeyStrokeA KeyStroke repres原创 2013-05-10 11:35:18 · 1363 阅读 · 0 评论 -
Java反射机制的缺点
译自官方指南(Tutorial):http://docs.oracle.com/javase/tutorial/reflect/index.html反射的用途 Uses of ReflectionReflection is commonly used by programs which require the ability to examine or modify翻译 2013-06-14 23:33:35 · 3684 阅读 · 0 评论 -
反射API
反射,是指一种能在运行时动态加载、分析类的能力。反射被广泛地用于那些需要在运行时检测或修改程序行为的程序中。这是一个相对高级的特性,使用反射技术应当具备相当的Java语言基础。我们可以通过反射机制让应用程序做一些几乎不可能做到的事情。一. Class类在java.lang包中有一个特殊的类,即Class类。JVM会为所有被加载的类创建一个对应的Class类的对象,这个对象保存了类的原创 2013-06-23 01:57:11 · 2308 阅读 · 0 评论 -
Java的IO操作(五) - PrintStream类、字符流、Reader和Writer、带缓冲的字符流BufferedReader和BufferedWriter
1. PrintStream类我们都知道,int类型在Java中占4个字节,如1在内存中表示为 00000000 00000000 00000000 00000001。如果我们直接使用OutputStream对象输出到一个文件中的话,那么程序就会向文件中直接写入 00000001。不用说,用记事本打开的话肯定会是一个奇怪的字符。现在我们想要将内存中的数据转换成字符型再输出到文件中,就可以使用P原创 2013-04-18 00:44:31 · 3179 阅读 · 0 评论 -
Java对象的内存模型
众所周知,函数调用在内存中是通过压栈,退栈实现的,而Java的方法调用则是在JVM栈中通过栈帧实现的,且所有的Java对象都只在堆上分配内存.那么一个Java对象在堆内存里到底长啥样呢?实际上,当一个对象在内存中被创建的时候,它只不过是一串0和1而已.编译器会维护一张表,这张表用来存储对象中的每一个成员变量所在位置的偏移量(offset).这样,通过查这张表,JVM就能知道每一个成员变量相对于其起原创 2013-10-19 09:15:22 · 2156 阅读 · 0 评论 -
HashMap计数器的高效实现
原始的计数器在实际应用中,我们经常把HashMap作为一个计数器使用.例如统计一篇文章中单词 'the' 出现了多少次.于是我们很轻松地就能写出下面的程序:Map counter = new HashMap(); for(String s : strs) { if(counter.containsKey(s)) { Integer times = counter.get(原创 2013-11-30 17:02:48 · 4495 阅读 · 0 评论 -
如何重写hashCode()和equals()方法
hashCode()和equals()方法可以说是Java完全面向对象的一大特色.它为我们的编程提供便利的同时也带来了很多危险.这篇文章我们就讨论一下如何正解理解和使用这2个方法.如何重写equals()方法最安全如果你决定要重写equals()方法,那么你一定要明确这么做所带来的风险,并确保自己能写出一个健壮的equals()方法.一定要注意的一点是,在重写equals()后,一原创 2013-12-02 12:57:13 · 44288 阅读 · 29 评论 -
Java中的null到底是啥?
我们从下面这个简单的语句说起:String x = null;这行代码做了什么?先回想一下什么叫做变量(variable),什么叫做值(value)。我们通常把一个变量比喻成一个盒子。我们可以用盒子来装东西,同样我们就可以用变量变保存值。定义变量时需要指定变量的类型。在Java中,有2种主要的数据类型:基本数据类型和引用类型。定义成基本数据类型的变量用来保存值,而定翻译 2013-12-28 04:48:30 · 2061 阅读 · 0 评论 -
JDK1.7 API -- Scanner
个人英文水平有限,勉强凑合看。。Class Scannerjava.util.ScannerScanner所实现的接口:Closeable, AutoCloseable, Iteratorpublic final class Scanner extends Object implements Iterator, Closeable这是一个可以使用正则表达式来翻译 2013-05-23 00:32:34 · 2637 阅读 · 0 评论