当前位置: 编程技术>移动开发
本页文章导读:
▪记录一个简单的有关问题 记录一个简单的问题
今天想提取com.test.test2这样的字符串的最后一个单词,没有想到什么好的方法,就用split把它分开之后取最后一个,但是又不太懂正则表达式简单的一位split(".")能达到效.........
▪ ClassLoader学习记要3 ClassLoader学习记录3
果然啊,内容越往后面,就越来越往安全上转移了,转移了有木有,看来得开始制定新的学习计划,这再往后学没神马用啊,或者说短时间用不上。写完这期,开始找找.........
▪ MinSdkVersion, targetSdkVersion, target API level的差别(转) MinSdkVersion, targetSdkVersion, target API level的区别(转)
转自:http://blog.csdn.net/champgauss/article/details/7291189MinSdkVersion, targetSdkVersion, target API level的区别在AndroidMenifest.xml中,常常会有下面的语句.........
[1]记录一个简单的有关问题
来源: 互联网 发布时间: 2014-02-18
记录一个简单的问题
今天想提取com.test.test2这样的字符串的最后一个单词,没有想到什么好的方法,就用split把它分开之后取最后一个,但是又不太懂正则表达式简单的一位split(".")能达到效果,结果分的结果是什么都没有。于是试了一下后发现有效果的是split("\\.")应该是转义之类的,看来正则是必备的一项技能啊!
[2] ClassLoader学习记要3
来源: 互联网 发布时间: 2014-02-18
ClassLoader学习记录3
果然啊,内容越往后面,就越来越往安全上转移了,转移了有木有,看来得开始制定新的学习计划,这再往后学没神马用啊,或者说短时间用不上。写完这期,开始找找新的学习路线。
这节介绍的是字节码的效验,严格来讲和“ClassLoader学习”这个题目有点不贴切,因为介绍的偏重于效验器(verifier)。不过还是能学到不少东西。
先回顾一下基本知识,在执行一个java文件的时候一般的步骤是:
javac Hello.java -> Hello.class
java Hello
(上面两行,忘记的或者记不清的,去面壁去!)
大家好,我刚面壁回来,给大家继续讲解:
如果执行命令 javac Hello.java -verbose,我们可以回顾下前面学习的知识,打印出的消息是:
D:\code>javac Hello.java -verbose
[解析开始时间 Hello.java]
[解析已完成时间 30ms]
[源文件的搜索路径: .,C:\Program Files\Java\jdk1.6.0_29\lib\dt.jar,C:\Program Fi
les\Java\jdk1.6.0_29\lib\tools.jar]
[类文件的搜索路径: C:\Program Files\Java\jdk1.6.0_29\jre\lib\resources.jar,C:\P
rogram Files\Java\jdk1.6.0_29\jre\lib\rt.jar,C:\Program Files\Java\jdk1.6.0_29\j
re\lib\sunrsasign.jar,C:\Program Files\Java\jdk1.6.0_29\jre\lib\jsse.jar,C:\Prog
ram Files\Java\jdk1.6.0_29\jre\lib\jce.jar,C:\Program Files\Java\jdk1.6.0_29\jre
\lib\charsets.jar,C:\Program Files\Java\jdk1.6.0_29\jre\lib\modules\jdk.boot.jar
,C:\Program Files\Java\jdk1.6.0_29\jre\classes,C:\Program Files\Java\jdk1.6.0_29
\jre\lib\ext\dnsns.jar,C:\Program Files\Java\jdk1.6.0_29\jre\lib\ext\localedata.
jar,C:\Program Files\Java\jdk1.6.0_29\jre\lib\ext\sunjce_provider.jar,C:\Program
Files\Java\jdk1.6.0_29\jre\lib\ext\sunmscapi.jar,C:\Program Files\Java\jdk1.6.0
_29\jre\lib\ext\sunpkcs11.jar,.,C:\Program Files\Java\jdk1.6.0_29\lib\dt.jar,C:\
Program Files\Java\jdk1.6.0_29\lib\tools.jar]
[正在装入 java\lang\Object.class(java\lang:Object.class)]
[正在装入 java\lang\String.class(java\lang:String.class)]
[正在检查 Hello]
[正在装入 java\lang\System.class(java\lang:System.class)]
[正在装入 java\io\PrintStream.class(java\io:PrintStream.class)]
[正在装入 java\io\FilterOutputStream.class(java\io:FilterOutputStream.class)]
[正在装入 java\io\OutputStream.class(java\io:OutputStream.class)]
[已写入 Hello.class]
[总时间 234ms]
代码就是一个Hello World。通过输出,我们可以看见前面学过得加载类的过程。
然后使用java Hello就可以输出Hello World了。
本章的开始部分引入这个命令: java -noverify Hello。
该命令特别之处就是在执行Hello的时候使用非正式的-noverify选项来钝化效验。
那么,我们就先来看看效验,都要效验什么东西:
如果以上这些检查中任何一条没有通过,那么该类就被认为遭到了破坏,并且不予加载。
肯定很多人有疑问了,在javac Hello.java的过程中,如果你违反了规则,就不会得到Hello.class,(这事编译器都做了)那还要效验器来干嘛?因为,一个具有汇编程序经验的人,可以很容易的制造出这样的字节码出来,然后送给虚拟机来执行。所以效验器是很有必要的,要记住,效验器总是在防范被故意篡改的类文件,而不仅仅只是检查编译器产生的类文件。
为了深入了解效验器的工作,也为了了解java字节码的载入原理,我们继续来看下面的代码:
static int fun(){
int m;
int n;
int m = 1;
int n = 2;
int r = m + n;
return r;
}
这个方法被编译以后会生成16进制的.class文件。
要了解编译后的数据,我们要借助javap工具,来查看助记(mnemonic)格式的字节码。
javap -c VerifierTest
得到:
0 iconst_11 istore_02 iconst_23 istore_14 iload_05 iload_16 iadd7 istore_28 iload_29 ireturn
那么如果我们把int n = 2 替换成 int m = 2,也就是istore_1改成istore_0; 使得n没有被初始化。我们就要修改16进制的class文件。先列出代码对应的16进制数:
0 iconst_1 041 istore_0 3B2 iconst_2 053 istore_1 3C4 iload_0 1A5 iload_1 1B6 iadd 607 istore_2 3D8 iload_2 1C9 ireturn AC
使用16进制数编辑器,将3C改为3B。这样执行VerifierTest程序,我们会得到java.lang.VerifyError的错误。
没错,虚拟机发现了我们的修改。
如果加入刚才的java -noverify VerifierTest参数,那么程序就可以产生输出了,为15102330,一个随机数,典型的输出错误。
所以,可以看出效验器果然给我们提供了很好的安全机制。
果然啊,内容越往后面,就越来越往安全上转移了,转移了有木有,看来得开始制定新的学习计划,这再往后学没神马用啊,或者说短时间用不上。写完这期,开始找找新的学习路线。
这节介绍的是字节码的效验,严格来讲和“ClassLoader学习”这个题目有点不贴切,因为介绍的偏重于效验器(verifier)。不过还是能学到不少东西。
先回顾一下基本知识,在执行一个java文件的时候一般的步骤是:
javac Hello.java -> Hello.class
java Hello
(上面两行,忘记的或者记不清的,去面壁去!)
大家好,我刚面壁回来,给大家继续讲解:
如果执行命令 javac Hello.java -verbose,我们可以回顾下前面学习的知识,打印出的消息是:
D:\code>javac Hello.java -verbose
[解析开始时间 Hello.java]
[解析已完成时间 30ms]
[源文件的搜索路径: .,C:\Program Files\Java\jdk1.6.0_29\lib\dt.jar,C:\Program Fi
les\Java\jdk1.6.0_29\lib\tools.jar]
[类文件的搜索路径: C:\Program Files\Java\jdk1.6.0_29\jre\lib\resources.jar,C:\P
rogram Files\Java\jdk1.6.0_29\jre\lib\rt.jar,C:\Program Files\Java\jdk1.6.0_29\j
re\lib\sunrsasign.jar,C:\Program Files\Java\jdk1.6.0_29\jre\lib\jsse.jar,C:\Prog
ram Files\Java\jdk1.6.0_29\jre\lib\jce.jar,C:\Program Files\Java\jdk1.6.0_29\jre
\lib\charsets.jar,C:\Program Files\Java\jdk1.6.0_29\jre\lib\modules\jdk.boot.jar
,C:\Program Files\Java\jdk1.6.0_29\jre\classes,C:\Program Files\Java\jdk1.6.0_29
\jre\lib\ext\dnsns.jar,C:\Program Files\Java\jdk1.6.0_29\jre\lib\ext\localedata.
jar,C:\Program Files\Java\jdk1.6.0_29\jre\lib\ext\sunjce_provider.jar,C:\Program
Files\Java\jdk1.6.0_29\jre\lib\ext\sunmscapi.jar,C:\Program Files\Java\jdk1.6.0
_29\jre\lib\ext\sunpkcs11.jar,.,C:\Program Files\Java\jdk1.6.0_29\lib\dt.jar,C:\
Program Files\Java\jdk1.6.0_29\lib\tools.jar]
[正在装入 java\lang\Object.class(java\lang:Object.class)]
[正在装入 java\lang\String.class(java\lang:String.class)]
[正在检查 Hello]
[正在装入 java\lang\System.class(java\lang:System.class)]
[正在装入 java\io\PrintStream.class(java\io:PrintStream.class)]
[正在装入 java\io\FilterOutputStream.class(java\io:FilterOutputStream.class)]
[正在装入 java\io\OutputStream.class(java\io:OutputStream.class)]
[已写入 Hello.class]
[总时间 234ms]
代码就是一个Hello World。通过输出,我们可以看见前面学过得加载类的过程。
然后使用java Hello就可以输出Hello World了。
本章的开始部分引入这个命令: java -noverify Hello。
该命令特别之处就是在执行Hello的时候使用非正式的-noverify选项来钝化效验。
那么,我们就先来看看效验,都要效验什么东西:
- 变量要在使用之前进行初始化。
- 方法调用与对象引用类型之间要匹配。
- 访问私有数据和方法的规则没有被违反。
- 对本地变量的访问都在运行时堆栈内。
- 运行时堆栈没有溢出。
如果以上这些检查中任何一条没有通过,那么该类就被认为遭到了破坏,并且不予加载。
肯定很多人有疑问了,在javac Hello.java的过程中,如果你违反了规则,就不会得到Hello.class,(这事编译器都做了)那还要效验器来干嘛?因为,一个具有汇编程序经验的人,可以很容易的制造出这样的字节码出来,然后送给虚拟机来执行。所以效验器是很有必要的,要记住,效验器总是在防范被故意篡改的类文件,而不仅仅只是检查编译器产生的类文件。
为了深入了解效验器的工作,也为了了解java字节码的载入原理,我们继续来看下面的代码:
static int fun(){
int m;
int n;
int m = 1;
int n = 2;
int r = m + n;
return r;
}
这个方法被编译以后会生成16进制的.class文件。
要了解编译后的数据,我们要借助javap工具,来查看助记(mnemonic)格式的字节码。
javap -c VerifierTest
得到:
0 iconst_11 istore_02 iconst_23 istore_14 iload_05 iload_16 iadd7 istore_28 iload_29 ireturn
那么如果我们把int n = 2 替换成 int m = 2,也就是istore_1改成istore_0; 使得n没有被初始化。我们就要修改16进制的class文件。先列出代码对应的16进制数:
0 iconst_1 041 istore_0 3B2 iconst_2 053 istore_1 3C4 iload_0 1A5 iload_1 1B6 iadd 607 istore_2 3D8 iload_2 1C9 ireturn AC
使用16进制数编辑器,将3C改为3B。这样执行VerifierTest程序,我们会得到java.lang.VerifyError的错误。
没错,虚拟机发现了我们的修改。
如果加入刚才的java -noverify VerifierTest参数,那么程序就可以产生输出了,为15102330,一个随机数,典型的输出错误。
所以,可以看出效验器果然给我们提供了很好的安全机制。
[3] MinSdkVersion, targetSdkVersion, target API level的差别(转)
来源: 互联网 发布时间: 2014-02-18
MinSdkVersion, targetSdkVersion, target API level的区别(转)
转自:http://blog.csdn.net/champgauss/article/details/7291189
MinSdkVersion, targetSdkVersion, target API level的区别
在AndroidMenifest.xml中,常常会有下面的语句:
<uses-sdk android:minSdkVersion="4" android:targetSdkVersion="10" android:maxSdkVersion="10" />
在default.properties中,会看到下面的语句: target=android-10
如果是使用Eclipse的话,还可能会看到这样的警告:Attribute minSdkVersion (4) is lower than the project target API level (10)
那么,这里面的minSdkVersion、targetSdkVersion、maxSdkVersion、target API level四个数值到底有什么区别?minSdkVersion与maxSdkVersion比较容易理解,就是在安装程序的时候,如果目标设备的API版本小于minSdkVersion,或者大于maxSdkVersion,程序将无法安装。一般来说没有必要设置maxSdkVersion。
targetSdkVersion相对复杂一些,如果设置了此属性,那么在程序执行时,如果目标设备的API版本正好等于此数值,他会告诉Android平台:此程序在此版本已经经过充分测,没有问题。不必为此程序开启兼容性检查判断的工作了。也就是说,如果targetSdkVersion与目标设备的API版本相同时,运行效率可能会高一些。但是,这个设置仅仅是一个声明、一个通知,不会有太实质的作用,比如说,使用了targetSdkVersion这个SDK版本中的一个特性,但是这个特性在低版本中是不支持的,那么在低版本的API设备上运行程序时,可能会报错:java.lang.VerifyError。也就是说,此属性不会帮你解决兼容性的测试问题。你至少需要在minSdkVersion这个版本上将程序完整的跑一遍来确定兼容性是没有问题的。
在default.properties中的target是指在编译的时候使用哪个版本的API进行编译。
综上,上面的四个值其实是作用于不同的时期:target API level是在编译的时候起作用,用于指定使用哪个API版本(SDK版本)进行编译。minSdkVersion和maxSdkVersion是在程序安装的时候起作用,用于指定哪些版本的设备可以安装此应用。targetSdkVersion是在程序运行的时候起作用,用于提高指定版本的设备上程序运行体验。这四个数值在程序编译时也没有严格的检查,比如说,你可以将minSdkVersion设置的比maxSdkVersion还大,他会自动忽略掉错误的maxSdkVersion。
转自:http://blog.csdn.net/champgauss/article/details/7291189
MinSdkVersion, targetSdkVersion, target API level的区别
在AndroidMenifest.xml中,常常会有下面的语句:
<uses-sdk android:minSdkVersion="4" android:targetSdkVersion="10" android:maxSdkVersion="10" />
在default.properties中,会看到下面的语句: target=android-10
如果是使用Eclipse的话,还可能会看到这样的警告:Attribute minSdkVersion (4) is lower than the project target API level (10)
那么,这里面的minSdkVersion、targetSdkVersion、maxSdkVersion、target API level四个数值到底有什么区别?minSdkVersion与maxSdkVersion比较容易理解,就是在安装程序的时候,如果目标设备的API版本小于minSdkVersion,或者大于maxSdkVersion,程序将无法安装。一般来说没有必要设置maxSdkVersion。
targetSdkVersion相对复杂一些,如果设置了此属性,那么在程序执行时,如果目标设备的API版本正好等于此数值,他会告诉Android平台:此程序在此版本已经经过充分测,没有问题。不必为此程序开启兼容性检查判断的工作了。也就是说,如果targetSdkVersion与目标设备的API版本相同时,运行效率可能会高一些。但是,这个设置仅仅是一个声明、一个通知,不会有太实质的作用,比如说,使用了targetSdkVersion这个SDK版本中的一个特性,但是这个特性在低版本中是不支持的,那么在低版本的API设备上运行程序时,可能会报错:java.lang.VerifyError。也就是说,此属性不会帮你解决兼容性的测试问题。你至少需要在minSdkVersion这个版本上将程序完整的跑一遍来确定兼容性是没有问题的。
在default.properties中的target是指在编译的时候使用哪个版本的API进行编译。
综上,上面的四个值其实是作用于不同的时期:target API level是在编译的时候起作用,用于指定使用哪个API版本(SDK版本)进行编译。minSdkVersion和maxSdkVersion是在程序安装的时候起作用,用于指定哪些版本的设备可以安装此应用。targetSdkVersion是在程序运行的时候起作用,用于提高指定版本的设备上程序运行体验。这四个数值在程序编译时也没有严格的检查,比如说,你可以将minSdkVersion设置的比maxSdkVersion还大,他会自动忽略掉错误的maxSdkVersion。
最新技术文章: