首页 > 其他分享 >泛型、序列化和反序列化

泛型、序列化和反序列化

时间:2024-10-18 19:48:10浏览次数:10  
标签:类型转换 对象 类型 泛型 序列化 public

一、泛型

1. 泛型概念

①Java 泛型(Generics) 是 JDK 5 中引入的一个新特性。
③定义类或者接口 时可以使用泛型,通过继承或者实现,减少了冗余代码,提高了代码的复用性。
④Java 不能创建具体类型的泛型数组
List[] li2 = new ArrayList[];

  1. 类型形参: 定义参数时不指定具体的类型,使用泛型通配符
  2. 类型实参: 在调用时传入具体的类型(类型实参)

2. 特性

泛型只在编译阶段有效。javac 编译器在把java文件编译成计算机识别的二进制字节码文件时, 会首先进行类型检查,检查通过后进行类型擦除。JVM并不知道泛型的存在,因为泛型在 编译阶段就已经被处理成普通的类和方法; 

3. 泛型的作用

  1. 类型安全

    编译时的强类型检查,对集合等容器限制存储元素的类型,编译时检查存储的元素是否 是容器允许存储的类型。把运行时期的问题提前到了编译期间。

  2. 消除强制类型转换

    没有泛型时可以存任意类型,取值时就需要强制类型转换。加了泛型,统一了容器中的元素类型,消除代码中强转,避免了强转时可能会出行的类型转换异常

  3. 更好的代码复用性:

    在框架设计时,类可以使用泛型类,通过继承或者实现,实现了所有的公共方法或者定 义接口公共响应类时使用泛型类,减少了冗余代码,提高了代码的复用性。

  4. 潜在的性能收益

    泛型为较大的优化带来可能。在泛型的初始实现中,编译器将强制类型转换(没有泛型的话,Java系统开发人员会指定这些强制类型转换)插入生成的字节码中。但是更多类 型信息可用于编译器这一事实,为未来版本的JVM的优化带来可能。

4. 泛型使用方式

泛型一般有三种使用方式:泛型类、泛型接口、泛型方法。

  1. 泛型类
    //此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型
    //在实例化泛型类时,必须指定T的具体类型
    public class Generic<T>{
    
        private T key;
    
        public Generic(T key) {
            this.key = key;
        }
    
        public T getKey(){
            return key;
        }
    }

    如何实例化泛型类:

    Generic<Integer> genericInteger = new Generic<Integer>(123456);
  2. 泛型接口
    public interface Generator<T> {
        public T method();
    }

    实现泛型接口,不指定类型:

    class GeneratorImpl<T> implements Generator<T>{
        @Override
        public T method() {
            return null;
        }
    }

    实现泛型接口,指定类型:

    class GeneratorImpl implements Generator<String> {
        @Override
        public String method() {
            return "hello";
        }
    }
    ------
    著作权归JavaGuide(javaguide.cn)所有
    基于MIT协议
    原文链接:https://javaguide.cn/java/basis/java-basic-questions-03.html

  3. 泛型方法
       public static < E > void printArray( E[] inputArray )
       {
             for ( E element : inputArray ){
                System.out.printf( "%s ", element );
             }
             System.out.println();
        }

    使用:

    // 创建不同类型数组:Integer, Double 和 Character
    Integer[] intArray = { 1, 2, 3 };
    String[] stringArray = { "Hello", "World" };
    printArray( intArray  );
    printArray( stringArray  );

    注意: public static < E > void printArray( E[] inputArray ) 一般被称为静态泛型方法;在 java 中泛型只是一个占位符,必须在传递类型后才能使用。类在实例化时才能真正的传递类型参数,由于静态方法的加载先于类的实例化,也就是说类中的泛型还没有传递真正的类型参数,静态的方法的加载就已经完成了,所以静态泛型方法是没有办法使用类上声明的泛型的。只能使用自己声明的 <E>

二、序列化和反序列化

1. 序列化和反序列化简介

  • 序列化:将数据结构或对象转换成可以存储或传输的形式,通常是二进制字节流,也可以是 JSON, XML 等文本格式
  • 反序列化:将在序列化过程中所生成的数据转换为原始数据结构或者对象的过程
  • 对于 Java 这种面向对象编程语言来说,我们序列化的都是对象(Object)也就是实例化后的类(Class)

下面是序列化和反序列化常见应用场景:

  • 对象在进行网络传输(比如远程方法调用 RPC 的时候)之前需要先被序列化,接收到序列化的对象之后需要再进行反序列化;
  • 将对象存储到文件之前需要进行序列化,将对象从文件中读取出来需要进行反序列化;
  • 将对象存储到数据库(如 Redis)之前需要用到序列化,将对象从缓存数据库中读取出来需要反序列化;
  • 将对象存储到内存之前需要进行序列化,从内存中读取出来之后需要进行反序列化。

2. 常见序列化协议

JDK 自带的序列化方式一般不会用 ,因为序列化效率低并且存在安全问题。比较常用的序列化协议有 Hessian、Kryo、Protobuf、ProtoStuff,这些都是基于二进制的序列化协议。

像 JSON 和 XML 这种属于文本类序列化方式。虽然可读性比较好,但是性能较差,一般不会选择。

3. 为什么不推荐使用 JDK 自带的序列化?

我们很少或者说几乎不会直接使用 JDK 自带的序列化方式,主要原因有下面这些原因:

  • 不支持跨语言调用 : 如果调用的是其他语言开发的服务的时候就不支持了。
  • 性能差:相比于其他序列化框架性能更低,主要原因是序列化之后的字节数组体积较大,导致传输成本加大。
  • 存在安全问题:序列化和反序列化本身并不存在问题。但当输入的反序列化的数据可被用户控制,那么攻击者即可通过构造恶意输入,让反序列化产生非预期的对象,在此过程中执行构造的任意代码。相关阅读:应用安全:JAVA 反序列化漏洞之殇

标签:类型转换,对象,类型,泛型,序列化,public
From: https://blog.csdn.net/2301_79814793/article/details/143003850

相关文章

  • 数据结构(JAVA)包装类&泛型
    文章目录包装类基本数据类型和对应的包装类装箱和拆箱面试题泛型什么是泛型泛型的语法泛型类的使用泛型的使用裸类型(RawType)(仅需了解)擦除机制泛型的上界泛型方法包装类基本数据类型和对应的包装类注意,除了int基本数据类型的包装类是Integer和char基本数据类......
  • Java中的Collections类和泛型
    在Java的集合框架中,`Collections`类扮演着一个非常重要的角色。它提供了一系列对集合进行操作的静态方法,这些方法可以用于各种集合类型,如`List`、`Set`和`Map`等,从而方便我们对集合进行诸如排序、查找、反转等操作。##一、排序操作1.**`sort`方法**  -`Collections`类......
  • java_day13_ArrayList、Vector、LinkedList、泛型
    一、ArrayListCollection[接口]:List[接口]:元素有序,可以发生重复,有索引的概念ArrayList[具体的子类]:底层数据结构是数组,查询快,增删慢,线程不安全,效率高。Set[接口]:元素无序且唯一,没有索引代码案例publicclassArrayListDemo1{publicstaticv......
  • shiro反序列化简单利用-1
    https://www.bilibili.com/video/BV1iF411b7bD?t=16.0环境搭建gitclonehttps://github.com/apache/shiro.gitcdshirogitcheckoutshiro-root-1.2.4编辑shiro/samples/web目录下的pom.xml,将jstl的版本修改为1.2流程分析静态分析尝试登录并抓包username和Password都......
  • JSON 请求太大,无法反序列化
    方案一asp.netmvc默认的json序列化ValueProviderFactory使用的是javascriptserializer,可以在配置文件web.config中设置:<addkey="aspnet:MaxJsonDeserializerMembers"value="150000000"/>和<system.web.extensions><scripting><w......
  • 泛型的使用和介绍
    一、泛型的介绍按照之前的写法,有几个问题1.程序中有大量的黄色警告2.在遍历的时候,迭代器不知道元素本身的类型,需要向下转型二、泛型的使用方法使用泛型[参数化类型]改进集合的使用。语法格式:<引用数据类型>publicclassFanXingDemo1{publicstaticvoidmain(Stri......
  • shiro 反序列化漏洞
    shiro反序列化漏洞Shiro-550漏洞原理影响版本:ApacheShiro<1.2.4特征判断:返回包中包含rememberMe=deleteMe字段。为了让浏览器或服务器重启后用户不丢失登录状态,Shiro支持将持久化信息序列化并加密后保存在Cookie的rememberMe字段中,下次读取时进行解密再反序列化。Pa......
  • C++模板初阶,只需稍微学习;直接起飞;泛型编程
    ......
  • javase笔记5----泛型
    泛型简介泛型是一种特殊的数据类型。它是Java的一个高级特性。定义一个语法结构时,不用指明具体类型,而是先定义一个类型变量,在真正使用的时候再确定该变量的具体类型。即类型参数化。语法泛型,定义在一对尖括号中,也是一个标识符,一般用在类名后,遵循大驼峰命名法。通常都......
  • 第108天:免杀对抗-Python&混淆算法&反序列化&打包生成器&Py2exe&Nuitka
    知识点#知识点:1、Python-对执行代码做文章2、Python-对shellcode做文章3、Python-对代码打包器做文章#章节点:编译代码面-ShellCode-混淆编译代码面-编辑执行器-编写编译代码面-分离加载器-编写程序文件面-特征码定位-修改程序文件面-加壳花指令-资源代码加载面-Dll反......