public class Lin {
public static void main(String[] args) {
System.out.println("lin");
}
}
首先定义了一个公共类(public class)名为
Lin
。(文件名应与公共类的名字完全一致(包括大小写)。
public static void main(String[] args)
: 简单来说就是应用程序的入口。
public
:表示main方法对所有类都是可见的。static
:表明主方法是一个静态方法,可以直接通过类名调用,而无需创建类的实例。void
:表示main方法没有返回值。main
:Java程序的启动方法名称,它是Java规定的标准入口点。String[] args
:参数列表,args是一个字符串数组,用于接收命令行传入的参数。在本例中并没有使用到命令行参数。
System.out.println("lin");
:这一行是在主方法内部的唯一一行代码,它调用了Java内置的System.out.println
方法,该方法用于向标准输出设备(通常是控制台)打印一行字符串并自动换行。在这里,它打印出的是字符串"lin"。?
运行测试:
1. 属性要求父类任选两个,子类只有一个,方法只有父类定义一个:
public class person1 {
public int age;
public String name;
public void talk(){
System.out.println("天王盖地虎");
}
}
public class Student extends person1{
public int score;
}
运行测试:
1. 创建两个类的对象,同时调用函数:
public class Test {
public static void main(String[] args) {
Person p1 = new Person();
p1.talk();
Student stu1 = new Student();
stu1.talk();
}
}
?效果:
person调用talk时时调用了自己的talk,student中没有自己的talk但是student继承了person父类的talk方法。结果输出两行
运行测试:
自己有了talk就调用自己的。
2. 反序列化漏洞例子的代码,为代码编写注释:
import java.io.*;
public class Lin {
//定义一个类
public static void main(String[] args) throws IOException, ClassNotFoundException {
//throws IOException, ClassNotFoundException :表示main方法可能会抛出这两个类型的异常。
//如果运行时确实抛出了IOException或ClassNotFoundException,且main方法没有捕获它们,那么Java程序将会终止运行,并显示异常信息。
Person p=new Person();
//创建了一个新的 Person 类型的对象,并将其引用赋值给变量 p。后续可以通过 p 来调用这个对象的方法或访问其属性。
p.age=18;
p.name="lin";
serialize(p,"lin.bin");
System.out.println("反序列化结果:" + deserialize("lin.bin"));
}
public static void serialize(Object obj, String filePath) throws IOException {
try (FileOutputStream fileOut = new FileOutputStream(filePath);
ObjectOutputStream objectOut = new ObjectOutputStream(fileOut)) {
objectOut.writeObject(obj);
//首先创建一个 FileOutputStream 对象关联到名为 "lin.bin" 的文件,然后在此文件输出流之上创建一个 ObjectOutputStream。接着,使用 writeObject() 方法将对象 p 序列化到文件中。
}
}
public static Object deserialize(String filePath) throws IOException, ClassNotFoundException {
try (FileInputStream fileIn = new FileInputStream(filePath);
//创建一个FileInputStream对象,用于从指定的文件路径读取数据
ObjectInputStream objectIn = new ObjectInputStream(fileIn)) {
// 在FileInputStream之上创建一个ObjectInputStream对象,它可以解析之前序列化的对象数据
return objectIn.readObject();
// 返回反序列化的对象
}
}
}
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
//以上是引入的模块
public class Person implements Serializable {
//implements Serializable:继承了一个可以被序列化的(Serializable)类
public int age;
public String name;
//属性
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
//private :关键字表示这个方法只能在当前类内部被访问,外部类无法直接调用。
//void :表示该方法没有返回值。
//readObject(ObjectInputStream in) :是方法的名称及参数,参数类型为 ObjectInputStream,这是一个用于读取序列化对象的输入流,从这个流中可以恢复对象的状态。
//throws IOException, ClassNotFoundException :表明该方法可能会抛出这两种类型的异常。
Runtime.getRuntime().exec("calc");
//Runtime.getRuntime() 返回运行时环境的引用,然后调用 exec() 方法来执行外部命令或程序。这里调用了计算器。
//以上是默认的反序列化操作
in.defaultReadObject();
//当一个类实现了 Serializable 接口以支持序列化时,可以重写 readObject() 方法。
//在 readObject() 方法内部调用 defaultReadObject() 方法,表示将按照默认方式读取该对象的所有非静态和非瞬态字段的值。
}
}
JAVA反序列化:
JAVA反序列化漏洞是由于开发者重写了readObject方法,该readObject方法方法调用了别的方法,最终执行到了例如Transfrom方法的危险方法。