一.前言
昨天我们讲了点java基础,大家是不是觉得就特别简单,今天讲点稍微难一丢丢的基础,也就是java基础2.0,今天我要和大家说的内容十分的重要,直接关乎到下一节的内容,所以,好好学!
二.JAVA和Python字节,字符,字符串的比较
字符串在我们app逆向加解密毋庸置疑是最重要的。
先来了解一下字节
字节:一个字节是8个比特位,一个英文字符 a 永远占一个字节,
一个中文字符,占多少字节,取决于编码方式
GBK编码:一个中文字符, 占2字节
utf8编码:一个中文字符,占3个字节字符: 一个符号 比如: 中 国 ? ? ! a
2.1 java字符串常用方法
这里给出代码,常见的就12个,如果遇到不会的,就去问chatgpt,我们这里只需要看得懂就行
import java.util.Arrays;
public class main {
public static void main(String[] args) {
//(1)取出指定位置的字符串
//运用charAt()
String v1="蔡徐坤";
System.out.println(v1.charAt(1));
System.out.println("===========================================");
//(2)循环答应每个字符串
//主要是字符换有个.length()方法
for (int i = 0; i < v1.length(); i++) {
System.out.println(v1.charAt(i));
}
System.out.println("===========================================");
//(3)去除字符串前后空白
//主要运用到trim()
String v2=" 蔡徐坤 ";
System.out.println(v2);
System.out.println(v2.trim());
System.out.println("===========================================");
//(4)转大写
//主要运用toUpperCase() 可以发现只有小写会变成大写,其他不变
String v3="caiXU坤";
System.out.println(v3.toUpperCase());
System.out.println("===========================================");
//(5)转小写
//主要运用toLowerCase() 可以发现只有小写变了,其他不变
System.out.println(v3.toLowerCase());
System.out.println("===========================================");
//(6)字符串分割
//主要运用split() 可以发现结果是一个String数组,展示出来要调用Attays.toString
String v4="蔡,徐,坤";
String []v5=v4.split(",");
System.out.println(v5);
System.out.println(Arrays.toString(v5));
System.out.println("===========================================");
//(7)字符串替换
//主要运用了replace()
String v6="蔡徐坤";
String v7=v6.replace('蔡','吴');
System.out.println(v7);
System.out.println("===========================================");
//(8)字符串切片
//主要运用substring 左开右闭
String v8=v6.substring(1,3);
System.out.println(v8);
System.out.println("===========================================");
//(9)比较字符串是否相等
//主要运用equals 结果是bool形的
String v9="吴亦凡";
String v10="蔡徐坤";
boolean v11= v9.equals(v10);
System.out.println(v11);
System.out.println("===========================================");
//(10)比较字符串是否包含
//主要运用contains 结果是bool形的
boolean v12=v10.contains("徐坤");
System.out.println(v12);
System.out.println("===========================================");
//(11)判断是以xx开头的
//主要运用startsWith 结果是bool形的
boolean v13=v10.startsWith("蔡");
System.out.println(v13);
System.out.println("===========================================");
//(12)判断是以xx结尾的
//主要运用endsWith 结果是bool形的
boolean v14=v10.endsWith("坤");
System.out.println(v14);
}
}
运行截图
2.2 java字符串拼接
代码给出如下
public class main {
public static void main(String[] args) {
//字符串拼接
//方式1 主要采取相加方式,但是这种方式很low 一般见不到
String v1="蔡";
String v2=v1+'徐'+"坤";
System.out.println(v2);
System.out.println("===========================");
//方式2 以后我们会经常见到一下这两种方式
//(1)StringBuilder 线程不安全的
StringBuilder sb1=new StringBuilder();
sb1.append('蔡');
sb1.append("徐坤");
System.out.println(sb1);
System.out.println("===========================");
//(2)StringBuffer 可以发现用法都一样的 唯一的区别就是 线程安全的
StringBuffer sb2=new StringBuffer();
sb2.append("蔡徐");
sb2.append("坤");
System.out.println(sb2);
}
}
运行截图
问:什么是java中的线程安全什么是线程不安全?
Java中的线程安全(Thread Safety)和线程不安全(Thread Unsafe)是涉及多线程编程时重要的概念。理解它们对于编写并发安全的程序至关重要。
线程安全(Thread Safety)
定义: 当多个线程同时访问某个对象时,如果不需要额外的同步措施或者采取了必要的同步措施,这个对象被称为线程安全的。
线程不安全(Thread Unsafe)
定义: 如果一个对象在多线程环境中没有适当的同步措施,那么它被称为线程不安全的。多个线程同时操作这个对象可能导致不可预期的结果或数据损坏。
也就是说,在多线程条件下我们得选择StringBulider而不是StringBuffer,所以我们在逆向时可以不用管这个,当个知识点了解就好
2.3 java字节数组和字符串转换
代码给出如下
import java.util.Arrays;
public class main {
public static void main(String[] args) {
String v1="往日情怀酿作酒";
try {
//转码可能会报错,所以java要求进行异常捕获
//字符串转字节数组
byte[] b1=v1.getBytes("utf-8");
System.out.println(b1);
System.out.println(Arrays.toString(b1));
byte[] b2=v1.getBytes("GBK");
System.out.println(b2);
System.out.println(Arrays.toString(b2));
//字节数组转字符串
String v2=new String(b1,"utf-8"); //后面也可以不写,不写默认就是utf-8
System.out.println(v2);
//修改一下字节输出
b2[10]=11;
String v3=new String(b2,"gbk");
System.out.println(v3);
// 如果要改变字符串中某个位置的值,需要转成 字节数组,字符数组,,按位置改完,再转回字符串
}catch (Exception e){
}
}
}
运行结果如下
可以发现同样一个字符串gbk和utf编码打印结果不同,这个时候就要考考你们有没有好好读文章,你们要是不知道那我可要心寒啦!文章开头就说了,一个中文utf-8编码是3个字节,gbk编码是2个字符
tips:如果要修改字符串某个位置的字符,得先把他变成字节,字符数组,按位置修改完再转成字符串
2.4java字符数组和字符串转换
代码如下
import java.sql.Array;
import java.util.Arrays;
public class main {
public static void main(String[] args) {
//字符串转换成字符数组
String v1="往日情怀酿作酒";
char[] c1=v1.toCharArray();
System.out.println(c1);
System.out.println(c1[1]);
//字符数组转字符串
char[] c2=new char[]{'往','日','情','怀','酿','作','酒'};
String v2=new String(c2);
System.out.println(v2);
System.out.println(v2 instanceof String); //判断是否为String
}
}
运行截图
2.5 python字节和字符串
代码如下
v1 = '往日情怀酿作酒'
# 转成字节
v2 = v1.encode('utf-8')
print(v2) # 16进制展示 ,java的字符串转成字节数组后是用十进制展示
v3 = v1.encode('GBK')
print(v3) # 16进制展示 ,java的字符串转成字节数组后是用十进制展示
# 10 进制展示
v4 = [item for item in v2]
print(v4)
# 11 二进制展示
v5 = [bin(item) for item in v2]
print(v5)
# 16进制展示
v6=[hex(item) for item in v2]
print(v6)
# 去除16进制前面的0x
v7=[hex(item)[2:] for item in v2]
print(v7)
# java 中 字符串, 字节数组 字符数组
# python中 字符串 字节列表(16进制,2进制,10进制) 字符列表
运行截图如下
2.6 java字节数组和python字符串转换
首先我们得知道 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
我们可以看的出来以上区别,java和python之间的联系就是python大于等于0的和java一样,但是java小于0的加上255就是等于python,所以我们后期反编译要在python中获取原来的字符串,就得把java数组换成python的,这里给出转换的函数代码
# java字节数组转成python字符串
def java_arr_to_python_str(b):
num_list = bytearray()
for i in b:
if i < 0:
i = i + 256
num_list.append(i)
return num_list.decode('utf-8')
三.java的Object类
先来介绍一下object的·特点
Object 类是所有类的父类
只要是父类的对象,子类的对象都可以赋值给它
Object obj=new Object()
假设有Person类
Person person = new Person()obj=person
Object person = new Person()
Object 类的对象,可以接收任意类的对象
泛指
Object类
Animal类
-Person--》人
-Dog---》狗
人是动物
狗是动物Object a =new Person()
Object d=new Dog()也是为了让你的函数参数可以接受更多的类型
3.1 object类可以接受所有类型
代码如下
public class main {
public static void main(String[] args) {
//Object是所有对象的父类
//Object类可以接受任意对象
Object obj1="往日情怀酿作为酒";
System.out.println(obj1);
Object obj2=new Person();
System.out.println(obj2);
Object obj3=new String[]{"蔡徐坤","吴亦凡"};
System.out.println(obj3);
}
}
class Person{
}
运行截图如下
3.2 object类中的方法
-equals :判断两个对象是否相等
-getClass:获取这个对象的具体类
-toString 把对象转成字符串
3.3 获取object具体类型
代码如下
public class main {
public static void main(String[] args) {
Object obj=11;
System.out.println(obj.getClass()); // class java.lang.Integer 当成是int即可
Object obj2="往日情怀酿作酒";
System.out.println(obj2.getClass()); // class java.lang.String
Object obj3=new Person();
System.out.println(obj3.getClass()); // class Person
// 4 通过 instanceof 判断类型
System.out.println("" instanceof String);
// Object obj4=99; // 表面上的类型是Object ,但它具体是Integer,但是我们不能把obj4当Integer,必须做强制类型转换才能用
// Object obj4="ssss";
Object obj4=new Person();
if (obj4 instanceof Integer){
System.out.println("obj4是Integer类型");
Integer i =(Integer) obj4; // 强制类型转换
System.out.println(i);
} else if (obj4 instanceof Person) {
System.out.println("obj4是Person类型");
Person p =(Person)obj4;
System.out.println(p);
}else if (obj4 instanceof String) {
System.out.println("obj4是String类型");
String s =(String)obj4;
System.out.println(s);
}
}
}
class Person{
}
运行截图如下
四.容器类型-List
我们先来介绍一下List
List是一个接口,接口下面有两个常见的类型(目的是可以存放动态的多个数据)
ArrayList,连续的内存地址的存储(底层基于数组,内部自动扩容) -> Python列表的特点
LinkedList,底层基于链表实现(底层基于链表) -> Python列表的特点
4.1 ArrayList 用法
代码如下
import java.util.ArrayList;
public class main {
public static void main(String[] args) {
ArrayList al1=new ArrayList();
ArrayList<String> al2 =new ArrayList<String>(); //代表这个只能存放String,不写就是默认<Object>
//ArrayList 的常用操作
//(1)添加元素
//主要是调通了add()
al2.add("蔡徐坤");
al2.add("吴亦凡");
System.out.println(al2);
//(2)根据索引取值
//主要调用了get()
String name=al2.get(0);
System.out.println(name);
//(3)修改某个位置元素
//主要调用了set()
al2.set(1,"马嘉祺");
System.out.println(al2);
//(4)删除某个位置
//主要调用了remove()
al2.remove(1);
System.out.println(al2);
//(5)长度
//主要调用了sixe()
System.out.println(al2.size());
//(6)是否包含
//主要调用了contains()
boolean v1= al2.contains("蔡徐坤");
System.out.println(v1);
//(7)循环:两种方式
//方式1
for (int i = 0; i <al2.size() ; i++) {
System.out.println(al2.get(i));
}
//方式2
for (String item:al2){
System.out.println(item);
}
}
}
运行截图如下
4.2 LinkedList用法
方法和ArrayLiat基本一样,但是多了两条在头部和尾部插入元素 ArrayLiat不行
代码如下
import java.util.LinkedList;
public class main {
public static void main(String[] args) {
LinkedList al1=new LinkedList();
LinkedList<String> al2 =new LinkedList<String>(); //代表这个只能存放String,不写就是默认<Object>
//ArrayList 的常用操作
//(1)添加元素
//主要是调通了add()
al2.add("蔡徐坤");
al2.add("吴亦凡");
System.out.println(al2);
//(2)根据索引取值
//主要调用了get()
String name=al2.get(0);
System.out.println(name);
//(3)修改某个位置元素
//主要调用了set()
al2.set(1,"马嘉祺");
System.out.println(al2);
//(4)删除某个位置
//主要调用了remove()
al2.remove(1);
System.out.println(al2);
//(5)长度
//主要调用了sixe()
System.out.println(al2.size());
//(6)是否包含
//主要调用了contains()
boolean v1= al2.contains("蔡徐坤");
System.out.println(v1);
//(7)循环:两种方式
//方式1
for (int i = 0; i <al2.size() ; i++) {
System.out.println(al2.get(i));
}
//方式2
for (String item:al2){
System.out.println(item);
}
//LinkList独有的
//在头部尾部插入元素
al2.addLast("尾部");
al2.addFirst("头部");
System.out.println(al2);
}
}
运行截图如下
五.容器类型-Map
Map的介绍
Map是一个接口,常见实现这个接口的有两个类,用于存储键值对。
- HashMap,无序。
- TreeMap,默认根据key排序。(常用)
5.1 HashMap和TreeMap
HashMap和TreeMap的方法都一样,唯一就是有序和无序的区别,这里避免又臭又长,我就只给出TreeMap的代码,因为TreeMap较为常用。(自闭了,写到这里已经刚好凌晨两点半,八千五百字了,自闭自闭,看个哥哥的视频就睡觉,肝不动了,搞了五个小时)
今天重新开始!
代码给出如下,最后一个循环有点难理解。等讲完基础三就差不多了,这里先不给出结束
import java.util.*;
public class main {
public static void main(String[] args) {
// 1 定义HashMap
// HashMap hm=new HashMap(); //用的很少
// HashMap<String, String> hm = new HashMap<String, String>();
TreeMap<String, String> hm = new TreeMap<String, String>();
//(1)增加元素
//主要调用put()
hm.put("name", "蔡徐坤");
hm.put("hobby", "篮球");
System.out.println(hm);
//(2)获取元素
//主要调用get
System.out.println(hm.get("name"));
//(3)移除元素
//主要调用remove()
hm.remove("name");
System.out.println(hm);
//(4)大小
//主要调用size()
System.out.println(hm.size());
//(5)是否包含key和value
//key 调用containsKey()
//value 调用containsValue()
System.out.println(hm.containsKey("name"));
System.out.println(hm.containsValue("蔡徐坤"));
//(6)替换
//主要调用replace()
hm.replace("hobby", "唱跳rap"); // hm["age"]=88
System.out.println(hm);
System.out.println("-------------------");
//(7)循环,三种循环方式
// 简单 基本后面见不到
for (String key : hm.keySet()) { // 循环得到key,根据key拿到value值
System.out.println(hm.get(key));
}
System.out.println("-------------------");
// 方式二:
for (Map.Entry<String, String> item : hm.entrySet()) {
System.out.println(item.getKey());
System.out.println(item.getValue());
}
System.out.println("-------------------");
// 方式三:以后不会写--》后面讲到会带你回来回顾 这个方式可以循环map
Set s2 = hm.entrySet();
Iterator it2 = s2.iterator();
while (it2.hasNext()) {
Map.Entry<String, String> item = (Map.Entry) it2.next();
String key = item.getKey();
String value = item.getValue();
System.out.println(key);
System.out.println(value);
}
}
}
运行截图如下
六.面向对象
6.1 类与对象
在程序中,先有类后有对象
例如,先定义一个人类,实例化得到一个对象,这个对象可以是蔡徐坤,吴亦凡,类中有所有人类的公有属性,例如,吃饭,睡觉等等,对象中可以定义各自的属性,例如名字,爱好,唱跳rap等等。(是不是特别好理解)
如何定义类,如何实例化得到对象?
定义类
class Person{
}
实例化得到对象
Person zhangsan=new Person();
Person lisi=new Person();
6.2 构造方法
代码给出如下
public class main {
public static void main(String[] args) {
//实例化得到对象
Person zhangsan=new Person("蔡徐坤","篮球");
Person lisi=new Person("吴亦凡","吃大碗宽面");
System.out.println(zhangsan.name);
System.out.println(lisi.name);
// 有参构造,无参构造
Person p=new Person(); // 触发无参构造
System.out.println(p.name);
Person p1=new Person("往日情怀酿作酒");
System.out.println(p1.name);
// 多个构造函数
Person p2=new Person("justin");
System.out.println(p2.name);
System.out.println(p2.hobby);
}
}
//定义类
class Person{
String name;
String hobby;
//使用public修饰,没有返回值,跟类同名的 方法,称之为构造方法,类实例化的时候自动触
public Person(String name,String hobby){
this.name=name;
this.hobby=hobby;
}
//构造方法可以有多个,根据参数数量来判断走哪个
public Person(){ //无参构造
this.name="默认名字";
this.hobby="默认爱好";
}
public Person(String name){ //有参构造
this.name=name;
}
}
运行截图:
6.3 静态方法和成员方法
代码如下
//这个我纠正就正经一点,我一直都正经不是吗
public class main {
public static void main(String[] args) {
Dog dog = new Dog("小野狗");
String name = dog.showName();
System.out.println(name);
dog.run();
Dog.showDog();
}
}
//定义类
class Dog{
String name;
public Dog(String name){
this.name=name;
}
//定义方法 方法属于对象,为不是类,只能是实例化对象才能用
public String showName(){
return this.name+"--傻狗";
}
//无返回值,用void修饰
public void run(){
System.out.println(this.name);
System.out.println("狗走路");
}
//定义静态方法 用static修饰 类用而不是对象用
public static void showDog(){
//类用,拿不到this
System.out.println("默认小狗");
}
}
运行截图
6.4 继承重载和重写
java中只允许单继承,不能多继承,不能同时继承多个类
代码如下
public class main {
public static void main(String[] args) {
Cat cat = new Cat();
// cat.run(); //cat 调用父类的方法,子类中没有,会调用父类
cat.run(); //没传参数,会触发没有参数的run方法
cat.run("xxx"); //传参数,会触发有参数的run方法
}
}
//定义类
class Animal{
public void run(){
System.out.println("动物走路");
}
}
//继承,用extends修饰
class Cat extends Animal{
//重载父类中的run方法
@Override //自动生成 写不写都行
public void run() {
super.run(); //调用父类中的run方法 不行就不会调用
System.out.println("猫走路");
}
//重写
public void run(String name) { // 类中,只要函数名一样,但是参数和返回值不一样,这个叫重载方法
System.out.print(name);
System.out.println("重载方法");
}
}
运行截图
七.总结
总结,今天讲了java基础2.0真的是又臭又长,大家做个了解就好了,又不是做开发,看得懂就好了,遇到不懂的就去chatgpt。多看看就会了,主要这是混个眼熟,刚好也适合java初学者的使用。
八.下期预告
下期我们将会说java基础最后的,也就是基础中最难的,面向对象,多态继承封装。今天最后也提了面向对象。就是为了下一期服务的。
补充
如有需要学习资料和交流加我绿泡泡
这里插入一条广告(希望理解一下,养家糊口)!!!
有需要逆向需求或者是项目,课设等等,都能找我接单,麻烦大家了
公众号(后续会更新相关文章)
期待你的关注!