Java从入门到放弃14

序列化和反序列化

Java在运行时,如果需要保存对象的状态(即下次程序运行时,能够还原对象当前的状态),就需要使用到序列化操作。本质是吧对象保存为一个文件存到磁盘上,下次运行时从磁盘上读取文件,恢复对象。

网络程序:如果把一个对象从一台机器(虚拟机)发送到另外一台机器(虚拟机),这种情况也需要把对象序列化为二进制内容,然后再通过网络发送给另外一台机器,对方收到二进制内容,在反序列化为对象。

ObjectOutputStream 序列化

把正在运行的对象保存为文件;

要被序列化的对象的类要实现Serializable接口;

  • Student
package com.hqyj;

import java.io.Serializable;

public class Student implements Serializable {
    private String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
  • 利用ObjectOutputStream的writeObject方法做序列化
package com.hqyj;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class SerializeDemo {
    public static void main(String[] args) {
        /*Student student = new Student();
        student.setName("张三");
        student.setAge(18);*/
        Student student = new Student("张三", 18);
        ObjectOutputStream oos = null;
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream("E:/student.data");
            oos = new ObjectOutputStream(fos);
            oos.writeObject(student);//序列化student对象
            oos.flush();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(oos != null){
                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos != null){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

ObjectInputStream 反序列化

  • 调用readObject()反序列化,该方法返回的是Object,所以要强制类型转换;
  • 读取的序列化的文件一定要是正确的序列化,并且要强制类型转换。
package com.hqyj;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class DeSerializeDemo {
    public static void main(String[] args) {
        FileInputStream fis = null;
        ObjectInputStream ois = null;
        try {
            fis = new FileInputStream("E:/student.data");//之前序列化的文件名
            ois = new ObjectInputStream(fis);
            //读取序列化的文件,还原为原来的对象(对象的属性都还在)
            Student student = (Student) ois.readObject();
            System.out.println(student);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }finally {
            if (ois != null){
                try {
                    ois.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fis != null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

复习

  • 构造方法在什么时候使用?有参和无参的区别在哪里?
    1. 构造方法在创建对象(实例化)的时候会被调用(也就是使用new Xxx());
    2. 子类创建对象时会先调用父类的构造方法,然后再调用子类的构造方法,没有指定调用的构造方法时,会自动调用父类的无参构造方法。
    3. new的关键字使用的时候,类名后面的小括号里面有几个参数就会调用对应参数数量的构造方法。调用有参构造方法的目的是创建对象的同时给属性赋值。

常量池中存的是一种对象吗

  1. 常量池中存的也是对象,主要针对String类型,如果用字面量赋值的String变量,就会在常量池中创建一个对象;下一次再用相同的字符串给变量赋值的时候,就共用常量池中的一个对象;
  2. 基本类型赋值不会创建对象。

instanceof的作用是判断一个对象是否是某个类型。

关于方法的调用

  1. 方法是用来执行某一个特定功能的一段代码,方法可以重复使用,使main里面的代码尽量的简洁;
  2. 方法是类的一种组成部分。

方法的定义:

public int fun1(int i, String s){

​ //方法体,方法类的代码

​ return 0;

}

方法的调用:

int j = fun1(5, “abc”);

  • 重写和重载的区别

  • 可变长参数

    定义方法时,参数类型后面跟三个点,这个参数就叫可变长参数,调用该方法可以传多个参数,可变长参数只能是最后一个参数。

  • 方法里面的变量都是局部变量,方法里面的引用类型的变量只保存对象的地址,实际对象存在堆里面;

    方法被调用的时候在栈里面会有一段内存(方法栈帧)保存局部变量,方法调用时入栈,方法调用结束后出栈,出栈后释放栈帧的内存,局部变量不可在访问。

    如果方法里面调用另一个方法(如s调用b),a方法暂停运行,先执行b方法,等b方法执行结束后,在执行a方法。

try语句块中出现return语句,finally仍然会执行;

即便是在try语句块里面出现Error,Finally也会执行。

抽象 abstract

  1. 抽象可以修饰类,方法;

  2. 抽象方法,就是这个方法没有方法体(没有代码),抽象方法的目的是为了统一方法的定义,具体的实现交给子类去实现。一般来说抽象方法在每个子类中的实现都不一样。如果不规定方法名,每个子类就可能写出不同的方法名,不方便向上造型之后的统一调用方法;

  3. 一个类中只要有一个方法是抽象方法,这个类就必须定义为抽象类。抽象类中可以没有抽象方法;

  4. 如果抽象类中所有的方法都是抽象方法,这个抽象方法就可以定义为接口(interface),interface的子类就用implements关键字实现接口,可以实现对公接口,接口可以相互继承;

  5. 接口里面的方法如果不写访问修饰符,默认就是public,如果不写访问修饰符,默认就是public static final(常量)。

Static

static可以是修饰符,方法,属性,代码块;

static是属于类的,不属于对象;

  1. static在类加载的时候执行,不是创建对象时执行;
  2. static是所以对象共享的,不属于对象独有;
  3. static的访问可以直接用类名访问,static的方法只能访问static的属性或方法;
  4. 序列化时不会序列化类的静态成员。

练习

  1. 给出一个数组{5, 7, 20, 18, 6},找出数组中最大的元素。

  2. public class Biggest {
        public static void main(String[] args) {
            int[] arr = {5, 7, 20, 18, 6};
            int max = 0;
            for (int i = 1; i < arr.length; i++) {
                max = arr[max] > arr[i] ? max : i;
            }
            System.out.println(arr[max]);
        }
    }
    
  3. 双色球号码生成:

    6个红球,红球范围1~32,随机生成,不能有重复;

    1个蓝球,蓝球范围1~7

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class TwoColorBall {
    public static void main(String[] args) {
        Random random = new Random();
        List<Integer> list = new ArrayList<>();
        System.out.print("红球:");
        for (int i = 0; i < 6; i++) {
            int n = random.nextInt(32) + 1;
            if (list.contains(n)){//判断是否重复,重复返回true,不重复返回false
                i--;
            }else{
                list.add(n);
                System.out.print(n + "\t");
            }
        }
        System.out.println();
        int m = random.nextInt(7) + 1;
        System.out.println("蓝球:" + m);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
大数据是一个广泛的领域,涉及到数据收集、存储、处理和分析等方面。想要入门大数据,你可以按照以下步骤进行: 1. 学习基础知识:了解大数据的基本概念、技术背景和应用场景。可以阅读相关书籍、网上教程或参加在线课程,掌握大数据的基本理论知识。 2. 学习数据处理工具:掌握常见的大数据处理工具,例如Hadoop、Spark等。可以通过安装和配置这些工具来学习它们的使用方法,并尝试使用它们处理一些简单的数据。 3. 学习编程语言:掌握至少一门编程语言,例如Python、Java等。编程语言在大数据处理中起到重要作用,可以使用它们来编写数据处理程序和脚本。 4. 实践项目:通过实践项目来巩固所学知识。可以选择一些简单的数据处理任务,例如数据清洗、数据分析等,逐步提高自己的技能。 5. 深入学习:如果对大数据领域有更深入的兴趣,可以学习更高级的技术,例如分布式计算、机器学习和人工智能等。这些知识可以帮助你在大数据领域取得更进一步的发展。 放弃与否取决于个人对大数据领域的兴趣和动力。大数据是一个快速发展的领域,对于持续学习和不断更新知识的人来说,提供了丰富的机会和挑战。如果你对数据分析和处理有浓厚的兴趣,并且愿意进行持续学习和实践,那么入门大数据是一个值得尝试的选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

深夜食堂℃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值