八期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包,此包下的所有类在使用时无需手动导入,系统会在程序编译期间自动导入

image-20230629134852387

// 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 接口概念(了解)

image-20230702155736322


// 接口用来规范子类行为: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() {

    }
}
posted @ 2023-07-02 16:27  凫弥  阅读(23)  评论(0编辑  收藏  举报