Java进阶4:泛型、序列化和反序列化

Java泛型

  • Java泛型是JDK5引入的一个新的特性,泛型提供了编译时的类型安全检测机制,这个机制运行程序员在编译的时候检测到非法的类型。
  • 泛型的本质是参数化类型,也就是所操作的数据类型被指定为一个参数。
泛型方法
  • 可以写一个泛型方法,这个方法在调用时候可以接受不同类型的参数,根据参数类型适当调用一个方法。
  • 定义泛型方法的规则

声明类型参数部分<>,定义在返回类型之前
声明多个类型参数,彼此用逗号隔开
类型参数能被用于声明返回值类型,并且能作为泛型方法得到的实际参数类型的占位符
方法体的声明和其他的方法一样,但是只能是代表引用型类型

  • 泛型标记符

E–Element(元素)
T–Type(Java类)
K–Key(键)
V–Value(值)
N–Number(数值类型)
?–不确定的类型

  • 声明实例,声明一个方法用于遍历各种数组
public class generics {
    //遍历元素的方法
    public static <E> void printArray(E[] type){
        for(E item:type){
            System.out.print(item);
        }
        System.out.println();
    }
}
public class Init {
    //main函数,程序入口
    public static void main(String[] args) {
        // 创建不同类型数组: Integer, Double 和 Character
        Integer[] intArray = { 1, 2, 3, 4, 5 };
        Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4 };
        Character[] charArray = { 'H', 'E', 'L', 'L', 'O' };
        generics.printArray(intArray);
        generics.printArray(doubleArray);
        generics.printArray(charArray);
    }
}
  • 界定类型参数
    有时候需要限制被允许传到一个类型参数种类范围。这需要用extends关键字来界定范围
public class Init {
    public static <T extends Comparable<T>> T maximum(T x, T y, T z){
    //使用Comparable<T>对范围进行界定,必须是可以被比较的类型
        T max = x; // 假设x是初始最大值
        if ( y.compareTo( max ) > 0 ){
            max = y; //y 更大
        }
        if ( z.compareTo( max ) > 0 ){
            max = z; // 现在 z 更大
        }
        return max; // 返回最大对象
    }

    //main函数,程序入口
    public static void main(String[] args) {
        System.out.printf( "%d, %d 和 %d 中最大的数为 %d\n\n",
                3, 4, 5, maximum( 3, 4, 5 ) );

        System.out.printf( "%.1f, %.1f 和 %.1f 中最大的数为 %.1f\n\n",
                6.6, 8.8, 7.7, maximum( 6.6, 8.8, 7.7 ) );

        System.out.printf( "%s, %s 和 %s 中最大的数为 %s\n","pear",
                "apple", "orange", maximum( "pear", "apple", "orange" ) );
    }
}
泛型类
  • 泛型类的定义只是在后面添加了类型参数的声明部分。
public class Box<T> {

        private T t;

        public void add(T t) {
            this.t = t;
        }

        public T get() {
            return t;
        }
类型通配符
  • 使用?代替具体的类型参数
  • 例如List<?>是所有的List以及List等具有具体类型参数的父类
import java.util.*;
public class Init {
        public static void getData(List<?> data) {
            System.out.println("data :" + data.get(0));
        }

        public static void main(String[] args) {
            List<String> name = new ArrayList<String>();
            List<Integer> age = new ArrayList<Integer>();
            List<Number> number = new ArrayList<Number>();

            name.add("icon");
            age.add(18);
            number.add(314);

            getData(name);
            getData(age);
            getData(number);
        }
}
  • 因为 getData() 方法的参数是 List<?> 类型的,所以 name,age,number 都可以作为这个方法的实参,这就是通配符的作用。

  • 对于通配符也可使用限定:List<? extends Number>

序列化

  • 一个对象可以被表示为一个字节序列,这个字节序列包含了这个对象的数据。
  • 将序列化写入文件之后还可以从文件中读取出来,并且对其进行反序列化。
  • 过程在Java虚拟机中独立,可以直接跨平台进行序列化和反序列化。
  • 如果一个类要想实现序列化,必须满足两个条件:

必须实现java.io.Serializable接口
这个类的所有属性必须是可被序列化的,如果有一个属性不能被序列化,这个属性必须被声明为短暂的

  • 下面的实例指明了构造一个可以被序列化的类
public class serializable implements java.io.Serializable {
    public String name;
    public String address;
    public transient int SSN;
    //transient修饰的作用,让某些变量不被序列化
    public int number;
    public void mailCheck(){
        System.out.println("Mailing a check to "+ this.name+" "+this.address);
    }
}
创建一个序列化对象
  • ObjectOutputStream类用于序列化一个对象。下面是一个实例,用于序列化一个对象。
  • 对于序列化,Java里面有一个特殊的方法用于输出序列化对象,这个方法包含在ObjectOutputStream类里面。
public final void writeObject(Object x) throws IOException

上述writeObject()方法用于序列化一个对象之后,输出到一个数据流,约定的Java中的序列化数据拓展名是.ser

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class Init {
        public static void main(String[] args) {
                Employee employee = new Employee("ABC","12123",31232);
                try{
                        FileOutputStream fileBuffer = new FileOutputStream("D:\\employee.ser");
                        ObjectOutputStream out = new ObjectOutputStream(fileBuffer);
                        //用FileOutputStream来初始化OjectOutputStream
                        out.writeObject(employee);
                        out.close();
                        fileBuffer.close();
                        System.out.println("True");
                }catch (IOException i){
                        i.printStackTrace();
                }
        }
}
反序列化对象
  • 对于反序列化,Java里面有一个特殊的方法用于输出序列化对象,这个方法包含在ObjectInputStream类里面。
public final Object readObject() throws IOException, ClassNotFoundException

上述readObject()对象用于在一个数据流中读取反序列化信息,并且实现反序列化。

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class Init {
        public static void main(String[] args) {
                Employee employee = null;
                try{
                        FileInputStream fileBuffer = new FileInputStream("D:\\employee.ser");
                        ObjectInputStream in = new ObjectInputStream(fileBuffer);
                        //用FileInputStream来初始化ObjectInputStream
                        employee = (Employee)in.readObject();
                        in.close();
                        fileBuffer.close();
                        System.out.println("True");
                }catch (IOException i){
                        i.printStackTrace();
                        return;
                }catch (ClassNotFoundException c){
                        System.out.println("Employee class Noet found!");
                        c.printStackTrace();
                        return;
                }
                employee.show();
        }
}

True
我叫ABC,我的工号是12123,我的薪水是31232.00
进程已结束,退出代码0

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值