java classloader

java classloader 双亲委托模型 AppClassLoader ExtClassLoader Bootstrap Class Loader URLClassLoader JDK 17 AppClassLoader PlatformClassLoader, 模块加载器 BootClassLoader 不同的 JVM 的实现不同,本文所描述的内容均只限于 Hotspot Jvm. 本文将会从 JDK 默认的提供的 ClassLoader,双亲委托模型,如何自定义 ClassLoader 以及 Java 中打破双亲委托机制的场景四个方面入手去讨论和总结一下。 JDK 默认提供了如下几种 ClassLoader Bootstrap Class Loader, 引导类装载器 虚拟机的内置类加载器 (称为 “bootstrap class loader”) 本身没有父类加载器,但是可以将它用作 ClassLoader 实例的父类加载器。 Bootstrap Class Loader 加载器是由 c++ 实现的 不继承 java.lang.ClassLoader 类, 所以它不属于 “ClassLoader 实例”,也没有办法在 Java 代码中获取到它。 用来加载核心类库,如 java.lang.* 等. 它是在 Java 虚拟机启动后初始化的,它主要负责加载 %JAVA_HOME%/jre/lib, -Xbootclasspath 参数指定的路径以及 %JAVA_HOME%/jre/classes 中的类。 ExtClassLoader, 扩展类装载器 Bootstrp loader 加载 ExtClassLoader, 并且将 ExtClassLoader 的父加载器设置为 Bootstrp loader ExtClassLoader 是用Java写的,具体来说就是 sun.misc.Launcher$ExtClassLoader,ExtClassLoader 主要加载 %JAVA_HOME%/jre/lib/ext,此路径下的所有 classes 目录以及 java.ext.dirs 系统变量指定的路径中类库。 ...

2011-09-09 · 8 min · 1663 words · -

java 反射, reflect

java 反射, reflect http://www.iteye.com/topic/137944 什么是反射 反射的概念是由 Smith 在 1982 年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用, 并在 Lisp 和面向对象方面取得了成绩。其中 LEAD/LEAD++ 、OpenC++ 、MetaXa 和 OpenJava 等就是基于反射机制的语言。最近,反射机制也被应用到了视窗系统、操作系统和文件系统中。 反射本身并不是一个新概念,尽管计算机科学赋予了反射概念新的含义。在计算机科学领域,反射是指一类应用,它们能够自描述和自控制。也就是说,这类应用通过采用某种机制来实现对自己行为的描述 (self-representation) 和监测 (examination) ,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。 什么是Java中的类反射 Reflection 是 Java 程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查,或者说"自审",并能直接操作程序的内部属性和方法。Java 的这一能力在实际应用中用得不是很多,但是在其它的程序设计语言中根本就不存在这一特性。例如,Pascal、C 或者 C++ 中就没有办法在程序中获得函数定义相关的信息。 Reflection 是 Java 被视为动态 (或准动态) 语言的关键,允许程序于执行期 Reflection APIs 取得任何已知名称之 class 的內部信息,包括 package、type parameters、superclass、implemented interfaces、inner classes, outer class, fields、constructors、methods、modifiers,並可于执行期生成instances、变更 fields 內容或唤起 methods。 Java类反射中所必须的类 Java的类反射所需要的类并不多,它们分别是: Field、Constructor、Method、Class、Object,下面我将对这些类做一个简单的说明。 Field类: 提供有关类或接口的属性的信息,以及对它的动态访问权限。反射的字段可能是一个类 (静态) 属性或实例属性,简单的理解可以把它看成一个封装反射类的属性的类。 Constructor类: 提供关于类的单个构造方法的信息以及对它的访问权限。这个类和Field类不同,Field类封装了反射类的属性,而Constructor类则封装了反射类的构造方法。 Method类: 提供关于类或接口上单独某个方法的信息。所反映的方法可能是类方法或实例方法 (包括抽象方法) 。 这个类不难理解,它是用来封装反射类方法的一个类。 ...

2011-09-09 · 5 min · 953 words · -

java static

java static static表示"全局"或者"静态"的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量的概念。 被static修饰的成员变量和成员方法独立于该类的任何对象。也就是说,它不依赖类特定的实例,被类的所有实例共享。只要这个类被加载,Java虚拟机就能根据类名在运行时数据区的方法区内定找到他们。因此,static对象可以在它的任何对象创建之前访问,无需引用任何对象。 用public修饰的static成员变量和成员方法本质是全局变量和全局方法,当声明它类的对象时,不生成static变量的副本,而是类的所有实例共享同一个static变量。 static变量前可以有private修饰,表示这个变量可以在类的静态代码块中,或者类的其他静态成员方法中使用 (当然也可以在非静态成员方法中使用) ,但是不能在其他类中通过类名来直接引用,这一点很重要。private是访问权限限定,static表示不要实例化就可以使用。static前面加上其它访问权限关键字的效果也以此类推。 static修饰的成员变量和成员方法习惯上称为静态变量和静态方法,可以直接通过类名来访问,访问语法为: 类名.静态方法名(参数列表…) 类名.静态变量名 用static修饰的代码块表示静态代码块,当Java虚拟机 (JVM) 加载类时,就会执行该代码块。 static变量 按照是否静态的对类成员变量进行分类可分两种: 一种是被static修饰的变量,叫静态变量或类变量;另一种是没有被static修饰的变量,叫实例变量。两者的区别是: 对于静态变量在内存中只有一个拷贝 (节省内存) ,JVM只为静态分配一次内存,在加载类的过程中完成静态变量的内存分配,可用类名直接访问 (方便) ,当然也可以通过对象来访问 (但是这是不推荐的) 。 对于实例变量,每创建一个实例,就会为实例变量分配一次内存,实例变量可以在内存中有多个拷贝,互不影响 (灵活) 。 静态方法 静态方法可以直接通过类名调用,任何的实例也都可以调用,因此静态方法中不能用this和super关键字,不能直接访问所属类的实例变量和实例方法(就是不带static的成员变量和成员成员方法),只能访问所属类的静态成员变量和成员方法。因为实例成员与特定的对象关联! static代码块 static代码块也叫静态代码块,是在类中独立于类成员的static语句块,可以有多个,位置可以随便放,它不在任何的方法体内,JVM加载类时会执行这些静态的代码块,如果static代码块有多个,JVM将按照它们在类中出现的先后顺序依次执行它们,每个代码块只会被执行一次。 static和final一块用表示什么 static final用来修饰成员变量和成员方法,可简单理解为"全局常量"! 对于变量,表示一旦给值就不可修改,并且通过类名可以访问。 对于方法,表示不可覆盖,并且可以通过类名直接访问。 因为static方法独立于任何实例,因此static方法必须被实现,而不能是抽象的abstract 定义一个类成员,使它的使用完全独立于该类的任何对象。通常情况下,类成员必须通过它的类的对象访问,但是可以创建这样一个成员,它能够被它自己使用,而不必引用特定的实例。在成员的声明前面加上关键字static(静态的)就能创建这样的成员。如果一个成员被声明为static,它就能够在它的类的任何对象创建之前被访问,而不必引用任何对象。你可以将方法和变量都声明为static。static 成员的最常见的例子是main( ) 。因为在程序开始执行时必须调用main() ,所以它被声明为static。 当声明一个对象时,并不产生static变量的拷贝,而是该类所有的实例变量共用同一个static变量。声明为static的方法有以下几条限制: 仅能调用其他的static 方法。 只能访问static数据。 不能以任何方式引用this 或super 可以声明一个static块,Static 块仅在该类被加载时执行一次

2011-09-08 · 1 min · 50 words · -

java 数组 list set, 数组转set

java 数组 list set, 数组转set http://jerval.iteye.com/blog/1001643 //数组->Set String[] strs = {“AA”,“BB”}; Set set2 = new HashSet(Arrays.asList(strs)); System.out.println(set2); //Set->数组 Set set3 = new HashSet(Arrays.asList(“PP”,“OO”)); String[] strSet = new String[set3.size()]; set3.toArray(strSet); System.out.println(Arrays.toString(strSet)); List(interface): 次序是List最重要的特点;它确保维护元素特定的顺序。List为Collection添加了许多方法,使得能够向List中间插入与移除元素(只推荐LinkedList使用)。一个List可以生成ListIterator,使用它可以从两个方向遍历List,也可以从List中间插入和删除元素。 ArrayList: 由数组实现的List。它允许对元素进行快速随机访问,但是向List中间插入与移除元素的速度很慢。ListIterator只应该用来由后向前遍历ArrayList,而不是用来插入和删除元素,因为这比LinkedList开销要大很多。 LinkedList: 对顺序访问进行了优化,向List中间插入与删除得开销不大,随机访问则相对较慢(可用ArrayList代替)。它具有方法addFirst()、addLast()、getFirst()、getLast()、removeFirst()、removeLast(),这些方法(没有在任何接口或基类中定义过)使得LinkedList可以当作堆栈、队列和双向队列使用。 #################################### Set(interface): 存入Set的每个元素必须是唯一的,因为Set不保存重复元素。加入Set的Object必须定义equals()方法以确保对象的唯一性。Set与Collection有完全一样的接口。Set接口不保证维护元素的次序。 HashSet: 为快速查找而设计的Set。存入HashSet的对象必须定义hashCode()。采用散列函数对元素进行排序,这是专门为快速查询而设计的; TreeSet: 保持次序的Set,底层为树结构。使用它可以从Set中提取有序的序列。TreeSet采用红黑树的数据结构进行排序元素; LinkedHashSet: 具有HashSet的查询速度,且内部使用链表维护元素的顺序(插入的次序)。于是在使用迭代器遍历Set时,结果会按元素插入的次序显示。LinkedHashSet内部使用散列以加快查询速度,同时使用链表维护元素的次序,使得看起来元素是以插入的顺序保存的。 需要注意的是,生成自己的类时,Set需要维护元素的存储顺序,因此要实现Comparable接口并定义compareTo()方法。

2011-09-08 · 1 min · 46 words · -

java zip

java zip package com.wiloon.et; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class ZipTest { static final int BUFFER = 2048; static String source = “D:/exported/”; static String destinationPath = “//x.x.x.x/share/xxx/”; static String fileName = “0000-0999.zip”; public static void main(String argv[]) { try { BufferedInputStream origin = null; FileOutputStream dest = new FileOutputStream(destinationPath fileName); ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream( dest)); byte data[] = new byte[BUFFER]; ...

2011-09-06 · 1 min · 141 words · -

loom

loom Oracle 已经停止了异步的JDBC (ADBA) 标准的相关工作。这传达了一个相当明确而又重要的信息: (在Java平台上)fiber 是未来的方向,而异步不是。Oracle 认为异步程序太难写难调,因此全力转向同步的方案 ( 注意这个帖子混用了 fiber 和 lightweight thread 这两个术语,后面的Ron用的术语是 lightweight virtual thread ) On Wednesday, September 18, at Oracle CodeOne Oracle announced that Oracle will stop work on ADBA (Asynchronous Database Access) The Java team’s position is that synchronous code is easier to write, test, debug, maintain, and understand than async code. The only reason to write async code is that threads are so expensive. Project Loom will add fibers, very lightweight threads, to Java. Fibers are so light weight that it is completely practical to spin up as many as you need. So just write first semester CS synchronous code and and execute it on a dedicated fiber. This is much easier than writing async code to do the same task. Synchronous code will use the same JDBC we all know and love. No need to learn a new API. Existing code can be made to work with few if any changes. ...

2011-09-04 · 1 min · 186 words · -

jdk中的jar包, rt.jar ,dt.jar ,tool.jar

jdk中的jar包, rt.jar ,dt.jar ,tool.jar 重点包 rt.jar : 运行时包 dt.jar: dt.jar是关于运行环境的类库 tools.jar: tools.jar是工具类库,编译和运行需要的都是toos.jar里面的类分别是sun.tools.java. ; sun.tols.javac.; charsets.jar: Java 字符集,这个类库中包含 Java 所有支持字符集的字符 cldrdata.jar: http://cldr.unicode.org/ CLDR - Unicode Common Locale Data Repository deploy.jar: deploy.jar是Java部署堆栈的一部分,用于applet和Webstart应用程序。 deploy.jar是Java安装目录的常见部分 - 该文件运行某些产品的安装。 正确设置Java路径后,用户可以执行此文件 (只需双击它或按文件上的Enter键) ,要部署的应用程序将运行其安装程序。 例如。 诺基亚OVI套件通常使用这种部署形式。 作为彼此的JAVA包,如果您将其重命名为ZIP并打开内容,则可以检查包中的类。 dnsns.jar:与 DNS 有关 jaccess.jar: Java Access Bridge is a technology that exposes the Java Accessibility API in a Microsoft Windows DLL, enabling Java applications and applets that implement the Java Accessibility API to be visible to assistive technologies on Microsoft Windows systems. Java Accessibility API is part of Java Accessibility Utilities, which is a set of utility classes that help assistive technologies provide access to GUI toolkits that implement the Java Accessibility API. Java Access Bridge是一种在Microsoft Windows DLL中公开Java Accessibility API的技术,使实现Java Accessibility API的Java应用程序和applet对Microsoft Windows系统上的辅助技术可见。 Java Accessibility API是Java Accessibility Utilities的一部分,它是一组实用程序类,可帮助辅助技术提供对实现Java Accessibility API的GUI工具包的访问。 ...

2011-08-30 · 3 min · 516 words · -

log4e

log4e Log4e是一个免费的Eclipse Plugin,它可帮助你在你的Java工程中快速加入Log; 我们可以在http://log4e.jayefem.de/index.php/Download 网站上下载Log4e最新版本。下载后将相应文件夹拷贝到Eclipse的插件目录下,重新Eclipse,在首选项中会多出一个Log4e选项。 go to http://log4e.jayefem.de/ Eclipse Update URL: http://log4e.jayefem.de/update

2011-08-29 · 1 min · 12 words · -

RxJava

RxJava Reactive Extension (RX) RX在Future和Promise的基础上更进了一步,将单一的事件处理扩展到多个先后相关的事件流处理。举个例子,鼠标拖拽事件,是由一个MouseDown事件加多个MouseMove事件以及一个MouseUp事件构成,Promise处理这种情况需要处理器具有状态记住拖拽的阶段。RX将MouseDown和MouseUp这些事件的处理标准化,并且将拖拽阶段的这一共享状态从业务处理器中抽离,而固化到事件处理流程中。RX抽象了大量的事件操作,使得我们可以将重心放到事件流程建模中,而不是具体的一个接一个事件的处理。共享状态从处理器中抽离也有利于业务处理器的重用以及并发处理。 综上,响应式编程中的事件驱动,要求 对事件建模 对事件流程建模 对事件相关性建模 在那个RxJava刚刚火爆的年代,那是一个荒蛮的年代。我们在异步方面资源匮乏,手头仅有ThreadPool,AsyncTask和Handler这些基础封装的异步库。所以当我们看见RxJava这个新奇的小玩意,当我们看到异步还可以这么简单,轻而易举的解决Concurrency问题。我们当然如获至宝。 而我们现在选择就更多了,无论是Java 8本身提供的CompletableFuture。还是后起之秀Kotlin上的Coroutine,还有Android 上官方提供的LiveData 作者:W_BinaryTree 链接:https://juejin.cn/post/6844903838978146317 来源:稀土掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 RxJava 在 GitHub 主页上的自我介绍是 “a library for composing asynchronous and event-based programs using observable sequences for the Java VM” (一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库) ReactiveX是Reactive Extensions的缩写,一般简写为Rx,最初是LINQ的一个扩展,由微软的架构师Erik Meijer领导的团队开发,在2012年11月开源,Rx是一个编程模型,目标是提供一致的编程接口,帮助开发者更方便的处理异步数据流,Rx库支持.NET、JavaScript和C++,Rx近几年越来越流行了,现在已经支持几乎全部的流行编程语言了,Rx的大部分语言库由ReactiveX这个组织负责维护,比较流行的有RxJava/RxJS/Rx.NET,社区网站是 reactivex.io。 Netflix参考微软的Reactive Extensions创建了Java的实现RxJava,主要是为了简化服务器端的并发。2013年二月份,Ben Christensen 和 Jafar Husain发在Netflix技术博客的一篇文章第一次向世界展示了RxJava。 RxJava也在Android开发中得到广泛的应用。 ReactiveX An API for asynchronous programming with observable streams. A combination of the best ideas from the Observer pattern, the Iterator pattern, and functional programming. ...

2011-08-29 · 1 min · 80 words · -

函数式编程, Functional Programming

函数式编程, Functional Programming 函数式编程已经存在了很长了时间,早在50年代 Lisp 编程语言的介绍中就有提过。如果你有关注近两年里内热门的 Clojure,Scala,Erlang,Haskell,Elixir 等语言的话,其中都有函数式编程的概念。 函数式编程的简要历史 正如我们所说的,早在50年代函数式编程开始之前,Lisp 语言就已经在 IBM 700/7000 系列的科学计算机上运行了。Lisp 引入了很多与我们现在的函数式编程有关的示例与功能,我们甚至可以称 Lisp 是所有函数式编程语言的鼻祖。 这也是函数式编程中最有趣的方面,所有函数式编程语言都是基于相同的 λ演算,这种简单数学基础。 λ演算是图灵完备的,它是一种通用的计算模型,可用于模拟任何一台单带图灵机。它名字中的希腊字母 lambda (λ),被使用在了 lambda 表达式和 lambda 项绑定函数中的变量中。 λ演算是一个极其简单但又十分强大的概念。它的核心主要有两个概念: 函数的抽象,通过引入变量来归纳得出表达式; 函数的应用,通过给变量赋值来对已得出的表达式进行计算; 什么是函数式编程 什么是函数式编程?它是一种编程范式,即一切都是数学函数。函数式编程语言里也可以有对象,但通常这些对象都是恒定不变的 —— 要么是函数参数,要什么是函数返回值。函数式编程语言里没有 for/next 循环,因为这些逻辑意味着有状态的改变。相替代的是,这种循环逻辑在函数式编程语言里是通过递归、把函数当成参数传递的方式实现的。 函数式编程单看上面的理论无疑是无法理解的,所以,需要通过它的一些特点来感受什么是函数式编程 函数是"第一等公民" 所谓"第一等公民" (first class),指的是函数与其他数据类型一样,处于平等地位,可以赋值给其他变量,也可以作为参数,传入另一个函数,或者作为别的函数的返回值。 举例来说,下面代码中的print变量就是一个函数,可以作为另一个函数的参数。 只用"表达式",不用"语句" “表达式” (expression)是一个单纯的运算过程,总是有返回值;“语句” (statement)是执行某种操作,没有返回值。函数式编程要求,只使用表达式,不使用语句。也就是说,每一步都是单纯的运算,而且都有返回值。 原因是函数式编程的开发动机,一开始就是为了处理运算 (computation),不考虑系统的读写 (I/O)。“语句"属于对系统的读写操作,所以就被排斥在外。 当然,实际应用中,不做I/O是不可能的。因此,编程过程中,函数式编程只要求把I/O限制到最小,不要有不必要的读写行为,保持计算过程的单纯性。 没有"副作用” 所谓"副作用" (side effect),指的是函数内部与外部互动 (最典型的情况,就是修改全局变量的值),产生运算以外的其他结果。 函数式编程强调没有"副作用",意味着函数要保持独立,所有功能就是返回一个新的值,没有其他行为,尤其是不得修改外部变量的值. 不修改状态 上一点已经提到,函数式编程只是返回新的值,不修改系统变量。因此,不修改变量,也是它的一个重要特点。 在其他类型的语言中,变量往往用来保存"状态" (state)。不修改变量,意味着状态不能保存在变量中。函数式编程使用参数保存状态,最好的例子就是递归。 引用透明 引用透明 (Referential transparency),指的是函数的运行不依赖于外部变量或"状态",只依赖于输入的参数,任何时候只要参数相同,引用函数所得到的返回值总是相同的。 OO (object oriented,面向对象)是抽象数据,FP (functional programming,函数式编程)是抽象行为。 在java中,函数式编程是通过lambda表达式实现的。 lambada表达式 基本表达形式如下: ...

2011-08-28 · 1 min · 110 words · -

java float,double,decimal

‘java float,double,decimal’ decimal:数字型,128bit,不存在精度损失,常用于银行帐目计算。 (28个有效位) float f = 345.98756f;//结果显示为345.9876,只显示7个有效位,对最后一位数四舍五入。 double d=345.975423578631442d;//结果显示为345.975423578631,只显示15个有效位,对最后一位四舍五入。 注: float和double的相乘操作,数字溢出不会报错,会有精度的损失。 decimal dd=345.545454879…..//可以支持28位,对最后一位四舍五入。 注: 当对decimal类型进行操作时,数值会因溢出而报错。 由于对float或double 的使用不当,可能会出现精度丢失的问题。问题大概情况可以通过如下代码理解: public class FloatDoubleTest { public static void main(String[] args) { float f = 20014999; double d = f; double d2 = 20014999; System.out.println("f=" + f); System.out.println("d=" + d); System.out.println("d2=" + d2); } } 得到的结果如下: f=2.0015E7 d=2.0015E7 d2=2.0014999E7 从输出结果可以看出double 可以正确的表示20014999 ,而float 没有办法表示20014999 ,得到的只是一个近似值。这样的结果很让人讶异。20014999 这么小的数字在float下没办法表示。于是带着这个问 题,做了一次关于float和double学习,做个简单分享,希望有助于大家对java 浮 点数的理解。 关于 java 的 float 和 double ...

2011-07-03 · 2 min · 269 words · -

java 替换 ascii 不可见字符, StringEscapeUtils.escapeJava

“java 替换ascii不可见字符, StringEscapeUtils.escapeJava” StringEscapeUtils.escapeJava StringEscapeUtils.escapeJava String.replaceAll 替换成? my_string.replaceAll("\\p{C}", "?"); https://stackoverflow.com/questions/6198986/how-can-i-replace-non-printable-unicode-characters-in-java StringEscapeUtils 在java.commons.lang3的包中有许多方便好用的工具类,类似于处理字符串的StringUtils,处理日期的DateUtils等等,StringEscapeUtils也是其中的一员。 StringEscapeUtils是在java.commons.lang3的2.0版本中加入的工具类,在3.6版本中被标注为@deprecated,表明在之后的版本中则为过时状态,之后StringEscapeUtils类被移到java.commons.text包下。 功能用途 StringEscapeUtils的主要功能就是为Java,Java Script,Html,XML进行转义与反转义。 escapeJava(String input) / unescapeJava(String unionCodeString) 将输入字符串转为unicode编码 / 将unicode字符串转为Utf-8格式的字符串 escapeHtml4(String input) / unescapeHtml4(String input) 转义/反转义html脚本 escapeEcmaScript(String input) / unescapeEcmaScript(String input) 转义/反转义js脚本 escapeXml(String input) / unescapeXml(String input) 转义/反转义xml脚本 除了列出的几个较常用的方法,还有escapeJson(String input) / unescapeJson(String input)、escapeCsv(String input) / unescapeCsv(String input)等等,可以看一下下面的执行例子,有个直观的认识。 import org.apache.commons.text.StringEscapeUtils; import org.junit.Test; /** * @author liuqian * @date 2018/4/3 16:27 */ public class EscapeTest { @Test public void escapeTest() { System.out.println("转义/反转义Java字符串"); String javaString = "这是Java字符串"; System.out.println(StringEscapeUtils.escapeJava(javaString)); System.out.println(StringEscapeUtils.unescapeJava(StringEscapeUtils.escapeJava(javaString))); System.out.println("-------------------------------------------------------------"); System.out.println("转义/反转义Json字符串"); String jsonString = "{\"keyword\": \"这是Json字符串\"}"; System.out.println(StringEscapeUtils.escapeJson(jsonString)); System.out.println(StringEscapeUtils.unescapeJson(StringEscapeUtils.escapeJson(jsonString))); System.out.println("-------------------------------------------------------------"); //除了html4还有html3等格式 System.out.println("转义/反转义Html字符串"); String htmlString = "加粗字符"; System.out.println(StringEscapeUtils.escapeHtml4(htmlString)); System.out.println(StringEscapeUtils.unescapeHtml4(StringEscapeUtils.escapeHtml4(htmlString))); System.out.println("-------------------------------------------------------------"); //除了xml10还有xml11等格式 System.out.println("转义/反转义xml字符串"); String xmlString = "<xml>\"xml字符串\"</xml>"; System.out.println(StringEscapeUtils.escapeXml10(xmlString)); System.out.println(StringEscapeUtils.unescapeXml(StringEscapeUtils.escapeXml10(xmlString))); System.out.println("-------------------------------------------------------------"); System.out.println("转义/反转义csv字符串"); String csvString = "1997,Ford,E350,\"Super, luxurious truck\""; System.out.println(StringEscapeUtils.escapeCsv(csvString)); System.out.println(StringEscapeUtils.unescapeCsv(StringEscapeUtils.escapeCsv(csvString))); System.out.println("-------------------------------------------------------------"); System.out.println("转义/反转义Java Script字符串"); String jsString = "<script>alert('1111')</script>"; System.out.println(StringEscapeUtils.escapeEcmaScript(jsString)); System.out.println(StringEscapeUtils.unescapeEcmaScript(StringEscapeUtils.escapeEcmaScript(jsString))); } } 结果 转义/反转义Java字符串 \u8FD9\u662FJava\u5B57\u7B26\u4E32 这是Java字符串 ------------------------------------------------------------- 转义/反转义Json字符串 {\"keyword\": \"\u8FD9\u662FJson\u5B57\u7B26\u4E32\"} {\"keyword\": \"这是Json字符串\"} ------------------------------------------------------------- 转义/反转义Html字符串 <strong>加粗字符</strong> 加粗字符 ------------------------------------------------------------- 转义/反转义xml字符串 <xml>&quot;xml字符串&quot;</xml> <xml>"xml字符串"</xml> ------------------------------------------------------------- 转义/反转义csv字符串 "1997,Ford,E350,""Super, luxurious truck""" 1997,Ford,E350,"Super, luxurious truck" ------------------------------------------------------------- 转义/反转义Java Script字符串 <script>alert(\'1111\')<\/script> <script>alert('1111')</script> https://github.com/lq920320/blogs/issues/9

1 min · 160 words · -

jvm

jvm JVM是Java Virtual Machine (Java虚拟机)的缩写 常用jvm 目前市面上普遍使用的JVM大致有三种 Sun公司的HotSpot——绝大多数java开发者都用的是这款,绝对的主力 Oracle公司的JRockit——这款主要用于金融和军事 IBM公司的J9 VM——这款是IBM硬件绑定的,用户也很少 IBM 开源了它开发的 J9 Java 虚拟机 (JVM),并将其贡献给了 Eclipse 基金会,重命名为 Eclipse OpenJ9。J9 是一个高性能可伸缩的 Java 虚拟机,是许多 IBM 企业级软件产品的核心,OpenJ9 可作为 Hotspot 的替代者用于 OpenJDK Java虚拟机四大组成部分 执行引擎(解释器和即时编译器) 类加载器 运行时数据区 垃圾回收器 执行引擎 Execution Engine Java虚拟机的执行引擎主要是用来执行Java字节码。JVM的执行引擎执行字节码通过两种解释器执行的:字节码解释器与模板解释器,运行过程中,可能会触发即时编译 (JIT),涉及到几种即时编译器,下面分别进行介绍。 执行引擎是Java虛拟机核心的组成部分之一。 虚拟机是一个相对于“物理机”的概念,这两种机器都有代码执行能力,其区别是物理机的执行引擎是直接建立在处理器、缓存、指令集和操作系统层面上的,而虚拟机的执行引擎则是由软件自行实现的,因此可以不受物理条件制约地定制指令集与执行引擎的结构体系,能够执行那些不被硬件直接支持的指令集格式。 JVM的主要任务是负责装载字节码到其内部,但字节码并不能够直接运行在操作系统之上,因为字节码指令并非等价于本地机器指令,它内部包含的仅仅只是一些能够被JVM所识别的字节码指令、符号表,以及其他辅助信息。 如果想要让一个Java程序运行起来,执行引擎(Execution Engine)的任务就是将字节码指令解释/编译为对应平台上的本地机器指令才可以。简单来说,JVM中的执行引擎充当了将高级语言翻译为机器语言的译者。 解释器分类 在Java的发展历史里,一共有两套解释执行器,即古老的字节码解释器、现在普遍使用的模板解释器。 字节码解释器:在执行时通过纯软件代码模拟字节码的执行,效率非常低下。 模板解释器:将每一条字节码和一个模板函数相关联,模板函数中直接产生这条字节码执行时的本地机器代码,从而很大程度上提高了解释器的性能。 在HotSpot VM中,解释器主要由Interpreter模块和Code模块构成。 Interpreter模块:实现了解释器的核心功能 Code模块:用于管理HotSpotVM在运行时生成的本地机器指令 JIT编译器(Just In Time Compiler) 就是虚拟机将源代码直接编译成和本地机器平台相关的汇编语言,通过汇编生成机器代码。 现代虚拟机为了提高执行效率,会使用即时编译技术将方法编译成本地机器代码后再执行 Hotspot JIT编译器生成的是汇编代码,保存在方法区的JIT缓存区 本地机器代码不等于机器码,不同平台虚拟机翻译成本地的能识别的指令集,或者说是汇编语言。指令集由不同的架构构成,如:x86指令集 为什么还需要解释器 有些开发人员会感觉到诧异,既然HotSpot VM中已经内置JIT编译器了,那么为什么还需要再使用解释器来“拖累”程序的执行性能呢?比如JRockit VM内部就不包含解释器,字节码全部都依靠即时编译器编译后执行。 首先明确: 当程序启动后,解释器可以马上发挥作用,省去编译的时间,立即执行。编译器要想发挥作用,把代码编译成本地代码,需要一定的执行时间。但编译为本地代码后,执行效率高。 所以: 尽管JRockitVM中程序的执行性能会非常高效,但程序在启动时必然需要花费更长的时间来进行编译。对于服务端应用来说,启动时间并非是关注重点,但对于那些看中启动时间的应用场景而言,或许就需要采用解释器与即时编译器并存的架构来换取一一个平衡点。在此模式下,当Java虛拟器启动时,解释器可以首先发挥作用,而不必等待即时编译器全 部编译完成后再执行,这样可以省去许多不必要的编译时间。随着时间的推移,编译器发挥作用,把越来越多的代码编译成本地代码,获得更高的执行效率。同时,解释执行在编译器进行激进优化不成立的时候,作为编译器的“逃生门” 当虚拟机启动的时候,解释器可以首先发挥作用,而不必等待即时编译器全部编译完成再执行,这样可以省去许多不必要的编译时间。并且随着程序运行时间的推移,即时编译器逐渐发挥作用,根据热点探测功能,将有价值的字节码编译为汇编语言,以换取更高的程序执行效率。 ...

7 min · 1412 words · -