当前位置:首页 » 《随便一记》 » 正文

你的对象被人从网络传输走了还能回来吗?

15 人参与  2023年04月15日 11:16  分类 : 《随便一记》  评论

点击全文阅读


在这里插入图片描述

? 博客主页:@风一样的美狼子
? 欢迎关注:?点赞?收藏?留言
?系列专栏: 《云平台实战》、《Linux随你玩-实操》
?在阳光下灿烂,风雨中奔跑,泪水中成长,拼搏中展望。?
?一起加油,去追寻、去成为更好的自己!?

文章目录

1、前言2、OOP知识点2.1、OOP面向对象的三特征与含义2.2、重写和重载2.3、重写和重载的区别2.4、反射2.4.1、反射的作用2.4.2、反射的原理2.4.3、利用反射动态创建对象实例 3、序列化和反序列化3.1、序列化使用场景3.2、 实现序列化和反序列化为什么要实现Serializable接口3.3、我们为什么要显示指定serialVersionUID值3.4、不显示指定serialVersionUID会导致什么问题呢?3.5、序列化ID3.6、Java序列化的其他特性3.7、static属性为什么不会被序列化? 4 、结语

1、前言

     万物皆可NEW,万物皆对象。从我们开始接触Java这门语言后,就有人告诉我们这是一个面向对象的语言。说的最多的是new个对象,其实并不知道什么是对象。
刚进大学时在路上 一群男生中有人说给你一个对象,还以为是 真给他个女朋友呢。
在这里插入图片描述
滚回寝室与室友聊起,他们让我去看一下OOP,我才知道 Object Oriented Programming,原来聊的是面向对象的编程啊,无比尴尬!
想想以前真是可笑,不扯太远了,回归正题,聊正主吧,GO!

2、OOP知识点

2.1、OOP面向对象的三特征与含义

封装(高内聚低耦合 -->解耦)

封装是指将某事物的属性和行为包装到对象中,这个对象只对外公布需要公开的属性和行为,而这个公布也是可以有选择性的公布给其它对象。 使用private、protected、public三种修饰符或不用(即默认defalut)对外部对象访问该对象的属性和行为进行限制。

继承(重用父类的代码)

继承是子对象可以继承父对象的属性和行为,亦即父对象拥有的属性和行为,其子对象也就拥有了这些属性和行为。

多态(父类引用指向子类对象)

多态是指父对象中的同一个行为能在其多个子对象中有不同的表现。
有两种多态的机制:编译时多态、运行时多态。

2.2、重写和重载

1、方法的重载:

重载是指同一类中有多个同名的方法,但这些方法有着不同的参数。
因此在编译时就可以确定到底调用哪个方法,它是一种编译时多态。

2、方法的重写:
子类可以覆盖父类的方法,因此同样的方法会在父类中与子类中有着不同的表现形式。

作用范围:重写的作用范围是父类和子类之间;重载是发生在一个类里面。参数列表:重载必须不同;重写不能修改。返回类型:重载可修改;重写方法返回相同类型或子类。抛出异常:重载可修改;重写可减少或删除,一定不能抛出新的或者更广的异常。访问权限:重载可修改;重写一定不能做更严格的限制。

2.3、重写和重载的区别

重载 Overload:方法名相同,参数列表不同(个数、顺序、类型不同)与返回类型无关。
重写 Override 覆盖: 将父类的方法覆盖。 重写方法重写:方法名相同,访问修饰符只能大于被重写的方法访问修饰符,方法签名个数,顺序个数类型相同。
Override(重写)

方法名、参数、返回值相同。子类方法不能缩小父类方法的访问权限。子类方法不能抛出比父类方法更多的异常(但子类方法可以不抛出异常)。存在于父类和子类之间。方法被定义为final不能被重写。

Overload(重载)
参数类型、个数、顺序至少有一个不相同。
不能重载只有返回值不同的方法名。存在于父类和子类、同类中。

重载的规则:
1、必须具有不同的参数列表。
2、可以有不同的返回类型,只要参数列表不同就可以了。
3、可以有不同的访问修饰符。
4、可以抛出不同的异常。

重写方法的规则:

1、参数列表必须完全与被重写的方法相同,否则不能称其为重写而是重载。
2、返回的类型必须一直与被重写的方法的返回类型相同,否则不能称其为重写而是重载。
3、访问修饰符的限制一定要大于被重写方法的访问修饰符(public>protected>default>private)。
4、重写方法一定不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查型异常。

例如: 父类的一个方法申明了一个检查异常IOException,在重写这个方法时就不能抛出Exception,只能抛出IOException的子类异常,可以抛出非检查异常。

2.4、反射

在运行状态中,通过一个类的Class对象来获取它获取类的方法、属性、父类、接口等类的内部信息的机制。这种动态获取信息以及动态调用对象的方法的功能称为JAVA的反射。

2.4.1、反射的作用

反射就是:在任意一个方法里:

1.如果我知道一个类的名称/或者它的一个实例对象, 我就能把这个类的所有方法和变量的信息找出来(方法名,变量名,方法,修饰符,类型,方法参数等等所有信息)
2.如果我还明确知道这个类里某个变量的名称,我还能得到这个变量当前的值。
3.当然,如果我明确知道这个类里的某个方法名+参数个数类型,我还能通过传递参数来运行那个类里的那个方法。

反射机制主要提供了以下功能:

在运行时判断任意一个对象所属的类。
在运行时构造任意一个类的对象。
在运行时判断任意一个类所具有的成员变量和方法。
在运行时调用任意一个对象的方法,生成动态代理。

2.4.2、反射的原理

JAVA语言编译之后会生成一个.class文件,反射就是通过字节码文件找到某一个类、类中的方法以及属性等。
反射的实现主要借助以下四个类:

Class:类的对象
Constructor:类的构造方法
Field:类中的属性对象
Method :类中的方法

1、通过Class类获取类对象的三种方法:

A. 通过类名获得:Class<?> class = ClassName.class;B. 通过类名全路径获得:Class<?> class = Class.forName(“类名全路径”);C. 通过实例对象获得:Class<?> class = object.getClass();

2、通过Class类获取实现类实例化:

 Object o = (Object) test.newInstance() ; (其中test为Class类的实例化对象)

2.4.3、利用反射动态创建对象实例

Class对象的 newInstance()
使用Class对象的 newInstance()方法来创建该Class对象对应类的实例,但是这种方法要求该Class对象对应的类有默认的空构造器。
调用 Constructor 对象的 newInstance()
先使用 Class 对象获取指定的 Constructor 对象,再调用 Constructor 对象的 newInstance()
方法来创建 Class 对象对应类的实例,通过这种方法可以选定构造方法创建实例。

3、序列化和反序列化

Java 序列化目的:为了保存各种对象在内存中的状态,并且可以把保存的对象状态再读出来。

序列化:把对象转换为字节序列的过程称为对象的序列化。反序列化:把字节序列恢复为对象的过程称为对象的反序列化。

3.1、序列化使用场景

当我们只在本地JVM里运行下Java实例,是不需要什么序列化和反序列化的
只有下面场景条件下需要序列化和反序列化:

将内存中的对象持久化到磁盘,数据库中时;与浏览器进行交互时;实现RPC(远程方法调用)传输对象时;

如上所说,但我们在与浏览器交互时, 还有将内存中的对象持久化到数据库中时, 好像都没有去进行序列化和反序列化, 因为我们都没有实现Serializable接口, 但一直正常运行,这又是为什么呢

实际情况是 服务器与浏览器交互时的数据格式是JSON, JSON格式实际上就是将一个对象转化为字符串, 而字符串String类型已实现了Serializable接口, 并显示指定serialVersionUID的值。

再来看对象持久化到数据库中时的情况:

Mybatis数据库映射文件里的insert ,实际上并不是将整个对象持久化到数据库中, 而是将对象中的属性持久化到数据库中, 而这些属性都是实现了Serializable接口的基本属性。

3.2、 实现序列化和反序列化为什么要实现Serializable接口

Java中实现了Serializable接口后, JVM会在底层帮我们实现序列化和反序列化, 如果我们不实现Serializable接口, 那自己去写一套序列化和反序列化代码。

3.3、我们为什么要显示指定serialVersionUID值

如果不显示指定serialVersionUID, JVM在序列化时会根据属性自动生成一个serialVersionUID, 然后与属性一起序列化, 再进行持久化或网络传输。

在反序列化时, JVM会再根据属性自动生成一个新版serialVersionUID, 然后将这个新版serialVersionUID与序列化时生成的旧版serialVersionUID进行比较, 如果相同则反序列化成功, 否则报错.如果显示指定了serialVersionUID, JVM在序列化和反序列化时仍然都会生成一个serialVersionUID, 但值为我们显示指定的值, 这样在反序列化时新旧版本的serialVersionUID就一致了.

3.4、不显示指定serialVersionUID会导致什么问题呢?

如果我们的类写完后不再修改, 那不会有问题, 但这在实际开发中是几乎是不可能的,
我们的类会不断迭代, 一旦类被修改了, 那旧对象反序列化就会报错.。
所以在实际开发中, 我们都会显示指定一个serialVersionUID, 值写成啥无所谓, 只要不变就行。

3.5、序列化ID

虚拟机是否允许反序列化,不仅取决于类路径和功能代码是否一致,一个非常重要的一点是两个类的序列化ID是否一致。

3.6、Java序列化的其他特性

被transient关键字修饰的属性不会被序列化;static属性也不会被序列化;

3.7、static属性为什么不会被序列化?

因为序列化是针对对象而言的, 而static属性优先于对象存在, 随着类的加载而加载, 所以不会被序列化。
看到这个结论, 是不是有人会问, serialVersionUID也被static修饰, 为什么serialVersionUID会被序列化?
其实serialVersionUID属性并没有被序列化, JVM在序列化对象时会自动生成一个serialVersionUID, 然后将我们显示指定的serialVersionUID属性值赋给自动生成的serialVersionUID。

4 、结语

各位看官今天就到此为止,你应该知道 你的对象被人从网络传输走了还能否回来的吧。
此系列简要笔记后续会不断更新,? 欢迎关注:?点赞?收藏?留言!
在这里插入图片描述


点击全文阅读


本文链接:http://zhangshiyu.com/post/59597.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1