八期day06-java基础2
零 python和java字节字符串比较
0.1 java字节数组和字符串相互转换
//1 字符串转字节数组
v4 = "彭于晏"
byte[] b = v4.getBytes(); // 默认utf8形式
System.out.println(b); // 输出对象形式,看不到字节数组
System.out.println(Arrays.toString(b));
// try {
// byte[] b1 = v4.getBytes("GBK"); // 'GBK'形式,需要捕获异常
// } catch (Exception e) {
//
// }
byte[] b1 = v4.getBytes("GBK"); // 'GBK'形式,需要捕获异常,或在方法上 throws Exception
System.out.println(Arrays.toString(b1));
// 2 字节数组转字符串
String v8 = new String(new byte[]{-27, -67, -83, -28, -70, -114, -26, -103, -113});
String v9 = new String(new byte[]{-59, -19, -45, -38, -22, -52},"GBK");
System.out.println(v8);
System.out.println(v9);
0.2 java 字符数组和字符串相互转换
// 1 字符数组转字符串
char[] c=new char[]{'彭','于','晏'};
String v1 = new String(c);
System.out.println(v1);
// 2 字符串串转字符数组
String str1 = "彭于晏";
char[] c=str1.toCharArray();
System.out.println(c.length);
System.out.println(c[0]);
0.3 python字节和字符串
##### python中字符串与字节
v1 = '彭于晏'
v2 = v1.encode('utf-8')
print(v2) # b'\xe5\xbd\xad\xe4\xba\x8e\xe6\x99\x8f' 16进制表示
v3 = v1.encode('GBK')
print(v3) # b'\xc5\xed\xd3\xda\xea\xcc' 16进制表示
# 转换为10进制
v3 = [item for item in v2]
print(v3) # [229, 189, 173, 228, 186, 142, 230, 153, 143]
# 转换为二进制
v4 = [bin(item) for item in v2]
print(v4) # ['0b11100101', '0b10111101', '0b10101101', '0b11100100', '0b10111010', '0b10001110', '0b11100110', '0b10011001', '0b10001111']
# 转换为16进制
v5 = [hex(item) for item in v2]
print(v5) # ['0xe5', '0xbd', '0xad', '0xe4', '0xba', '0x8e', '0xe6', '0x99', '0x8f']
0.4 java字节数组转python字符串
# 字节有无符号
Python字节无符号(不含负数): 0 ~ 255
0 1 2 3 4 5 ... 127 128 129 130 ... 255
Java字节是有符号(含有负数):-128 ~ 127
0 1 2 3 4 5 ...127 -128 -127 - 126 -125 .... -2 -1
# python:彭于晏
[229, 189, 173, 228, 186, 142, 230, 153, 143]
# java:彭于晏
[-27, -67, -83, -28, -70, -114, -26, -103, -113]
### 编写一个java字节数组转换为python的字符串代码
逻辑是:数字大于0,不操作,小于0,加上256
v1 = [-27, -67, -83, -28, -70, -114, -26, -103, -113]
def java_arr_to_python_str(v1):
num_list = bytearray()
for i in v1:
if i < 0:
i = i + 256
num_list.append(i)
return num_list.decode('utf-8')
if __name__ == '__main__':
print(java_arr_to_python_str(v1))
一 Object类
Object类是java.lang包下的核心类,Object类是所有类的父类,何一个类时候如果没有明确的继承一个父类的话,那么它就是Object的子类
以下两种类的定义的最终效果是完全相同的
class Person { }
class Person extends Object
1.1 Object类可以接受所有类的对象
public class Demo05 {
public static void main(String[] args) {
String name="justin";
int age =19;
Object v1=name;
v1=age;
Person p=new Person();
v1=p;
System.out.println(v1);
// 定义Object类型数组
Object[] arrs=new Object[3];
arrs[0]="justin";
arrs[1]=19;
arrs[2]=p;
System.out.println(Arrays.toString(arrs));
}
}
class Person{
}
1.2 Object 类的方法
Object 类属于
java.lang
包,此包下的所有类在使用时无需手动导入,系统会在程序编译期间自动导入
// 1. clone()
保护方法,实现对象的浅复制,只有实现了Cloneable接口才可以调用该方法,否则抛出CloneNotSupportedException异常。
// 2. getClass()
final方法,返回Class类型的对象,反射来获取对象。
//3. toString()
该方法用得比较多,一般子类都有覆盖,来获取对象的信息。
//4. finalize()
该方法用于释放资源。因为无法确定该方法什么时候被调用,很少使用。
//5. equals()
比较对象的内容是否相等
// 6. hashCode()
该方法用于哈希查找,重写了equals方法一般都要重写hashCode方法。这个方法在一些具有哈希功能的Collection中用到。
// 7. wait()
wait方法就是使当前线程等待该对象的锁,当前线程必须是该对象的拥有者,也就是具有该对象的锁。wait()方法一直等待,直到获得锁或者被中断。wait(long timeout)设定一个超时间隔,如果在规定时间内没有获得锁就返回。
调用该方法后当前线程进入睡眠状态,直到以下事件发生。
其他线程调用了该对象的notify方法。
其他线程调用了该对象的notifyAll方法。
其他线程调用了interrupt中断该线程。
时间间隔到了。
此时该线程就可以被调度了,如果是被中断的话就抛出一个InterruptedException异常。
// 8. notify()
该方法唤醒在该对象上等待的某个线程。
//9. notifyAll()
该方法唤醒在该对象上等待的所有线程。
/* 常用的
getClass()
toString()
hashCode()
*/
1.3 获取Object类型变量的具体类型
// 4 把Object转回具体类型
// 4.1 方式一
Person p = new Person();
Object[] names = new Object[]{"彭于晏", "刘亦菲", 19, p};
System.out.println(names[0].getClass()); // 返回具体的类型 class java.lang.String
System.out.println(names[3].getClass()); // 返回具体的类型 class Person
// 方式2 通过判断转换
if (names[0] instanceof String) {
String v1 = (String) names[0];
System.out.println(v1);
}
if (names[2] instanceof Integer) {
Integer a1 = (Integer) names[2];
System.out.println(a1);
}
if (names[3] instanceof Person) {
Person p1 = (Person) names[3];
System.out.println(p1);
}
二 容器类型之List
List是一个接口,接口下面有两个常见的类型(目的是可以存放动态的多个数据)
Java的数组只能放取,不能扩容缩容,增加删除元素
- ArrayList,连续的内存地址的存储(底层基于数组,内部自动扩容) -> Python列表的特点
- LinkedList,底层基于链表实现(底层基于链表) -> Python列表的特点
- 后面讲的ArrayList和LinkedList所有方法都一样,但是他们操作数据效率不一样
2.1 基本使用
import java.util.ArrayList; // 需要导入使用,编辑器会自动导入
import java.util.LinkedList;
public class Demo04 {
public static void main(String[] args) {
// List 接口类型:ArrayList和LinkedList
// 1 ArrayList
//// ArrayList l1 = new ArrayList(); // 定义ArrayList -->如果这样写,表示内部放的是Object类型
// ArrayList<Object> l1 = new ArrayList<Object>(); //上面等同于
// // 放入元素
// l1.add("彭于晏");
// l1.add("Justin");
// l1.add("留一份");
// l1.add(99); // 可以放任意类型
// l1.add(new Dog());
// System.out.println(l1);
//
// ArrayList<String> l2 = new ArrayList<String>();
//// l2.add(99); // 只能放字符串类型
// l2.add("xxxx");
//// l2.add('中'); // 字符类型也不可以
// 2 LinkedList
// LinkedList l1 = new LinkedList(); // 定义LinkedList-->如果这样写,表示内部放的是Object类型
LinkedList<Object> l1 = new LinkedList<Object>(); //上面等同于
// 放入元素
l1.add("彭于晏");
l1.add("Justin");
l1.add("留一份");
l1.add(99); // 可以放任意类型
l1.add(new Dog());
System.out.println(l1);
// LinkedList<String> l2=new LinkedList();
// LinkedList<String> l2=new LinkedList<>();
LinkedList<String> l2 = new LinkedList<String>();
l2.add("justin");
l2.add(11); //不行
}
}
class Dog {
}
2.2 接口概念(了解)
// 接口用来规范子类行为:java不允许多继承,实现多个接口,接口是就一个规范,规定了子类有那些方法,但是没有具体实现
// python 中不需要显示的继承一个类,只要类中有共同的属性或方法,他们就属于同一类
/**
* 定义了一个接口,规定,有两个方法,speak,run,我的子类,必须实现这俩方法
*/
interface Duck {
public void speak();
public void run();
}
class TDuck implements Duck {
public void speak() {
System.out.println("唐老鸭说话");
}
public void run() {
System.out.println("唐老鸭走路");
}
}
class PDuck implements Duck {
public void speak() {
System.out.println("普通鸭说话");
}
public void run() {
}
public void eat(){}
}
public class Demo05 {
public static void main(String[] args) {
//接口的概念
TDuck t = new TDuck();
PDuck p = new PDuck();
// 接口类型的变量,可以接收 实现
Duck d = t;
d = p;
}
}
2.3 指定类型的List及常用操作
import java.util.ArrayList;
import java.util.LinkedList;
public class Demo05 {
public static void main(String[] args) {
//***************** ArrayList 常用操作
// ArrayList<String> names = new ArrayList<String>();
// names.add("彭于晏");
// names.add("古天乐");
// names.add("杨颖");
//// names.add(19); //不能放数字
// names.add("刘亦菲");
// //1 根据索引取值
// String name = names.get(1);
// System.out.println(name);
//
// // 2 修改某个位置值
// names.set(1,"迪丽热巴");
// System.out.println(names);
//
// // 3 删除某个值
// names.remove("迪丽热巴");
// names.remove(0);
//
// // 4 大小
// System.out.println(names.size());
// // 5 是否包含
// System.out.println(names.contains("刘亦菲"));
//
// // 6 循环
// for (int i = 0; i < names.size(); i++) {
// System.out.println(names.get(i));
// }
//
// for (String item:names) {
// System.out.println(item);
//
// }
//***************** ArrayList 常用操作
LinkedList<String> names = new LinkedList<String>();
names.add("彭于晏");
names.add("古天乐");
names.add("杨颖");
// names.add(19); //不能放数字
names.add("刘亦菲");
//1 根据索引取值
String name = names.get(1);
System.out.println(name);
// 2 修改某个位置值
names.set(1,"迪丽热巴");
System.out.println(names);
// 3 删除某个值
names.remove("迪丽热巴");
names.remove(0);
// 4 大小
System.out.println(names.size());
// 5 是否包含
System.out.println(names.contains("刘亦菲"));
// 6 循环
for (int i = 0; i < names.size(); i++) {
System.out.println(names.get(i));
}
for (String item:names) {
System.out.println(item);
}
// 7 其他操作
names.push("xxx"); // 放在首位
names.addFirst("第一");
names.addLast("倒数第一");
System.out.println(names);
}
}
2.4 迭代
// 类似于python的迭代器
//ArrayList<String> names = new ArrayList<String>();
LinkedList<String> names = new LinkedList<String>();
names.add("彭于晏");
names.add("古天乐");
names.add("杨颖");
names.add("刘亦菲");
Iterator i =names.iterator();
while (i.hasNext()){
System.out.println(i.next());
}
三 容器类型之 Set
Set是一个接口,常见实现这个接口的有两个类,用于实现不重复的多元素集合。
- HashSet,去重,无序。
- TreeSet,去重,内部默认排序(ascii、unicode)【不同的数据类型,无法进行比较】。
3.1 基本使用
import java.util.Arrays;
import java.util.HashSet;
import java.util.TreeSet;
public class Demo04 {
public static void main(String[] args) throws Exception {
// HashSet使用
// HashSet h= new HashSet();
// HashSet<String> h= new HashSet<String>();
// // 1 基本使用
// h.add("刘亦菲");
// h.add("刘亦菲");
// h.add("迪丽热巴");
// h.add("古天乐");
// h.add("彭于晏");
// h.add("Justin");
//
// System.out.println(h);
//
// // 2 判断值是否存在
// System.out.println(h.contains("迪丽热巴"));
//
// // 3 删除元素
// h.remove("刘亦菲");
// System.out.println(h);
// // 4 长度
// System.out.println(h.size());
// TreeSet使用,自动排序
TreeSet<String> h = new TreeSet<String>();
// TreeSet<String> h = new TreeSet<String>(){{add("刘亦菲");add("迪丽热巴");}};
// 1 基本使用
h.add("刘亦菲");
h.add("刘亦菲");
h.add("迪丽热巴");
h.add("古天乐");
h.add("彭于晏");
h.add("Justin");
System.out.println(h);
// 2 判断值是否存在
System.out.println(h.contains("迪丽热巴"));
// 3 删除元素
h.remove("刘亦菲");
System.out.println(h);
// 4 长度
System.out.println(h.size());
}
}
3.2 交并差集
import java.util.Arrays;
import java.util.HashSet;
import java.util.TreeSet;
public class Demo04 {
public static void main(String[] args) throws Exception {
HashSet<String> h1 = new HashSet<String>();
h1.add("古天乐");
h1.add("彭于晏");
h1.add("Justin");
HashSet<String> h2 = new HashSet<String>();
h2.add("古力娜扎");
h2.add("杨颖");
h2.add("迪丽热巴");
h2.add("刘亦菲");
h2.add("Justin");
HashSet<String> h3 = new HashSet<String>();
h3.addAll(h2); // 把h2的所有数据增加到h3中
System.out.println(h3);
h3.retainAll(h1); // 交集 & [Justin]
System.out.println(h3);
h2.addAll(h1); // 并集 | [杨颖, 迪丽热巴, 古力娜扎, 刘亦菲, Justin, 古天乐, 彭于晏]
System.out.println(h2);
h2.removeAll(h1); // 差集 [杨颖, 迪丽热巴, 古力娜扎, 刘亦菲]
System.out.println(h2);
}
}
3.3 循环取值和迭代
import java.util.HashSet;
import java.util.Iterator;
public class Demo04 {
public static void main(String[] args) throws Exception {
HashSet<String> h1 = new HashSet<String>();
h1.add("古天乐");
h1.add("彭于晏");
h1.add("Justin");
// 循环
for (String item: h1) {
System.out.println(item);
}
//迭代
Iterator i=h1.iterator();
while (i.hasNext()){
System.out.println(i.next());
}
}
}
四 容器类型之Map
Map是一个接口,常见实现这个接口的有两个类,用于存储键值对。
HashMap,无序。
TreeMap,默认根据key排序。(常用)
4.1 基本使用
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.TreeMap;
public class Demo04 {
public static void main(String[] args) throws Exception {
// HashMap hm=new HashMap();
// hm.put("name","lqz");
// hm.put("age",19);
// hm.put("hobby","篮球");
// System.out.println(hm);
// HashMap<String,String> hm=new HashMap<String,String> ();
// hm.put("name","lqz");
// hm.put("age","19");
// hm.put("hobby","篮球");
// System.out.println(hm);
TreeMap<String,String> hm=new TreeMap<String,String> ();
hm.put("name","lqz");
hm.put("age","19");
hm.put("hobby","篮球");
System.out.println(hm);
}
}
4.2 常用操作
import java.util.*;
public class Demo04 {
public static void main(String[] args) throws Exception {
TreeMap<String,String> hm=new TreeMap<String,String> ();
hm.put("name","lqz");
hm.put("age","19");
hm.put("hobby","篮球");
System.out.println(hm);
// 1 移除元素
hm.remove("name");
System.out.println(hm);
// 2 大小
System.out.println(hm.size());
// 3 获取值
System.out.println(hm.get("name"));
//4 包含
System.out.println(hm.containsKey("name"));
System.out.println(hm.containsValue("篮球"));
//5 替换
hm.replace("age","99");
System.out.println(hm);
//6 循环 方式一 keySet
for (String key:hm.keySet()) {
System.out.println(hm.get(key));
}
// 循环方式 二 entrySet
for (Map.Entry<String,String> item:hm.entrySet()) {
System.out.println(item);
System.out.println(item.getKey());
System.out.println(item.getValue());
}
// 循环方式 三
Set s2 = hm.entrySet();
Iterator it2 = s2.iterator();
while (it2.hasNext()) {
Map.Entry entry = (Map.Entry) it2.next();
String k = (String) entry.getKey();
String v = (String) entry.getValue();
System.out.println(k);
System.out.println(v);
}
}
}
五 面向对象
5.1 类与对象构造方法
public class Demo09 {
public static void main(String[] args) {
//1 类实例化得到对象
// Animal a =new Animal(); //
// a.speak();
// 2 python中有__init__ 构造方法 有参和无参构造方法
// Animal a = new Animal(); //触发无参构造
Animal a1 = new Animal("Justin", 19);//触发有参构造
System.out.println(a1.name);
System.out.println(a1.age);
}
}
/**
* 定义类
*/
class Animal {
public String name;
public int age;
/**
* 构造方法,无参构造,构造方法可以写多个
*/
public Animal() {
System.out.println("我是无参");
}
/**
* 有参构造方法
*
* @param name
* @param age
*/
public Animal(String name, int age) {
System.out.println("我是有参");
// java中this 代指 python的self
this.name=name;
this.age=age;
}
public void speak() {
System.out.println("说话了");
}
}
5.1.1 方法重载
import java.util.*;
public class Demo04 {
public static void main(String[] args) throws Exception {
Person p =new Person();
System.out.println(p);
Person p1=new Person("Justin",99);
System.out.println(p1);
p.speak();
p.speak("说呀说");
}
}
class Person {
public String name;
public int age;
/**
* 构造方法一
*/
public Person() {
this.name = "justin";
this.age = 19;
}
/**
* 构造方法2
* @param name
* @param age
*/
public Person(String name, int age) {
this.name = name;
this.age = age;
}
/**
* speak方法,无参数
*/
public void speak(){
System.out.println("说哈");
}
/**
* speak方法,有参数,重载方法
*/
public void speak(String s){
System.out.println(s);
}
}
5.1.2 Hook重载的方法
/*
adb shell
su
cd /data/local/tmp/
./frida-server-16.0.19-android-arm64
端口转发
adb forward tcp:27042 tcp:27042
adb forward tcp:27043 tcp:27043
*/
import frida
import sys
# 连接手机设备
rdev = frida.get_remote_device()
session = rdev.attach("油联合伙人")
scr = """
Java.perform(function () {
// 包.类
var MessageDigest = Java.use("java.security.MessageDigest");
MessageDigest.update.overload('[B').implementation = function(data){
var res = this.update(data);
return res;
}
MessageDigest.update.overload('java.nio.ByteBuffer').implementation = function(data){
var res = this.update(data);
return res;
}
});
"""
script = session.create_script(scr)
def on_message(message, data):
print(message, data)
script.on("message", on_message)
script.load()
sys.stdin.read()
5.1.3 Hook构造方法
import frida
import sys
# 连接手机设备
rdev = frida.get_remote_device()
session = rdev.attach("油联合伙人")
scr = """
Java.perform(function () {
// 包.类
var StringBuilder = Java.use("java.lang.StringBuilder");
StringBuilder.$init.overload('int').implementation = function(num){
console.log(num);
if(num==32){
var res = this.$init(num);
}
return res;
}
});
"""
script = session.create_script(scr)
def on_message(message, data):
print(message, data)
script.on("message", on_message)
script.load()
sys.stdin.read()
5.2 静态成员(方法,变量)
public class Demo10 {
public static void main(String[] args) {
Cat c =new Cat("小野猫",4);
System.out.println(c.name); // 小野猫
Cat c1 =new Cat("大野猫",40);
System.out.println(c.name); // 大野猫
// python中有类属性,java的意思是用static修饰
// 静态成员,类可以来调用,对象也可以调用
c1.school="清华大学";
System.out.println(c1.school);
System.out.println(c.school); //改了静态成员,所有对象都受影响
// 通过类来改
Cat.school="北京大学";
System.out.println(c1.school);
System.out.println(c.school); //改了静态成员,所有对象都受影响
// 类和对象都可以调用静态方法
c1.speak();
Cat.speak();
}
}
class Cat{
// 这些成员属于对象的
public String name;
public int age;
// 静态成员,属于类的
public static String school;
public Cat(String name,int age){
this.name=name;
this.age=age;
}
public static void speak(){
// 静态方法,python中的类方法,对象可以调用,类也可以调用
System.out.println("猫喵喵叫");
}
}
5.3 继承
Java中的继承,只支持单继承,不支持多继承,但支持实现多个接口
5.3.1 java只支持单继承
// java中只允许单继承
public class Demo11 {
public static void main(String[] args) {
Fish f=new Fish();
f.eat();
f.eat("xxxxxxx");
}
}
class Base extends Foo{
public void eat(){
System.out.println("吃吃吃");
}
}
class Foo{
}
class Fish extends Base{
@Override // 子类中重写
public void eat() {
System.out.println("重写了eat方法");
}
public void eat(String a){// 重载
// 方法可以同名,参数不一样,这个叫重载,跟父类没有必然联系
System.out.println(a);
}
}
// java只允许单继承 使用extends ,子类中重写父类的方法叫重写
// 方法名相同,但是参数不同,叫重载 ,跟父类没有必然联系
5.3.2 实现多个接口
interface Base{
public void speak();
}
interface Foo{
public void run();
}
class Person implements Base,Foo{
@Override
public void speak() {
}
@Override
public void run() {
}
}