Java基础之Scanner类和对象序列化4月打卡day27

举报
java厂长 发表于 2022/04/13 09:36:37 2022/04/13
【摘要】 Java基础之Scanner类和对象序列化4月打卡day27关于作者作者介绍🍓 博客主页:作者主页🍓 简介:JAVA领域优质创作者🥇、一名在校大三学生🎓、在校期间参加各种省赛、国赛,斩获一系列荣誉🏆。🍓 关注我:关注我学习资料、文档下载统统都有,每日定时更新文章,励志做一名JAVA资深程序猿👨‍💻。1、Scanner这个类是作为了一个工具类出现的,在Scanner之中定义两个...

Java基础之Scanner类和对象序列化4月打卡day27

关于作者

  • 作者介绍


🍓 博客主页:作者主页

🍓 简介:JAVA领域优质创作者🥇、一名在校大三学生🎓、在校期间参加各种省赛、国赛,斩获一系列荣誉🏆。

🍓 关注我:关注我学习资料、文档下载统统都有,每日定时更新文章,励志做一名JAVA资深程序猿👨‍💻。

1、Scanner

这个类是作为了一个工具类出现的,在Scanner之中定义两个如下的一些方法:

public Scanner(InputStream sourse); 构造方法
public Boolean hasNextXxx(); 判断是否有数据
public 数据类型 nextXxx(); 取得数据
public Scanner useDelimiter(String partern); 定义分隔符

以后调用的时候在执行nextXxx()之前一定要首先使用hasNextXxx()判断是否有指定格式的数据出现。

通过Scanner类进行数据的输入

package com.day15.demo;
​
import java.util.Scanner;
​
public class ScannerDemo {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入数据:");
        if(sc.hasNext()){//现在有输入的内容,不能判断空字符串
            System.out.println(sc.next());
        }
        sc.close();
    }
}

使用Scanner类判断输入数据是否是int型数据

package com.day15.demo;
​
import java.util.Scanner;
​
public class ScannerDemo {
    public static void main(String[] args) {
        System.out.println("请输入数据:");
        Scanner sca=new Scanner(System.in);
        if(sca.hasNextInt()){
            int date=sca.nextInt();
            System.out.println("输入的数据是:"+date);
        }else{
            System.out.println("输入的不是数字");
        }
    }
}

在Scaner类之中,useDelimiter()方法的输入针对于字符串,但是其他的数据类型并不方便使用。

使用Scanner类判断用户输入的是不是生日

package com.day15.demo;
​
import java.util.Scanner;
​
public class ScannerDemo {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入生日:");
        if(sc.hasNext("\\d{4}-\\d{2}-\\d{2}")){//现在有输入的内容,不能判断空字符串
            String bir = sc.next("\\d{4}-\\d{2}-\\d{2}");
            System.out.println(bir);
        }
        sc.close();
    }
}

Scanner读取文件内容

package com.day15.demo;
​
import java.io.File;
import java.io.FileInputStream;
import java.util.Scanner;
​
public class ScannerDemo {
    public static void main(String[] args) throws Exception{
        Scanner sc = new Scanner(new FileInputStream(new File("f:" + File.separator + "test" + File.separator + "hello.txt")));
        sc.useDelimiter("\n");
        if(sc.hasNext()){//现在有输入的内容,不能判断空字符串
            System.out.println(sc.next());
        }
        sc.close();
    }
}

除了二进制文件拷贝处理之外,只要针对于程序的信息输出都使用打印流,对于信息的输入都是Scanner。

2、对象序列化

所有的项目都一定有序列化的概念。

2.1 对象序列化的概念

所谓的对象序列化是指在内存中保存的对象变为二进制流的形式进行传输,或者将其保存在文本中。但是我们并不意味着所有对象都可以被序列化,严格来讲,我们需要被实例化的类对象往往需要传输使用,同时这个类 必须实现java.io.Serializable接口。但是这个接口没有任何方法定义,所以只是一个标识。

package com.day15.demo;
​
import java.io.Serializable;
​
class Person implements Serializable{
    private String name;
    private int age;
    public Person(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;
    }
}
public class SerializableDemo {
​
}

序列化对象是所需要保存的就是对象中的属性所以默认情况下对象的属性将被转为二进制数据流存储。

2.2 实现序列化和反序列化

如果要想进行对象的序列化和反序列话的手工操作,在java之中提提供了两个操作类:ObjectOutputStream,ObjectInputStream,而这两个类的继承结构,构造方法,操作方法定义如下:

ObjectOutputStream ObjectInputStream
java.lang.Object java.io.OutputStream java.io.ObjectOutputStream java.lang.Object java.io.InputStream java.io.ObjectInputStream
public ObjectOutputStream(OutputStream out) throws IOException public ObjectInputStream(InputStream in) throws IOException
public final void writeObject(Object obj) throws IOException public final Object readObject() throws IOException,ClassNotFoundException

image-20210819210231615

image-20210819210310589

实现对象的序列化操作

package com.day15.demo;
​
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Arrays;
​
class Person implements Serializable{
    private String name;
    private int age;
    public Person(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 "Person [name=" + name + ", age=" + age + "]";
    }
}
public class SerializableDemo{
    public static final File FILE = new File("F:" + File.separator + "test" + File.separator + "person.txt");
    public static void ser(Object o) throws Exception {
        ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(FILE));
        outputStream.writeObject(o);
        outputStream.close();
    }
    public static void dser() throws Exception {
        ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(FILE));
        System.out.println(inputStream.readObject());
        inputStream.close();
    }
    public static void main(String[] args) throws Exception{
        //序列化
        //ser(new Person("张麻子",20));
        //反序列化
        dser();
    }
}

如果出现com.day15.demo.Person@6d311334这个情况的主要原因是因为实体类没有进行toString()方法的重写。

2.3 transient关键字(了解)

实际上序列化的处理在Java.io有两类,Serializable是使用最多的序列化接口,这种操作采用自动化的模式完成,默认情况下所有的属性都会进行序列化。有一个Externalizable接口需要用户手动序列化处理。

由于默认情况Serializable会将对象中的所有属性进行保存,但是如果现在有某些属性不希望被保存了,那么可以使用transient关键字。

使用transient

package com.day15.demo;
​
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Arrays;
​
class Person implements Serializable{
    private transient String name;
    private int age;
    public Person(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 "Person [name=" + name + ", age=" + age + "]";
    }
}
public class SerializableDemo{
    public static final File FILE = new File("F:" + File.separator + "test" + File.separator + "person.txt");
    public static void ser(Object o) throws Exception {
        ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(FILE));
        outputStream.writeObject(o);
        outputStream.close();
    }
    public static void dser() throws Exception {
        ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(FILE));
        System.out.println(inputStream.readObject());
        inputStream.close();
    }
    public static void main(String[] args) throws Exception{
        ser(new Person("张麻子",20));
        dser();
    }
}
/*
Person [name=null, age=20]
*/

发现此处name没有进行序列化操作。使用序列化往往在简单java类上使用,其他类上使用序列化的使用很少,但是在简单java类中基本上不去使用transient。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。