1. 变量是否会自动初始化?
在类定义的field,String的值被赋予NULL,int被赋予0。而在方法内的String,int没有手动赋值会报编译错误The local variable s2 may not have been initialized。
class Test{ int a; //a==0,不论是否为static String s;//s == null,不论是否为static; void func(){ String s2; s2.length();//报错,提示未初始化 s2 == null;//报错,提示未初始化 } }
2. return 语句不要放到finally
因为如果抛出一个runtimeException,而catch没有捕获的话,那么finally中 return值会导致runtimeException被忽略!
static int func(){ int a =1; try{ if(1 ==a ){ throw new RuntimeException(); } throw new IOException(); }catch(IOException e){ }finally{ return 1; } } public static void main(String[] args){ System.out.println(func());//print 1; no exception throws out }
3. 一个类不依赖容器是很重要的。
曾经遇到过一个类,不能直接new ,需要在启动了Tomcat之后的环境里面才能new,导致非常难测试。到后面,还导致无法编写提速开发的工具类(自动生成配置和文件等)!因为需要使用反射执行某些方法获取结果,但是那个方法不是静态方法,需要实例化对象!所以以后我会要求一些类做到与servletContext,httpServlet无关,可以在脱离中间件情况直接newInstance!这里我进一步理解了为什么struts2为什么要与中间件API解耦合了
4. 正则表达式的贪婪匹配,勉强匹配,全占匹配。
例如有字符串 "{name} lives in {village} , which is far from the company."
正则表达式 "\\{.*\\}" 会匹配到 "{name} lives in {village } ",这是贪婪匹配.
正则表达式 "\\{.*?\\}" 会匹配到 "{name}"和"{ village }",这是勉强匹配.
正则表达式 "\\{.*+\\}" 没有匹配项,这是possessive匹配(不知道怎么翻译了,理解成”全占匹配“也可以吧)。
算法
3种匹配的匹配算法不一样。
约定概念:
目标字符串a:被匹配的字符串,如上面所说的"{name} lives in {village} , which is far from the company."
读入字符串r:算法中需要用到的临时字符串变量
a. 贪婪匹配
1) 将整个目标字符串r读入,使读入字符串r=a,如果能够匹配,则返回SUCCESS,退出,否则转入2)。
2) 如果r的长度>=1:
去掉r末尾的一个字符,如果剩余的字符串能够匹配,则返回SUCESS,退出,否则转入2)。
如果此时r的长度为0:
如果""能匹配正则表达式,则返回SUCCESS,退出,否则返回FAIL,退出。
3) 如果1),2)之后返回SUCCESS,那么去掉a中的r部分,使 a = a - r, r = "",重新进入1)
b. 勉强匹配
与贪婪相反
这里为了表达清晰,在引入一个临时变量b
1)将读入字符串r置为"",使b=a, 如果空字符串能够匹配,则返回SUCESS,退出,否则转入2)
2)如果r的长度<a的长度
b移出开始的字符,放入r的末尾,如果r能够匹配,返回SUCESS,退出,否则转入2)。
如果r的长度==a的长度
如果r能够匹配,返回SUCESS,退出,否则返回FAILURE,退出
3)如果1),2)之后返回SUCCESS,那么去掉a中的r部分,使 a = a - r, r = "",b="",重新进入1)
c.全占匹配
这个很简单,相当于贪婪的第一步
1)将整个目标字符串r读入,使读入字符串r=a,如果能够匹配,则返回SUCCESS,退出,否则返回FAILURE。
对于全占匹配,它只匹配一次——整个匹配,就像名字一样。个人觉得它没有什么存在的意义,贪婪正则表达式使用^...$不就可以取代全站匹配了吗?
Differences Among Greedy, Reluctant, and Possessive Quantifiers
[QUOTE from http://docs.oracle.com/javase/tutorial/essential/regex/quant.html ]
Greedy quantifiers are considered "greedy" because they force the matcher to read in, or eat, the entire input string prior to attempting the first match. If the first match attempt (the entire input string) fails, the matcher backs off the input string by one character and tries again, repeating the process until a match is found or there are no more characters left to back off from. Depending on the quantifier used in the expression, the last thing it will try matching against is 1 or 0 characters.
The reluctant quantifiers, however, take the opposite approach: They start at the beginning of the input string, then reluctantly eat one character at a time looking for a match. The last thing they try is the entire input string.
Finally, the possessive quantifiers always eat the entire input string, trying once (and only once) for a match. Unlike the greedy quantifiers, possessive quantifiers never back off, even if doing so would allow the overall match to succeed.
按照官方文档的说法,贪婪是从右往左吃,勉强是从左往右吃,全占是一次吃完!
5. Class.getResource和ClassLoader.getResource的相对路径的基础路径不一样
前者是class本身所在的路径,而后者是classpath。前者有绝对路径概念,后者只有相对路径概念。
package lgc.tools.struts2;
public class ConventionUtil {
public static void p(Object o){
System.out.println(o);
}
public static void main(String[] args) throws Exception{
//获取类的所在的路径
p(ConventionUtil.class.getResource(""));//file:/E:/workspace/m4/web/WEB-INF/classes/lgc/tools/struts2/
//获取类的所在的根路径,即排除package的路径,或者说是classpath
p(ConventionUtil.class.getResource("/"));//file:/E:/workspace/m4/web/WEB-INF/classes/
//以类的所在的路径为基础路径,查找相对于基础路径的jsp_template.jsp文件
p(ConventionUtil.class.getResource("jsp_template.jsp"));//file:/E:/workspace/m4/web/WEB-INF/classes/lgc/tools/struts2/jsp_template.jsp
//通过绝对路径查找jsp_template.jsp文件
p(ConventionUtil.class.getResource("/lgc/tools/struts2/jsp_template.jsp"));//file:/E:/workspace/m4/web/WEB-INF/classes/lgc/tools/struts2/jsp_template.jsp
//classpath路径
p(ConventionUtil.class.getClassLoader().getResource(""));//file:/E:/workspace/m4/web/WEB-INF/classes/
//没有绝对路径概念
p(ConventionUtil.class.getClassLoader().getResource("/"));//null
//相对于classpath路径查找jsp_template.jsp文件
p(ConventionUtil.class.getClassLoader().getResource("lgc/tools/struts2/jsp_template.jsp"));//file:/E:/workspace/m4/web/WEB-INF/classes/lgc/tools/struts2/jsp_template.jsp
}
}
6. String replace与replaceAll, 不能见名知意
1) replace(CharSequence a, CharSequence b)
是直接全文搜索,直接将所有与第一个参数相等的字符串替换为第二个参数
public String replace(CharSequence target, CharSequence replacement) { return Pattern.compile(target.toString(), Pattern.LITERAL).matcher( this).replaceAll(Matcher.quoteReplacement(replacement.toString())); }
2) replaceAll(regex,replacement)的第一个参数是正则表达式,所有符合正则表达式的子字符串都被替换成replacement,replacement也不是普通字符串,它可以以$0~$8方式引用被匹配字符串的分组,如果你期望replacement是个普通字符串,必须对replacement中的$和\进行转义,以免被JAVA误认为引用分组,转义方法如下
replacement = replacement.replaceAll("\\\\","\\\\\\\\").replaceAll("\\$", "\\\\\\$");
public String replaceAll(String regex, String replacement) { return Pattern.compile(regex).matcher(this).replaceAll(replacement); }
7 encoding
字符集(Charset):是一个系统支持的所有抽象字符的集合。字符是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。
字符编码(Character Encoding):是一套法则,使用该法则能够对自然语言的字符的一个集合,与数字进行配对。
UTF-8,UTF-16,GKB,ISO88559-1都是字符编码,它们0-127配对的字符都是一致的,除此之外配对的规则都不一样,这是产生乱码的根本原因。
例如"中文"这两个字的UTF-8编码是E4 B8 AD E6 96 87,那么当使用UTF-8去解析数字E4 B8 AD E6 96 87的话,会得出“中文”两个字,但是当使用GBK去解析的话,就成了乱码,因为数字E4 B8 AD E6 96 87在GBK的编码规则中代表的字符和UTF-8是不一样的,通常会匹配到一些极少见的字符,这就造成了所谓的乱码现象。
java字符串是以UTF-16的编码方式保存在内存中。getBytes("")和new String(byte[],"")是最常用的转码API。
byte[] a = str.getBytes("charsetName")会将内存中的字符串由UTF-16编码转换为charsetName的编码格式,存放在数组a中。
String s = new String (byte[] ,"charsetName");是getBytes的逆过程,由charsetName编码转换为UTF-16,保存在内存中。
后面我打算写篇博文详细讲讲编码,这里就主要说个原理吧。避免字符串乱码在不同的机器节点传输一个极其有效的方法是将中文字符转换\uxxxx的形式,那么字符串完全变成了unicode的形式(只是unicode形式,unicode是字符集,不是编码!),只包含编码为0-127的字符,不可能出现乱码问题。这带来的代价是,
代价1 需要在发送方将在字符串变成unicode形式
例如要发送 "abc中文",首先转换成abc\u4e2d\u6587,再发送。调用toUnicodeString("abc中文")即可转换为abc\u4e2d\u6587
public static String toUnicodeString(String s){ StringBuilder strb = new StringBuilder(); char[] c = s.toCharArray(); for(int i=0,len=c.length;i<len;i++){ if(c[i] < 128){ strb.append(c[i]); }else{ strb.append("\\u"); String hex = Integer.toHexString(c[i]); if(hex.length()<4){ int padLen = 4-hex.length();//需要左补齐的0 for(int k=0;k<padLen;k++){ hex = "0" + hex; } } strb.append(hex); } } return strb.toString(); }
代价2 需要在接受方法将unicode形式的字符串转换成原来的字符串
例如收到abc\u4e2d\u6587,就转换为"abc中文"。调用parseUnicodeString("abc\u4e2d\u6587")即可转换为"abc中文"。
public static String parseUnicodeString(String s){ StringBuilder rtn = new StringBuilder(); for(int i=0,len=s.length();i<len;i++){ char c = s.charAt(i); if(c=='\\'){ i++; char c1 = s.charAt(i); if(c1 == 'u'){ try{ char c_chinese = (char) Integer.parseInt(s.substring(i+1,i+1+4),16); rtn.append(c_chinese); i += 4; }catch(Exception e){ throw new RuntimeException("parseUnicodeString出错",e); } }else{ rtn.append(c).append(c1); } }else{ rtn.append(c); } } return rtn.toString(); }
备注:以上两个方法已经经历实际环境磨练,暂时没有错误。理解上面的两个方法,首先要理解好,JAVA的一个字符的在内存中的保存,是使用两个BYTE存放一个字符UTF-16编码(如果不够则使用4个BYTE,大部分情况2个BYTE)。
8 禁止直接访问JSP小技巧
如果不想浏览器能直接访问jsp文件,可以考虑把jsp文件都放到WEB-INF下,然后在中间层某个类(servlet,action等)使用request,getRequestDispatcher转向访问。
相关推荐
### 阿里内部资料——Java开发杂项:多线程并发详解 #### 一、远程调试JVM启动参数解析 在阿里巴巴内部资料中,提到了进行Java远程调试时所用到的关键JVM启动参数。这包括了`-Xdebug`、`-Xrunjdwp`等选项,具体...
"java-utils:杂项 Java 实用程序"是一个包含多种实用工具类的Java库,它为开发者提供了方便快捷的代码片段,以解决常见的编程任务。这个库可能是由dbj开发的,其目标是提高代码的可复用性和效率,减少开发时间。 在...
一类是实现投影,摄像系统(直接图像对齐设置匹配主要GNImageAligner,ProjectiveTransformer,ProjectiveGainBiasTransformer,ProCamTransformer和ReflectanceInitializer),以及在JavaCV类杂项功能。
JavaCV 提供了在计算机视觉领域的封装库,包括:OpenCV、ARToolKitPlus、libdc1394 2.x 、PGR FlyCapture和FFmpeg。此外,该工具可以很容易地使用Java平台的功能。...JavaCV 类杂项功能。 标签:JavaCV
在Java开发过程中,处理Unicode表情符号(Emoji)可能是一项挑战,因为并非所有Java API都原生支持它们。这时,第三方库如"emoji-java"就显得非常有用。这个库由vdurmont开发,专为Java提供了方便的方式来解析、验证...
### 八、Miscellaneous(杂项) - **网络编程**:学习如何使用Java进行网络编程,包括HTTP请求、WebSocket通信等。 - **操作系统交互**:掌握如何在Java程序中调用操作系统命令或与操作系统交互。 - **多媒体**:...
GraphQL的Java实现——graphql-java,使得Java开发者能够轻松地在后端集成GraphQL服务。 ### GraphQL的基本概念 1. **Schema**: GraphQL服务的核心是Schema,它定义了客户端可以查询和修改的数据类型、字段以及...
在Java开发中,有一个名为`User-Agent Utilities`的库,由Harald Walker开发,其版本号可能为2a6db83,这正是我们要讨论的焦点。 这个库提供了一种简单而有效的方式来分解和理解User-Agent字符串。它包含了对常见...
1. 多种编程语言的库:如C++、Python、Java等,每种语言可能有多个不同的库。 2. 源代码和编译后的二进制文件:源代码供开发者阅读和修改,二进制文件用于实际应用。 3. 文档和示例:提供库的使用说明,以及如何在...
Java和JavaScript库之间的交互是软件开发中的一个重要主题,特别是在构建多平台应用或增强网页功能时。Java和JavaScript作为两种不同的编程语言,它们各自在特定领域有着优势:Java以其强大的后端处理能力,而...
"Java开发-其它杂项"标签表明这个库属于Java开发领域,但可能不是Java标准库的一部分,而是开发者社区贡献的一种扩展或特定用途的工具。"其它杂项"可能暗示这个库是针对特定问题域的解决方案,可能不适用于所有Java...
5. **misc**、**dist**:可能包含了一些杂项文件和发布相关的文件,如配置文件、示例脚本或者打包后的库文件。 6. **src**:源代码目录,其中包含了smslib库的所有Java源代码,通过阅读源码,开发者可以深入理解...
除了上述内容,"其余杂项"可能涵盖了许多其他细节,比如资源管理(如图片、音频)、系统兼容性检查、设置选项的保存和加载、以及屏幕保护程序的激活和退出逻辑。例如,你可能需要获取系统的屏幕分辨率来适应不同的...
8. `misc`:这个目录可能包含了各种杂项文件,可能包括示例代码、配置文件或其他辅助资源。 9. `dist`:通常存放的是软件的打包文件,可能包含了可执行的jar包或者其他分发形式。 10. `src`:源代码目录,这里包含...
标题 "Some java projects:杂项java项目-开源" 暗示了这是一些与Java编程相关的开源项目,主要用于展示算法及其具体实现。在开源软件领域,开发者通常会分享他们的代码,以便其他人学习、改进或在自己的项目中使用。...
八皇子leetcode 编码实践 大整数的算术运算,格式为字符串。 Column和Interger之间的转换。 . 找出因子的尾随零的数量。 () 评估字符串表达式,它与单个数字正...杂项container_of(ptr,类型,成员) 人工智能 并发
usb4java跨平台的基于 libusb 1.0 开发的 Java USB 类库,通过 usb4java-javax extension 支持 javax-usb standard (JSR-80) 开发。 平台环境支持: Linux (x86 32/64 bit, ARM 32 bit) OS X (x86 32/64 ...
- **利用`stegsolve`工具**:`stegsolve`是一个基于Java的图像隐写分析工具,专门设计用来提取图像中的隐藏信息。 #### 2. Unicode 编码识别与解码 - **Unicode 编码**:Unicode是一种国际编码标准,支持世界上几乎...
标题“jmisc:杂项Java的东西”和描述“杂项Java的东西”暗示这是一个关于Java编程语言的项目,可能包含各种工具、库或者示例代码,用于解决不同场景下的问题。由于没有具体的文件列表,我们将根据Java的一般特性、...