Java JNI

Java JNI http://blog.csdn.net/u_xtian/article/details/6033963 我们知道Java是一个运行在虚拟机里面的高级的编程语言,如果要调用系统的动态链接库的话,就要先声明native修饰的方法(类似接口里面的方法),再由C/C++程序来实现(类似实现接口里的方法)。这样Java调用这些native方法就相当于调用了C/C++里面实现了的方法。通常我们把这种机制叫做JNI(Java NativeInterfac),即Java 本地编程接口 Android也同理,要学会在Android上进行NDK开发,首先我们到打好java JNI的基础。现在我们暂时把Android开发丢到一边先,试试在Java之下编译一个C动态链接库,再用Java程序调用。 1)先来个最简单的打印HelloWorld例子: Java代码(HelloJni.java): import java.util.*; public class HelloJni{ static{ System.loadLibrary(“hello”); } public native static void sayHello(); public static void main(String [] args) { HelloJni.sayHello(); } } 生成头文件(HelloJni.h): 先javac HelloJni.java编译你的Java源码,再javah–jni HelloJni生成所需的头文件 头文件内容是这样的: /* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class HelloJni */ #ifndef _Included_HelloJni #define _Included_HelloJni #ifdef __cplusplus extern “C” { #endif JNIEXPORT void JNICALL Java_HelloJni_sayHello (JNIEnv *, jclass); ...

2014-04-14 · 5 min · 1039 words · -

System.load System.loadLibrary

‘System.load System.loadLibrary’ System.load 和 System.loadLibrary详解 分类: Java 2008-11-06 23:21 16051人阅读 评论(4) 收藏 举报 jniwindowsjvm平台pathsystem System.load 和 System.loadLibrary详解 1.它们都可以用来装载库文件,不论是JNI库文件还是非JNI库文件。在任何本地方法被调用之前必须先用这个两个方法之一把相应的JNI库文件装载。 2.System.load 参数为库文件的绝对路径,可以是任意路径。 例如你可以这样载入一个windows平台下JNI库文件: System.load(“C://Documents and Settings//TestJNI.dll”);。 System.loadLibrary 参数为库文件名,不包含库文件的扩展名。 例如你可以这样载入一个windows平台下JNI库文件 System. loadLibrary (“TestJNI”); 这里,TestJNI.dll 必须是在java.library.path这一jvm变量所指向的路径中。 可以通过如下方法来获得该变量的值: System.getProperty(“java.library.path”); 默认情况下,在Windows平台下,该值包含如下位置: 和jre相关的一些目录 程序当前目录 Windows目录 系统目录 (system32) 系统环境变量path指定目录 4.如果你要载入的库文件静态链接到其它动态链接库,例如TestJNI.dll 静态链接到dependency.dll, 那么你必须注意: 如果你选择 System.load(“C://Documents and Settings// TestJNI.dll”); 那么即使你把dependency.dll同样放在C://Documents and Settings//下,load还是会因为找不到依赖的dll而失败。因为jvm在载入TestJNI.dll会先去载入TestJNI.dll所依赖的库文件dependency.dll,而dependency.dll并不位于java.library.path所指定的目录下,所以jvm找不到dependency.dll。 你有两个方法解决这个问题: 一是把C://Documents and Settings//加入到java.library.path的路径中,例如加入到系统的path中。二是先调用 System.load(“C://Documents and Settings// dependency.dll”); 让jvm先载入dependency.dll,然后再调用System.load(“C://Documents and Settings// TestJNI.dll”); 如果你选择 System. loadLibrary (“TestJNI”); 那么你只要把dependency.dll放在任何java.library.path包含的路径中即可,当然也包括和TestJNI.dll相同的目录。

2014-04-11 · 1 min · 69 words · -

Jode

Jode http://moonights.iteye.com/blog/568886 Jode介绍 源码开放的JODE是全球最大的开源项目网站Sourceforge.net的成员,在所有的JAVA反编译器中,JODE的反编译效果是最好的,尤其是对付一些常见的加密手段,例如混淆技术等,更是出类拔粹。JODE本身也是纯JAVA开发的,最近越来越多的JAVA反编译软件也选择JODE来做它们的核心引擎,例如JCavaj Java Decompiler、BTJ (Back To Java)、jEdit’s JavaInsight plugin等。JODE是一个可运行的JAR文件,在windows环境下双击即可运行。 Jode Eclipse插件安装 顺序点击Eclipse上的==>help ==> Software Updates ==> Find and Install ==> Search for new features to install, 单击"New Remote Site…", 在Name中输入Jode Decompliter在URL栏输入 [http://www.technoetic.com/eclipse/update> 然后下一步,就可以看到"Jode Decompiler"了,选上并单击Finish就开始自动到相应的官网上去下载安装了。安装好后,可以在Window ==> Preferences… ==> Java ==](http://www.technoetic.com/eclipse/update> 然后下一步,就可以看到"Jode Decompiler"了,选上并单击Finish就开始自动到相应的官网上去下载安装了。安装好后,可以在Window ==> Preferences… ==> Java ==) Jode Decompiler选项卡。 安装好了再设置一下文件关联就可以了,Window => Preferences… => General => Editors => File Associations找到"*.class"在"Associated editors"里面可以看到"Jode class file viewer"选中它再单击Default按钮就OK了 3.Jode的使用 其实之所以要使用Jode就是因为我们往往只有Java的class字节码文件却没有源文件,这时就只有进行反编译了,在Eclipse中我们通常为了查看一个class文件的源代码,必须将它与源文件相关联。而如果我们安装了Jode插件,那么就不用去苦苦寻找源文件了,直接反编译就OK (虽然有时会报出一堆的错误@_@) 。要注意的是Jode只认识.jar文件 (不支持war文件,因此如果是war文件,你因该先将之解压然后打包成.jar包) 。 首先将你要反编译的class文件利用Java自带的jar命令将class文件打包成.jar包,然后导入到你的Eclipse的Project中去,接着就可以展开刚才导入的jar包,查看class文件相应的源文件了。

2014-04-11 · 1 min · 71 words · -

Java中 goto

Java中 goto http://lavasoft.blog.51cto.com/62575/178997/ Java语言中goto是保留关键字,没有goto语句,也没有任何使用goto关键字的地方。 Java中也可在特定情况下,通过特定的手段,来实现goto的功能。显然Java不愿意开发者随意跳转程序。下面解释两个特定: 特定情况: 只有在循环体内,比如for、while语句 (含do…while语句) 中。 特定手段: 语句标签和循环控制关键字break、continue,语法格式是: break/continue 语句标签。 一、break、continue和语句标签 语句标签 语句标签的语法是: 标签名: 语句标签可以定义在方法体内的最后一条语句之前即可。但是语句标签实际使用的机会是与break和continue结合使用的,而break和continue是和循环语句结合使用的,因此实际上语句标签的使用也是和循环紧密结合的。 语句标签在被使用的情况,只能定义在循环迭代语句之前,否则编译出错! 因此,有意义、可使用的标签含义是: 指定循环语句的标识! break、continue语句单独使用 单独使用情况下: break语句作用是结束当前的循环迭代体,进而执行剩余的语句。 continue语句的作用是结束本次迭代过程,继续执行下一轮迭代。 break、continue语句结合语句标签的使用 为什么需要语句标签呢? 原因是因为程序可能有循环的嵌套,当多层循环嵌套时候,有时候需要一次跳出多级循环,这种情况下就需要结合语句标签才能实现此功能了。 带标签使用情况下: break中断并跳出标签所指定循环,continue跳转到标签指定的循环处,并继续执行该标签所指定的循环。 为了说明情况,看看下面的例子: import java.util.Random; /** 语句标签测试 @author leizhimin 2009-7-16 11:43:08 */ public class TestLable { public static void main(String[] args) { outer: for (int i = 0; i < 10; i++) { System.out.println("\nouter_loop:" + i); inner: for (int k = 0; i < 10; k++) { ...

2014-04-11 · 2 min · 359 words · -

OutOfMemoryError, StackOverflowError

OutOfMemoryError, StackOverflowError 这是IGT笔试的题目,分别写出可以造成两种错误的代码。由于之前测试过HashMap的容量的时候出现过内存不足的错误,所以能写出来,但StackOverflowError没什么印象了。 回来查了下StackOverflowError的资料,在德问社区上有人发帖子java产生StackOverflowError的原因是什么?询问: 请问java.lang.StackOverflowError产生的原因有什么? 已知的有死循环,循环的嵌套层数达到了环境的设定值 谢谢 有人回复说: 死循环本身是不会StackOverflow的,只有无限递归的时候会出现。原则上循环嵌套次数本身是没有限制的,限制的是占用的栈空间,如果你的函数里定义了很多很多变量,栈空间就会用完得比较快。 还有人讲的更详细: JVM里会有两种StackOverflowError, 一种是对应JVM stack, 一种是对应Native Method stack. 我们一般说的都是JVM stack. 每一个JVM线程维护自己的JVM stack. JVM stack里面存放 JVM栈帧. 栈帧中存放 数据和中间结果(本地变量数组, 操作符栈, 和对runtime 常量池的引用). 这些数据都比较小(对象都在堆中, 栈帧仅存放对象引用), 所以想单纯通过 在栈帧中存放大数据的方法 去引入StackOverflowError, 基本是不现实的.一般都是因为方法调用嵌套层数过大. http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html#jvms-2.5.2 JVM stack的大小是可以调节的, sun的windows jvm6 x64,jvm栈默认大小为1024k.可以通过-Xss1024k来调节. http://www.oracle.com/technetwork/java/hotspotfaq-138619.html#threads_oom 另外,在oracle的docsChapter 2. The Structure of the Java Virtual Machine中,有如下解释: Java Virtual Machine Stacks The following exceptional conditions are associated with Java Virtual Machine stacks: If the computation in a thread requires a larger Java Virtual Machine stack than is permitted, the Java Virtual Machine throws a StackOverflowError. ...

2014-04-09 · 2 min · 379 words · -

ByteArrayInputStream ByteArrayOutputStream

ByteArrayInputStream ByteArrayOutputStream http://blog.csdn.net/rcoder/article/details/6118313 bytejdkclassstream存储socket 第一次看到ByteArrayOutputStream的时候是在Nutch的部分源码,后来在涉及IO操作时频频发现这两个类的踪迹,觉得确实是很好用,所以把它们的用法总结一下。 ByteArrayOutputStream的用法 以下是JDK中的记载: public class ByteArrayOutputStream extends OutputStream 此类实现了一个输出流,其中的数据被写入一个 byte 数组。缓冲区会随着数据的不断写入而自动增长。可使用 toByteArray()和 toString()获取数据。 关闭 ByteArrayOutputStream 无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何IOException。 我的个人理解是ByteArrayOutputStream是用来缓存数据的 (数据写入的目标 (output stream原义) ) ,向它的内部缓冲区写入数据,缓冲区自动增长,当写入完成时可以从中提取数据。由于这个原因,ByteArrayOutputStream常用于存储数据以用于一次写入。 实例: 从文件中读取二进制数据,全部存储到ByteArrayOutputStream中。 FileInputStream fis=new FileInputStream(“test”); BufferedInputStream bis=new BufferedInputStream(fis); ByteArrayOutputStream baos=new ByteArrayOutputStream(); int c=bis.read();//读取bis流中的下一个字节 while(c!=-1){ baos.write(c); c=bis.read(); } bis.close(); byte retArr[]=baos.toByteArray(); ByteArrayInputStream的用法 相对而言,ByteArrayInputStream比较少见。先看JDK文档中的介绍: public class ByteArrayInputStreamextends InputStreamByteArrayInputStream 包含一个内部缓冲区,该缓冲区包含从流中读取的字节。内部计数器跟踪 read 方法要提供的下一个字节。 关闭 ByteArrayInputStream 无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException。 构造函数: ByteArrayInputStream(byte[] buf) 注意它需要提供一个byte数组作为缓冲区。 与大部分Inputstream的语义类似,可以从它的缓冲区中读取数据,所以我们可以在它的外面包装另一层的inputstream以使用我们需要的读取方法。 个人认为一个比较好的用途是在网络中读取数据包,由于数据包一般是定长的,我们可以先分配一个够大的byte数组,比如byte buf[]=new byte[1024]; 然后调用某个方法得到网络中的数据包,例如: Socket s=…; DataInputStream dis=new DataInputStream(s.getInputStream()); ...

2014-04-04 · 1 min · 85 words · -

java 内部类, 静态内部类, inner class

java 内部类, 静态内部类, inner class 内部类 public class OuterClass { private String name; private int age; class InnerClass { public InnerClass(){ name = "mark"; age = 20; } public void echo() { System.out.println(name + " " + age); } } } 问题思考 上面这个很简单的例子中,也包含了很多应该思考的问题: 内部类如何被实例化? 内部类能否改变外围类的属性,两者之间又是什么一种关系? 内部类存在的意义是什么? 在回答这三个问题之前,必须要明确一个点,那就是内部类是依附于外围类而存在的,其实也就是内部类存在着指向外围类的引用。明白了这个之后,上面的问题就好解答了。 实例化与数据访问 内部类与外围类之间形成了一种联系,使得内部类可以无限制地访问外围类中的任意属性。 正如上面的例子中,InnerClass内部可以随意访问OuterClass中的private属性。 同样的,因为内部类依赖与外围类的存在,所以无法在外部直接将其实例化,而是必须先实例化外围类,才能够实例化内部类 (注意,在外围类的成员方法里仍然是可以直接实例化内部类的): public static void main(String[] args) { InnerClass inner = new OuterClass().new InnerClass(); inner.echo(); } 复制代码使用外围类的.new来创建外部类。 我们也知道,内部类和外围类的联系是通过内部类所持有的外部类的引用来实现的,想要获取这个引用,可以使用外围类的.this来实现,可以参考下面这个测试用例 public class OuterClass { private String name; private int age; class InnerClass { public InnerClass(){ name = “mark”; age = 20; } public void echo() { System.out.println(name + " " + age); } public OuterClass getOuter() { return OuterClass.this; } } ...

2014-04-04 · 5 min · 876 words · -

HashMap遍历

HashMap遍历 HashMap 遍历 // 1 Map map = new HashMap(); Iterator iter = map.entrySet().iterator(); while (iter.hasNext()) { Map.Entry entry = (Map.Entry) iter.next(); Object key = entry.getKey(); Object val = entry.getValue(); } // 2 Map map = new HashMap(); Iterator iter = map.keySet().iterator(); while (iter.hasNext()) { Object key = iter.next(); Object val = map.get(key); } 前一种性能好些. 第一种可以把 key value 同时取出,第二种还得需要通过 key 取一次 value,效率较低。 ...

2014-04-02 · 1 min · 170 words · -

JAVA获取时间戳

JAVA获取时间戳 http://tangmingjie2009.iteye.com/blog/1543166 JAVA时间戳 目前获取毫秒值大概有下面三种方法 Java代码 收藏代码 //方法 一 System.currentTimeMillis(); //方法 二 Calendar.getInstance().getTimeInMillis(); //方法 三 new Date().getTime(); 最近做监控系统,发现代码中有前两种方法,然后突然有了一个想法,到底哪个更快呢? 然后做了如下实验: Java代码 收藏代码 import java.util.Calendar; import java.util.Date; public class TimeTest { private static long _TEN_THOUSAND=10000; public static void main(String[] args) { long times=1000*_TEN_THOUSAND; long t1=System.currentTimeMillis(); testSystem(times); long t2=System.currentTimeMillis(); System.out.println(t2-t1); testCalander(times); long t3=System.currentTimeMillis(); System.out.println(t3-t2); testDate(times); long t4=System.currentTimeMillis(); System.out.println(t4-t3); } public static void testSystem(long times){//use 188 for(int i=0;i<times;i++){ long currentTime=System.currentTimeMillis(); } } public static void testCalander(long times){//use 6299 for(int i=0;i<times;i++){ long currentTime=Calendar.getInstance().getTimeInMillis(); } } public static void testDate(long times){ ...

2014-04-01 · 1 min · 107 words · -

SAX 解析和生成XML文档

SAX解析和生成XML文档 SAX解析和生成XML文档 分类: 【xml】 2013-09-24 22:37 2207人阅读 评论(6) 收藏 举报 生成解析xmljavasax 目录? 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本人声明。否则将追究法律责任。 作者: 永恒の_☆ 地址: http://blog.csdn.net/chenghui0317/article/details/11990891 一、前言 SAX操作xml是基于事件来完成的,自己只负责调用解析的方法,然后具体解析操作都是交给DefaultHandler处理者来完成的,总的来说使用SAX解析和生成xml文档还是比较方便的 。 二、准备条件 因为SAX是jdk自带的解析方式,所以不用添加jar包引用。 三、使用SAX实战 解析xml文档 实现思路: <1>先由SAXParserFactory这个工厂的实例生产一个SAXParser解析器; <2>然后根据读取的xml路径,传递给SAXParser这个解析器,再调用parse()方法; <3>在parse()方法中需要传递DefaultHandler这个类的扩展类的实例,因为它才会真正去一步步去解析xml文档的; <4>在DefaultHandler扩展类中需要重写startDocument(),endDocument()等等方法,因为他们方法内部有返回的具体文档的结果。 具体代码如下: print? import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import javax.xml.transform.OutputKeys; import javax.xml.transform.Result; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.sax.SAXTransformerFactory; import javax.xml.transform.sax.TransformerHandler; import javax.xml.transform.stream.StreamResult; import org.xml.sax.Attributes; ...

2014-04-01 · 7 min · 1333 words · -

4款json的java类库, FastJson

4款json的java类库, FastJson JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。 易于人阅读和编写。同时也易于机器解析和生成。 它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一个子集。 JSON采用完全独立于语言的文本格式,这些特性使JSON成为理想的数据交换语言。 下面介绍四款处理json的java类库: Json-lib、Gson、Jackson、Fastjson FastJson Fastjson是一个Java语言编写的JSON处理器,由阿里巴巴公司开发。网址: https://github.com/alibaba/fastjson maven依赖配置: <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.79</version> </dependency> 示例: 复制代码 public static String bean2Json(Object obj){ return JSON.toJSONString(obj); } VO vo = JSON.parseObject("...", VO.class);``` Json-lib JSON-lib is a java library for transforming beans, maps, collections, java arrays and XML to JSON and back again to beans and DynaBeans. 官网: http://json-lib.sourceforge.net/ ...

2014-03-31 · 5 min · 923 words · -

apache commons StringUtils

apache commons StringUtils http://vipcowrie.iteye.com/blog/1513017 org.apache.commons.lang.StringUtils StringUtils是apache commons lang库 (http://commons.apache.org/lang)旗下的一个工具类,提供了很多有用的处理字符串的方法,本文不打算把所有的方法都介绍一遍,我会介绍一些精选的常用的给大家。 目前StringUtils有两个版本可用,分别是较新的org.apache.commons.lang3.StringUtils和较老的org.apache.commons.lang.StringUtils,他们有比较大的区别,前者需要JAVA 5,我想这个应该是我们希望使用的。 public static boolean equals(CharSequence str1,CharSequence str2) 我们就先从最简单的方法equals开始,和你想的一样,他需要两个字符串参数,当相同的时候返回true,否则返回false。 但是java.lang.String已经有现成的比较完美的equals方法了,为何我们还需要一个第三方的实现呢? 这个问题很好,让我们来看看下面这些代码,看看有何问题? Java代码 收藏代码 public void doStuffWithString(String stringParam) { if(stringParam.equals(“MyStringValue”)) { // do stuff } } 这个可能有NullPointerException出现,那么有几个办法处理: Java代码 收藏代码 public void safeDoStuffWithString1(String stringParam) { if(stringParam != null && stringParam.equals(“MyStringValue”)) { // do stuff } } public void safeDoStuffWithString2(String stringParm) { if(“MyStringValue”.equals(stringParam)) { // do stuff } } 我本人不喜欢上面的两个方法,第一个看起来太臃肿,第二个看起来像错误的。这里我们就可以用一些StringUtils类了,这个类提供的equals方法是空指针安全的,不用担心传递给他的是什么参数,他不会抛出空指针异常,这样写: Java代码 收藏代码 public void safeDoStuffWithString3(String stringParam) { if(StringUtils.equals(stringParam,“MyStringValue)) { // do stuff } } 这个是我个人的喜好,但是这个确实看起来比较简单易读。前面的两个方法虽然么有什么问题,但是我想StringUtils.equals还是值得考虑的。 isEmpty,isNotEmpty,isBlank,isNotBlank 和前面一样,这些方法相对于jdk提供的isEmpty方法来说,多了一个"空指针安全”,即不用考虑传递参数的空值问题,让我们来看一个例子: Java代码 收藏代码 if(myString != null && !myString.isEmpty()) { ...

2014-03-21 · 1 min · 176 words · -

Java获取客户端真实IP地址的两种方法

Java获取客户端真实IP地址的两种方法 http://dpn525.iteye.com/blog/1132318 在JSP里,获取客户端的IP地址的方法是: request.getRemoteAddr () ,这种方法在大部分情况下都是有效的。但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实IP地址了。 在JSP里,获取客户端的IP地址的方法是: request.getRemoteAddr () ,这种方法在大部分情况下都是有效的。但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实IP地址了。 如果使用了反向代理软件,将http://192.168.1.110: 2046/ 的URL反向代理为 http://www.javapeixun.com.cn / 的URL时,用request.getRemoteAddr () 方法获取的IP地址是: 127.0.0.1或192.168.1.110,而并不是客户端的真实IP。 经过代理以后,由于在客户端和服务之间增加了中间层,因此服务器无法直接拿到客户端的IP,服务器端应用也无法直接通过转发请求的地址返回给客户端。但是在转发请求的HTTP头信息中,增加了X-FORWARDED-FOR信息。用以跟踪原有的客户端IP地址和原来客户端请求的服务器地址。当我们访问http://www.javapeixun.com.cn/index.jsp/ 时,其实并不是我们浏览器真正访问到了服务器上的index.jsp文件,而是先由代理服务器去访问http://192.168.1.110: 2046/index.jsp ,代理服务器再将访问到的结果返回给我们的浏览器,因为是代理服务器去访问index.jsp的,所以index.jsp中通过request.getRemoteAddr () 的方法获取的IP实际上是代理服务器的地址,并不是客户端的IP地址。 于是可得出获得客户端真实IP地址的方法一: Java代码 收藏代码 public String getRemortIP(HttpServletRequest request) { if (request.getHeader(“x-forwarded-for”) == null) { return request.getRemoteAddr(); } return request.getHeader(“x-forwarded-for”); } 可是当我访问http://www.5a520.cn /index.jsp/ 时,返回的IP地址始终是unknown,也并不是如上所示的127.0.0.1或192.168.1.110了,而我访问http://192.168.1.110: 2046/index.jsp 时,则能返回客户端的真实IP地址,写了个方法去验证。原因出在了Squid上。squid.conf 的配制文件forwarded_for 项默认是为on,如果 forwarded_for 设成了 off 则: X-Forwarded-For: unknown 于是可得出获得客户端真实IP地址的方法二: Java代码 收藏代码 public String getIpAddr(HttpServletRequest request) { String ip = request.getHeader(“x-forwarded-for”); if(ip == null || ip.length() == 0 || “unknown”.equalsIgnoreCase(ip)) { ...

2014-03-13 · 2 min · 302 words · -

Java Iterator 迭代器

Java Iterator 迭代器 http://www.cnblogs.com/amboyna/archive/2007/09/25/904804.html http://jnotnull.iteye.com/blog/262379 迭代器 (Iterator) 迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构。迭代器通常被称为"轻量级"对象,因为创建它的代价小。 Java中的Iterator功能比较简单,并且只能单向移动: (1) 使用方法iterator()要求容器返回一个Iterator。第一次调用Iterator的next()方法时,它返回序列的第一个元素。注意: iterator()方法是java.lang.Iterable接口,被Collection继承。 (2) 使用next()获得序列中的下一个元素。 (3) 使用hasNext()检查序列中是否还有元素。 (4) 使用remove()将迭代器新返回的元素删除。 Iterator是Java迭代器最简单的实现,为List设计的ListIterator具有更多的功能,它可以从两个方向遍历List,也可以从List中插入和删除元素。 迭代器应用: list l = new ArrayList(); l.add(“aa”); l.add(“bb”); l.add(“cc”); for (Iterator iter = l.iterator(); iter.hasNext();) { String str = (String)iter.next(); System.out.println(str); } /*迭代器用于while循环 Iterator iter = l.iterator(); while(iter.hasNext()){ String str = (String) iter.next(); System.out.println(str); } */

2014-02-28 · 1 min · 55 words · -

Java URL URI

Java URL URI http://blog.csdn.net/majiabao123/article/details/4202158 从JDK1.4开始,java.net包对统一资源定位符(uniform resource locator URL)和统一资源标识符(uniform resource identifier URI)作了非常有用的区分。 URI是个纯粹的句法结构,用于指定标识Web资源的字符串的各个不同部分。URL是URI的一个特例,它包含了定位Web资源的足够信息。其他URI,比如: mailto: cay@horstman.com 则不属于定位符,因为根据该标识符无法定位任何资源。像这样的URI我们称之为URN(统一资源名称)。 在Java类库中,URI类不包含任何访问资源的方法,它唯一的作用就是解析。相反的是,URL类可以打开一个到达资源的流。因此URL类只能作用于那些Java类库知道该如何处理的模式,例如: http: ,https: ,ftp:,本地文件系统(file:),和Jar文件(jar:)。 URI类的作用之一是解析标识符并将它们分解成各个不同的组成部分。你可以用以下方法读取它们: getSchema getHost getPort getPath getQuery URI类的另一个作用是处理绝对标识符和相对标识符。如果存在一个如下的绝对URI: http://docs.mycompany.com/api/java/net/serversocket.html 和一个如下的相对URI: ../../java/net/socket.html#Socket() 那么你可以将它们合并成一个绝对URI: http://docs.mycompany.com/api/java/net/socket.html#Socket() 这个过程被称为相对URL的转换。 与此相反的过程成为相对化。例如: 假设你有一个基本URI: http://docs.mycompany/api 和另一个URI: http://docs.mycompany/api/java/lang/String.html 那么相对化后的URI就是: java/lang/String.html

2014-02-26 · 1 min · 39 words · -

java – volatile

java – volatile volatile 关键字, Volatile [‘vɑlətl] volatile关键字告诉编译器,去内存里面取最新值。但是,即使取的是内存里的所谓“最新”值,事实上并不能保证最新。 voldatile关键字首先具有“易变性”,声明为volatile变量编译器会强制要求读内存,相关语句不会直接使用上一条语句对应的的寄存器内容,而是重新从内存中读取。 其次具有”不可优化”性,volatile告诉编译器,不要对这个变量进行各种激进的优化,甚至将变量直接消除,保证代码中的指令一定会被执行。 最后具有“顺序性”,能够保证Volatile变量间的顺序性,编译器不会进行乱序优化。不过要注意与非volatile变量之间的操作,还是可能被编译器重排序的。 需要注意的是其含义跟原子操作无关,比如: volatile int a; a++; 其中a++操作实际对应三条汇编指令实现”读-改-写“操作 (RMW) ,并非原子的。 思考: bool 类型是不是适合使用, 不会出问题。 不同编程语言中 voldatile 含义与实现并不完全相同, Java 语言中 voldatile 变量可以被看作是一种轻量级的同步, 因其还附带了 acuire 和 release 语义。 实际上也是从 JDK5 以后才通过这个措施进行完善,其 volatile 变量具有 synchronized 的可见性特性, 但是不具备原子特性。 Java语言中有 volatile 修饰的变量, 赋值后多执行了一个 load addl $0x0, (%esp) 操作, 这个操作相当于一个 lock 指令, 就是增加一个完全的内存屏障指令, 这点与C++实现并不一样。 volatile 的读性能消耗与普通变量几乎相同, 但是写操作稍慢 ,因为它需要在本地代码中插入许多内存屏障指令来保证处理器不发生乱序执行。 Java 实践中仅满足下面这些条件才应该使用 volatile 关键字: 变量写入操作不依赖变量当前值,或确保只有一个线程更新变量的值 (Java可以,C++仍然不能) 该变量不会与其他变量一起纳入 变量并未被锁保护 C++中voldatile等于插入编译器级别屏障,因此并不能阻止CPU硬件级别导致的重排。C++11 中volatile语义没有任何变化,不过提供了std::atomic工具可以真正实现原子操作,而且默认加入了内存屏障 (可以通过在store与load操作时设置内存模型参数进行调整,默认为std::memory_order_seq_cst) 。 ...

2014-02-12 · 3 min · 533 words · -

Tomcat 访问日志

Tomcat 访问日志 http://hooray520.iteye.com/blog/1335156 Tomcat的访问日志是靠org.apache.catalina.valves.AccessLogValve来控制的,你可以修改$tomcat/conf/server.xml来启用它 ($tomcat是Tomcat安装的目录)。AccessLogValve默认应该是注释掉的,简单的将其注释去掉,然后重启Tomcat就可以了。 以下是Tomcat默认的配置: 引用 你可以设置日志保存的目录(directory),日志的文件名的前缀(prefix),后缀(suffix)和日志的具体格式。保存目录,文件名的前缀、后缀都很简单,一般默认设置也就可以了。resolveHost出于性能的考虑,一般也设为false. 但访问日志的格式(pattern)却有很多的选项供你选择。以下列出了一些基本的日志格式项: 引用 %a – 远程主机的IP (Remote IP address) %A – 本机IP (Local IP address) %b – 发送字节数,不包含HTTP头,0字节则显示 ‘-’ (Bytes sent, excluding HTTP headers, or ‘-’ if no bytes were sent) %B – 发送字节数,不包含HTTP头 (Bytes sent, excluding HTTP headers) %h – 远程主机名 (Remote host name) %H – 请求的具体协议,HTTP/1.0 或 HTTP/1.1 (Request protocol) %l – 远程用户名,始终为 ‘-’ (Remote logical username from identd (always returns ‘-’)) %m – 请求方式,GET, POST, PUT (Request method) %p – 本机端口 (Local port) %q – 查询串 (Query string (prepended with a ‘?’ if it exists, otherwise an empty string) %r – HTTP请求中的第一行 (First line of the request) %s – HTTP状态码 (HTTP status code of the response) %S – 用户会话ID (User session ID) %t – 访问日期和时间 (Date and time, in Common Log Format format) %u – 已经验证的远程用户 (Remote user that was authenticated %U – 请求的URL路径 (Requested URL path) %v – 本地服务器名 (Local server name) %D – 处理请求所耗费的毫秒数 (Time taken to process the request, in millis) %T – 处理请求所耗费的秒数 (Time taken to process the request, in seconds) 你可以用以上的任意组合来定制你的访问日志格式,也可以用下面两个别名common和combined来指定常用的日志格式: ...

2014-01-10 · 2 min · 311 words · -

ModelAndView

ModelAndView http://itroop.iteye.com/blog/263845 的构造方法有7个。但是它们都是相通的。这里使用无参构造函数来举例说明如何构造ModelAndView 实例。 ModelAndView类别就如其名称所示,是代表了MVC Web程序中Model与View的对象,不过它只是方便您一次返回这两个对象的holder,Model与View两者仍是分离的概念。 最简单的ModelAndView是持有View的名称返回,之后View名称被view resolver,也就是实作org.springframework.web.servlet.View接口的实例解析,例如 InternalResourceView或JstlView等等: ModelAndView(String viewName) 如果您要返回Model对象,则可以使用Map来收集这些Model对象,然后设定给ModelAndView,使用下面这个版本的ModelAndView: ModelAndView(String viewName, Map model) Map对象中设定好key与value值,之后可以在视图中取出,如果您只是要返回一个Model对象,则可以使用下面这个ModelAndView版本: ModelAndView(String viewName, String modelName, Object modelObject) 藉由modelName,您可以在视图中取出Model并显示。 ModelAndView类别提供实作View接口的对象来作View的参数: ModelAndView(View view) ModelAndView(View view, Map model) ModelAndView(View view, String modelName, Object modelObject) 一个例子是org.springframework.web.servlet.view.RedirectView,ModelAndView预设是使 用forward来转发请求结果至视图,使用RedirectView的话,则会使用redirect将请求重导至视图,例如: … public ModelAndView handleRequest(….) … { …. return new ModelAndView(new RedirectView(this.getViewPage())); } …. 在这边,viewPage的地址是从服务器网页根目录开始指定,而不是Web应用程序的根目录,所以您的getViewPage()传回的地址必须像是 /springapp/pages/index.htm这样的地址,其中springapp是您的Web应用程序目录。 使用forward的话,网址列上并不会出现被转发的目标地址,而且forward是在Web应用程序之内进行,可以访问Web应用程序的隐藏目录,像是WEB-INF,然而forward只能在Web应用程序中进行,不能指定至其它的Web应用程序地址。 使用redirect的话,是要求客户端浏览器重新发出一个指定的请求地址,因此网址列上会出现被重导的目录地址,重导的请求是由浏览器发出,所以不能 访问Web应用程序中的隐藏目录,像是WEB-INF,然而重导是重新要求一个网页,所以可以指定至其它的Web应用程序地址。 DispatcherServlet会根据传回的ModelAndView来解析View名称,并处理给予的Model。View名称的解析是委托给实 作org.springframework.web.servlet.ViewResolver接口的实例,ViewResolver接口定义如下: public interface ViewResolver { public view resolveViewName(String, Locale locale) throws ServletException; } ViewResolver的一个实例是InternalResourceViewResolver,名称解析完之后,实际的View绘制与Model转 换处理是交给实作org.springframework.web.servlet.View的实例,View接口如下: public interface View { ...

2014-01-09 · 1 min · 153 words · -

AspectJ 编译时织入(Compile Time Weaving, CTW)

AspectJ 编译时织入(Compile Time Weaving, CTW) 本文主要介绍 AspectJ 编译时织入 (Compile Time Weaving, CTW) 的技术,并附有详细示例代码。 AspectJ 是一个 AOP 的具体实现框架。AOP (Aspect Oriented Programming) 即面向切面编程,可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。 AspectJ不但可以通过预编译方式 (CTW) 和运行期动态代理的方式织入切面,还可以在载入 (Load Time Weaving, LTW) 时织入。 AspectJ 扩展了Java,定义了一些专门的AOP语法。官网上这样描述: a seamless aspect-oriented extension to the Java programming language Java platform compatible easy to learn and use 在网上,关于 Spring + AspectJ Annotation动态代理或者AspectJ 载入时织入 (Load Time Weaving, LTW) 的文章特别多 (其特点是: 前者需要用Java编写切面并加以注释,后者需要编写 aop.xml 文件并在启动 Java 时带上参数-javaagent) ,所以本文就不在涉及。 编译时织入是 AspectJ 的一个重要功能,因为 AspectJ 有一个专门的编译器用来生成遵守 Java 字节编码规范的 Class 文件。 ...

2014-01-08 · 3 min · 464 words · -

class.getName

class.getName http://bbs.csdn.net/topics/70162498 java.lang.Object java.lang.Class String getName() Returns the name of the entity (class, interface, array class, primitive type, or void) represented by this Class object, as a String. java的类映射函数..用来得到类的具体名字 比如说1个类mypackage.MyClass MyClass.class.getName();就能得到mypackage.MyClass 在object里面这么用getClass().getName();

2014-01-05 · 1 min · 32 words · -