免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动!
内容参考于:图灵Python学院
上一个内容:2.安卓逆向-初识java语言
上一个内容里写了编写java语言代码的环境搭建,也就是下载jdk和安装jdk和下载idea和安装idea和创建一个写java语言代码的项目,还写了几个简单的java代码示例
要强调一件事,现在写的是java基础,然后主线是app逆向不是java开发,所以java基础不会写的很细有些概念省略,写什么就记什么不要细想,记不住后面逆向的时候再练,所以这里的java基础只能保证逆向时可以看懂代码可以看懂代码做了一件什么事情
接下来继续认识java语言
首先是一个逻辑运算符
如下图,现在只需要看一遍就行,后面通过java代码来理解它们
javapublic class Test { public static void main(String[] args) { boolean a = true; boolean b = false; System.out.println("a && b = " + (a && b)); System.out.println("a || b = " + (a || b) ); System.out.println("!(a && b) = " + !(a && b)); } }
true表示满足,false表示不满足
条件运算符:
示例:
javapublic class Test { public static void main(String[] args){ int a , b; a = 10; /** (a == 1) ? 20 : 30;是固定写法 意思是 如果 a 等于 1 成立,则设置 b 为 20,否则为 30 (a == 1)这样 == 表示a的值是否等于1,这里如果是等于就是true不等于就是 false 也就是这里不能说等于要说满足不满足 */ b = (a == 1) ? 20 : 30; System.out.println( "Value of b is : " + b ); /** (a == 10) ? 20 : 30;是固定写法 意思是 如果 a 等于 10 成立,则设置 b 为 20,否则为 30 */ b = (a == 10) ? 20 : 30; System.out.println( "Value of b is : " + b ); } }
运行结果
条件语句:
示例:用来控制代码的走向
javaint num = 10; if (num > 0) { System.out.println("这个数是正数"); } else { System.out.println("这个数不是正数"); }
运行结果:
然后这个if和else还可以有如下的写法
javaint score = 85; if (score >= 90) { System.out.println("优秀"); } else if (score >= 80) { System.out.println("良好"); } else if (score >= 60) { System.out.println("及格"); } else { System.out.println("不及格"); }
运行结果:
循环:
循环就是字面意思,实际效果就是多次执行一段代码
示例:只要写了while这个单词就说明这是一个循环
javapublic class Hello { public static void main(String[] args) { int count = 0; /** * count < 3是循环的条件,只要满足它就会一直执行 * System.out.println("执行中..."+count); * count += 1; * 这两段代码 */ while (count < 3) { System.out.println("执行中..."+count); count += 1; } } }
运行效果:
java语言中有多种循环上面是第一种
还有一个do..while循环,这个循环不管满足不满足都会执行一次
示例:
c++public class Hello { public static void main(String[] args) { int count = 0; do { System.out.println("执行中..."); count += 1; } while (count < 3); } }
运行结果:
然后还有一个for循环
javapublic class Hello { public static void main(String[] args) { // i++ 先赋值在运算 //++i 先运算在赋值 for (int i = 0; i < 10; i++) { System.out.println("哈哈哈"); } } }
运行结果:
for循环示例2:
javapublic class Hello { public static void main(String[] args) { /*** * nameList变量是一个String类型的数组,String是字符串类型,字符串就是一 段文字 * 下方它就有4段文字分别是苏苏、菲菲、莹莹、丽丽 */ String[] nameList = {"苏苏", "菲菲", "莹莹", "丽丽"}; // nameList.length 4 // nameList[0] /** * nameList.length的值是nameList它里面有几段文字 * nameList[0]这样是取出第一段文字也就是苏苏 * nameList[1]这样是取出第二段文字也就是菲菲 * nameList[2]这样是取出第三段文字也就是莹莹 * nameList[3]这样是取出第四段文字也就是丽丽 */ for (int idx = 0; idx < nameList.length; idx++) { String ele = nameList[idx]; System.out.println(ele); } } }
运行结果:
结束循环:
结束循环的方式有两种一种是break、一种continue,break意思是结束循环,continue意思是结束本次循环进入下一次循环
break示例:
javaimport java.util.Scanner; public class d1 { public static void main(String[] args) { /*** * nameList变量是一个String类型的数组,String是字符串类型,字符串就是一 段文字 * 下方它就有4段文字分别是苏苏、菲菲、莹莹、丽丽 */ String[] nameList = {"苏苏", "菲菲", "莹莹", "丽丽"}; // nameList.length 4 // nameList[0] /** * nameList.length的值是nameList它里面有几段文字 * nameList[0]这样是取出第一段文字也就是苏苏 * nameList[1]这样是取出第二段文字也就是菲菲 * nameList[2]这样是取出第三段文字也就是莹莹 * nameList[3]这样是取出第四段文字也就是丽丽 */ for (int idx = 0; idx < nameList.length; idx++) { String ele = nameList[idx]; if (ele == "莹莹"){ break; } System.out.println(ele); } } }
运行结果:
continue示例:
javaimport java.util.Scanner; public class d1 { public static void main(String[] args) { /*** * nameList变量是一个String类型的数组,String是字符串类型,字符串就是一段文字 * 下方它就有4段文字分别是苏苏、菲菲、莹莹、丽丽 */ String[] nameList = {"苏苏", "菲菲", "莹莹", "丽丽"}; // nameList.length 4 // nameList[0] /** * nameList.length的值是nameList它里面有几段文字 * nameList[0]这样是取出第一段文字也就是苏苏 * nameList[1]这样是取出第二段文字也就是菲菲 * nameList[2]这样是取出第三段文字也就是莹莹 * nameList[3]这样是取出第四段文字也就是丽丽 */ for (int idx = 0; idx < nameList.length; idx++) { String ele = nameList[idx]; if (ele == "莹莹"){ continue; } System.out.println(ele); } } }
运行结果:
数据类型:
java语言里的数据类型分两类:基本数据类型 和 引用数据类型
java语言里的基本数据类型:byte、short、int、long、float、double、char、boolean
byte,字节 【1字节】表示范围:-128 ~ 127 即:
-2^7 ~ 2^7 -1
short,短整型 【2字节】表示范围:-32768 ~ 32767
int,整型 【4字节】表示范围:-2147483648 ~ 2147483647
long,长整型 【8字节】表示范围:-9223372036854775808 ~ 9223372036854775807 最小负数到最大值
示例:
javapublic class Hello { public static void main(String[] args) { byte v1 = 32; short v2 = 10000; int v3 = 22221331; long v4 = 554534353424L;// long类型后面要加一个L } }
这里补充一个编码的知识,电脑中只能存放二进制数怎么就能显示中文了?它是有一个编码表Windows的中文编码表是GBK,GBK编码一个文字是两个数字组成,但一般通用的是UTF-8(UTF8)编码,UTF8编码一个文字由三个数字组成,下方以UTF-8编码为例
javav1 = "夏洛"// 这是一个字符串,在逆向的时候它可能就直接显示中文了,但是也可能显示下方的数字,一个文字由3个数字组成,这个数字是编码表里文字所在的序号 v2 = [-27, -92, -113, -26, -76, -101]// 这6个数字就是夏洛这俩字的编码(所在编码表里的序号),所以这六个数字实际上和上面直接写夏洛是一样的,作用就是为了让我们不好分析的
编码转换
javaimport java.util.Arrays; public class Demo { public static void main(String[] args) { // 1.字节数组(转换为字符串) [字节,字节,字节] byte[] dataList = {97, 105, 100, 61, 50, 52, 54, 51, 56, 55, 53, 55, 49, 38, 97, 117, 116, 111, 95, 112, 108, 97, 121, 61, 48, 38, 99, 105, 100, 61, 50, 56, 57, 48, 48, 56, 52, 52, 49, 38, 100, 105, 100, 61, 75, 82, 69, 104, 69, 83, 77, 85, 74, 104, 56, 116, 70, 67, 69, 86, 97, 82, 86, 112, 69, 50, 116, 97, 80, 81, 107, 55, 87, 67, 104, 67, 74, 103, 38, 101, 112, 105, 100, 61, 48, 38, 102, 116, 105, 109, 101, 61, 49, 54, 50, 55, 49, 48, 48, 57, 51, 55, 38, 108, 118, 61, 48, 38, 109, 105, 100, 61, 48, 38, 112, 97, 114, 116, 61, 49, 38, 115, 105, 100, 61, 48, 38, 115, 116, 105, 109, 101, 61, 49, 54, 50, 55, 49, 48, 52, 51, 55, 50, 38, 115, 117, 98, 95, 116, 121, 112, 101, 61, 48, 38, 116, 121, 112, 101, 61, 51}; String dataString = new String(dataList); System.out.println("字符串是:" + dataString); // 2.字符串->字节数组 try { /* Python中的 name.encode("gbk") string = "夏洛" byte_list = list(string.encode("gbk")) signed_byte_list = [byte if byte < 128 else byte - 256 for byte in byte_list] print(signed_byte_list) */ String name = "夏洛"; byte[] v1 = name.getBytes("GBK");// GBK编码一个中文由两个数字组成 System.out.println(Arrays.toString(v1)); //[-49, -60, -62, -27] // Python中的 name.encode("utf-8") byte[] v2 = name.getBytes("UTF-8");// UTF8编码一个中文由三个数字组成 System.out.println(Arrays.toString(v2)); // [-27, -92, -113, -26, -76, -101] } catch (Exception e) { } } }
运行结果:
引用类型:引用类型有很多,概念很抽象,现在这样理解 只要不是基本数据类型它就是引用类型
String就是一个引用类型,实例:下方的例子是通过构造函数来创建的字符串,不要关心构造函数是什么,先记着这俩字,后面会写
javaimport java.io.UnsupportedEncodingException; public class Hello { public static void main(String[] args) throws UnsupportedEncodingException { String v1 = "夏洛";// 会默认有一个new String("夏洛") // 用构造函数创建字符串: String v2 = new String("夏洛");// 与 String v1 = "夏洛";一样 String v4 = new String(new byte[]{-27, -92, -113, -26, -76, -101});// 默认utf8编码 String v5 = new String(new byte[]{-49, -60, -62, -27}, "GBK"); String v6 = new String(new char[]{'夏', '洛'}) ; } }
处理字符串的函数
javapublic static void demo2(){ String origin = "请叫我靓仔AA"; int len = origin.length(); // 长度 for (int i = 0; i < len; i++) { char item = origin.charAt(i); } String v2 = origin.trim(); // 去除空白 String v3 = origin.toLowerCase(); // 小写 String v4 = origin.toUpperCase(); // 大写 String[] v5 = origin.split("我"); // 分割 String v6 = origin.replace("叫", "喊"); // 替换 String v7 = origin.substring(2, 6); // 子字符串=切片 [2:6] boolean v8 = origin.equals("请叫我"); // origin的值是一个字符串,equals的意思是origin的值是不是跟 请叫我 这三个字相等 boolean v9 = origin.contains("el");// origin中是否包含el这俩字 boolean v10 = origin.startsWith("请"); String v11 = origin.concat("哈哈哈"); }
拼接字符串,就是多个文字进行合并
在java语言中字符串合并是通过StringBuilder类型或StringBuffer类型合并的,StringBuilder类型或StringBuffer类型它俩用法都一样,区别一句两句写不明白现记着StringBuilder类型或StringBuffer类型它俩用法都一样就行,String和它俩的区别,String a = "ass"; 这样就会发现如果还有个文字bbb,怎么放到a里?没办法放,想放就不能用String类型要使用StringBuilder类型或StringBuffer类型,它们俩有一个append函数,这个函数可以做合并操作
追加字符串:通过
append()
方法将字符串追加到StringBuilder
的末尾。
- 插入字符串:使用
insert()
方法在指定位置插入字符串。- 替换字符串:使用
replace()
方法替换指定范围内的字符串。- 删除字符串:通过
delete()
方法删除指定范围内的字符。- 反转字符串:使用
reverse()
方法将字符串反转。- 获取字符串长度:通过
length()
方法获取当前字符串的长度。- 转换为字符串:使用
toString()
方法将StringBuilder
对象转换为普通字符串,也就是转成String类型字符串。- 逆向的时候一般用来把请求参数和请求头拼接再一起进行加密
javaimport java.io.UnsupportedEncodingException; public class Hello { public static void main(String[] args) { StringBuilder sb = new StringBuilder(); // StringBuffer线程安全 sb.append("name"); sb.append("="); sb.append("xialuo"); sb.append("&"); sb.append("age"); sb.append("="); sb.append("18"); String dataString = sb.toString(); System.out.println(dataString); } }
运行结果:
数组:
数组可以理解一块内存空间,内存空间的大小由数组个数组成,这种一般称为容器
javaimport java.util.Arrays; public class Hello { public static void main(String[] args) { /** int[] numArray = new int[3]; 数组声明,数组个数是3个 个数是固定的声明了3个数组就只能放三个数据,多了不行 */ int[] numArray = new int[3]; numArray[0] = 123;// 给数组中第一个位置赋值 numArray[1] = 1;// 给数组中第二个位置赋值 numArray[2] = 99;// 给数组中第三个位置赋值 System.out.println(Arrays.toString(numArray)); // 定义和初始化数组 String[] names = new String[]{"夏洛", "aa", "bb"}; System.out.println(Arrays.toString(names)); String[] nameArray = {"夏洛", "aa", "bb"}; System.out.println(Arrays.toString(nameArray)); // nameArray[0] // nameArray.length for (int idx = 0; idx < nameArray.length; idx++) { String item = nameArray[idx]; } } }
Object类
在java中所有引用类型都默认继承自Object类,不需要手动继承Object类它会自己隐藏式的继承Object类,类就是类型的意思,也就是java中所有引用类型都可以是Object类型
javaimport java.util.Arrays; public class Hello { public static void main(String[] args) { // String 使用 Object类型接收 Object v1 = new String("xialuo"); System.out.println(v1); System.out.println(v1.getClass()); Object v2 = 123; System.out.println(v2); System.out.println(v2.getClass()); } }
实例2:
javaimport java.util.Arrays; public class Hello { public static void main(String[] args) { // 声明数组,数组中元素必须int类型; int[] v1 = new int[3]; // 声明数组,数组中元素必须String类型; String[] v2 = new String[3]; // 声明数组,数组中可以是数组中存储任何类型的对象 Object[] v3 = new Object[3]; v3[0] = 123;// 这里的123是Integer类型,Integer类型本质是int这个基本类型,Integer和int会隐藏式的转换所以用起来会感知不到这件事 v3[1] = "xialuo"; } }
如果Object的字符串想使用String类型里的函数:
javaimport java.util.Arrays; public class Hello { public static void main(String[] args) { // v1是指上字符串对象;String String v1 = new String("xialuo"); String res = v1.toUpperCase(); System.out.println(res); // v2本质是字符串对象;Object Object v2 = new String("xialuo"); String data = (String)v2; // (String)v2表示把v2这个Object类型强制转换成String类型 } }
对于类型进行判断:使用 instanceof 单词就可以比较两个数据类型是否一样了
javaimport java.util.Arrays; public class Hello { public static void func(Object v1) { // aaaa 会进入到这里,然后往下执行,执行完再返回到 bbbb // System.out.println(v1); // System.out.println(v1.getClass()); if (v1 instanceof Integer) { System.out.println("整型"); } else if (v1 instanceof String) { System.out.println("字符串类型"); } else { System.out.println("未知类型"); } } public static void main(String[] args) { func(123);// 这里运行了会进入到 aaaa // 返回到 bbbb func("123"); } }
常用的引用类型
List类型,List是一个规范,java中ArrayList类型和LinkedList类型实现了这个规范,所以要使用List时要用ArrayList类型 或 LinkedList类型
List类型实际上是一个无限制的数组(比如它刚开始创建10个数组,然后10个数组用完了它会重新创建一个大于10的数组),它数组的大小取决于内存的大小
实例:
javaimport java.util.ArrayList; import java.util.Collections; import java.util.LinkedList; import java.util.List; /** * ArrayList和LinkedList查询和插入时间 */ public class ListTest { public static void main(String[] args) { /** <Integer>表示要存放Integer类型 如果不写<XX>这个东西默认存放Object类型,也就是任意类型数据 */ ArrayList<Integer> arrayList = new ArrayList<Integer>(); LinkedList<Integer> linkedList = new LinkedList<Integer>(); //插入十万数据 for (int i = 0; i < 100000; i++) { arrayList.add(i);// add函数用来添加数据 linkedList.add(i); } //记录时间 //System.out.println("array查询时间:"+gettime(arrayList)); //System.out.println("linked查询时间:"+gettime(linkedList)); System.out.println("array插入时间:"+inserttime(arrayList)); System.out.println("linked插入时间:"+inserttime(linkedList)); } //插入数据 private static long inserttime(List<Integer> list) { long number = 10000;//插入的数据量 10000 50000 80000 int index = 10000;//从哪里开始插入 100 1000 10000 long time = System.currentTimeMillis(); for (int i = 0; i < number; i++) { list.add(index,i); } return System.currentTimeMillis()-time; } //查询数据 public static long gettime(List<Integer> list){ long time = System.currentTimeMillis(); for (int i = 0; i < 100000; i++) { //根据索引值找到对应索引 int search = Collections.binarySearch(list, list.get(i));//list.get(0)表示获取第一个数据list.get(2)表示获取第三个数据 if (search!=i){ System.out.println("索引值错误!"); } } return System.currentTimeMillis()-time; } }
上方的代码不全,只有手写的代码
完整代码:以 它的代码为基础进行修改
链接:百度网盘 请输入提取码
提取码:q9n5
复制这段内容后打开百度网盘手机App,操作更方便哦