Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenDocCN
jbt-zh
提交
86e54a98
J
jbt-zh
项目概览
OpenDocCN
/
jbt-zh
8 个月 前同步成功
通知
0
Star
8
Fork
1
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
J
jbt-zh
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
86e54a98
编写于
6月 23, 2020
作者:
W
wizardforcel
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
2020-06-23 21:44:12
上级
c7387d1f
变更
11
隐藏空白更改
内联
并排
Showing
11 changed file
with
119 addition
and
124 deletion
+119
-124
docs/174.md
docs/174.md
+1
-1
docs/48.md
docs/48.md
+1
-1
docs/50.md
docs/50.md
+19
-21
docs/51.md
docs/51.md
+16
-16
docs/52.md
docs/52.md
+16
-16
docs/54.md
docs/54.md
+8
-8
docs/55.md
docs/55.md
+11
-16
docs/56.md
docs/56.md
+12
-10
docs/57.md
docs/57.md
+15
-15
docs/59.md
docs/59.md
+18
-18
docs/62.md
docs/62.md
+2
-2
未找到文件。
docs/174.md
浏览文件 @
86e54a98
...
...
@@ -2,7 +2,7 @@
> 原文: [https://javabeginnerstutorial.com/python-tutorial/object-oriented-programming-in-python/](https://javabeginnerstutorial.com/python-tutorial/object-oriented-programming-in-python/)
与在 Python 中一样,在开发程序时不必将代码创建为类,因为我们可以使用也称为过程编程的函数。 但是,过程
式
编程用于编写小型,简短和简单的程序,而面向对象的编程(OOP)程序随着程序的大小和复杂性的增长而变得越来越重要。 自从开发以来,Python 一直是面向对象的语言。
与在 Python 中一样,在开发程序时不必将代码创建为类,因为我们可以使用也称为过程编程的函数。 但是,过程
序
编程用于编写小型,简短和简单的程序,而面向对象的编程(OOP)程序随着程序的大小和复杂性的增长而变得越来越重要。 自从开发以来,Python 一直是面向对象的语言。
因此,让我们简要介绍一下所使用的面向对象的编程概念-
...
...
docs/48.md
浏览文件 @
86e54a98
...
...
@@ -4,7 +4,7 @@
在这里,我们将详细了解
`List`
接口及其不同实现。
`java.util`
包中的列表接口是
`java.util.Collection`
接口的子类型。
## `List`接口
显着
点
## `List`接口
要
点
1.
它是
`java.util`
包的一部分。
2.
它是
`java.util.Collection`
接口的子类型。
...
...
docs/50.md
浏览文件 @
86e54a98
...
...
@@ -2,51 +2,51 @@
> 原文: [https://javabeginnerstutorial.com/core-java-tutorial/set-collection-tutorial-for-java-beginners/](https://javabeginnerstutorial.com/core-java-tutorial/set-collection-tutorial-for-java-beginners/)
`Set`
是 Java 集合框架的一部分。
`Set`
是
*java.util*
程序包中的一个接口。 它实现了 Collection
接口。
`Set`
是 Java 集合框架的一部分。
`Set`
是
`java.util`
程序包中的一个接口。 它实现了
`Collection`
接口。
# 与集
合
有关的要点
# 与集有关的要点
*
它不包含重复的元素。
*
一些
Set 实现对 NULL
元素有限制。
*
一些
`Set`
实现对
`NULL`
元素有限制。
#
设置
接口的具体实现
#
`Set`
接口的具体实现
*
哈希集
*
链接哈希集
*
树集
*
EnumSet
*
`HashSet`
*
`LinkedHashSet`
*
`TreeSet`
*
`EnumSet`
# 设置界面中的重要方法
此接口不包含任何特殊方法。 它仅继承
Collection
接口的所有方法。
此接口不包含任何特殊方法。 它仅继承
`Collection`
接口的所有方法。
#
哈希集
#
`HashSet`
*
此类是 Java
CollectionFramework
的一部分。
*
此类实现
Set
接口。
*
此类是 Java
集合框架
的一部分。
*
此类实现
`Set`
接口。
*
它由哈希表支持。
*
它是无序的。 (随着时间的推移,订单不可预测)
*
基本操作(如添加,删除,包含和大小)的恒定时间性能。
*
它不同步。
*
Iterator 方法返回的迭代器为 FailFast
。
*
`Iterator`
方法返回的迭代器为快速失败
。
## 构造器
*
**`HashSet(Collection<? extends E> c)`**
:构造一个新集合,其中包含指定集合中的元素。
*
**`HashSet(int initialCapacity, float loadFactor)`**
:构造一个新的空集; 支持的
HashMap
实例具有指定的初始容量和指定的负载系数。
*
**`HashSet(int initialCapacity, float loadFactor)`**
:构造一个新的空集; 支持的
`HashMap`
实例具有指定的初始容量和指定的负载系数。
*
**`HashSet(int initialCapacity)`**
:构造一个新的空集。
#
链接哈希集
#
`LinkedHashSet`
*
元素的顺序是可预测的。
*
它维护遍历所有条目的双链表。
*
元素的顺序将与插入顺序相同。
*
它允许
NULL
值。
*
与
HashSet
一样,它为基本操作提供恒定的时间性能。
*
它允许
`NULL`
值。
*
与
`HashSet`
一样,它为基本操作提供恒定的时间性能。
*
链接列表上的迭代时间与大小成正比。
*
初始容量和负载因子决定
LinkedHashSet
的性能。
*
初始容量和负载因子决定
`LinkedHashSet`
的性能。
*
它不同步。
*
此类的
Iterator 方法返回的 Iterator 为 FAIL-FAST
。
*
此类的
`Iterator`
方法返回的迭代器为快速失败
。
## 构造器
...
...
@@ -54,5 +54,3 @@
*
**`LinkedHashSet(int initialCapacity)`**
:构造一个新的,空的,具有指定初始容量和默认加载因子 0.75 的链接哈希集。
*
**`LinkedHashSet()`**
:构造一个新的空链接哈希集,默认初始容量为 16,负载因子为 0.75。
*
**`LinkedHashSet(Collection<? extends E> c)`**
:构造一个新的链接哈希集,其元素与指定的集合相同。
# 树集
\ No newline at end of file
docs/51.md
浏览文件 @
86e54a98
# Java 初学者的
排序集
集合教程
# Java 初学者的
`SortedSet`
集合教程
> 原文: [https://javabeginnerstutorial.com/core-java-tutorial/sorted-set-collection-tutorial-for-java-beginners/](https://javabeginnerstutorial.com/core-java-tutorial/sorted-set-collection-tutorial-for-java-beginners/)
该接口是 Java
Collection Interface
的一部分。
该接口是 Java
集合接口
的一部分。
SortedSet
的重要点
`SortedSet`
的重要点
*
它提供其元素的顺序。
*
元素根据创建
SortedSet 时提供的 Comparable / Comparator
进行排序。
*
元素根据创建
`SortedSet`
时提供的
`Comparable`
/
`Comparator`
进行排序。
*
迭代器将以升序遍历集合。
*
此接口是
SortedMap
的集合类似物。
*
插入
SortedSet 中的元素需要实现 Comparable
接口(或接受比较器接口)。
*
SortedSet
的所有实现应提供 4 个构造器。
*
没有
Arg
构造器
*
具有
Comparator 单个
参数的构造器。
*
具有单个
参数的构造方法为 Collection
。
*
具有单个
参数的构造器为 SortedSet
。
*
此接口是
`SortedMap`
的集合类似物。
*
插入
`SortedSet`
中的元素需要实现
`Comparable`
接口(或接受比较器接口)。
*
`SortedSet`
的所有实现应提供 4 个构造器。
*
没有
带参
构造器
*
具有
单个
`Comparator`
参数的构造器。
*
具有单个
`Collection`
参数的构造器
。
*
具有单个
`SortedSet`
参数的构造器
。
#
SortedSet
中的重要方法
#
`SortedSet`
中的重要方法
*
**`Comparator<? super E> comparator()`**
:返回用于对 Set 中的元素进行排序的比较器。
*
**`subSet(E fromElement, E toElement)`**
:返回此集合部分的视图,其元素范围从 fromElement(包括)到 toElement(不包括)。
*
**`headSet(E toElement)`**
:返回此集合中的元素严格小于 toElement 的部分的视图。
*
**`tailSet(E fromElement)`**
:返回此集合中其元素大于或等于 fromElement 的部分的视图
\ No newline at end of file
*
**`Comparator<? super E> comparator()`**
:返回用于对
`Set`
中的元素进行排序的比较器。
*
**`subSet(E fromElement, E toElement)`**
:返回此集合部分的视图,其元素范围从
`fromElement`
(包括)到
`toElement`
(不包括)。
*
**`headSet(E toElement)`**
:返回此集合中的元素严格小于
`toElement`
的部分的视图。
*
**`tailSet(E fromElement)`**
:返回此集合中其元素大于或等于
`fromElement`
的部分的视图
\ No newline at end of file
docs/52.md
浏览文件 @
86e54a98
# Java 初学者
排序映射收藏
教程
# Java 初学者
`SortedMap`集合
教程
> 原文: [https://javabeginnerstutorial.com/core-java-tutorial/sorted-map-collection-tutorial-for-java-beginners/](https://javabeginnerstutorial.com/core-java-tutorial/sorted-map-collection-tutorial-for-java-beginners/)
##
SortedMap 的显着
点
##
`SortedMap`的要
点
*
此接口是
SortedSet
的映射类似物。
*
IT 提供按键排
序。
*
排序标准将是创建时提供的自然顺序或
Comparator
。
*
其中使用的键必须实现
Comparable
或接受指定的比较器。
*
此接口是
`SortedSet`
的映射类似物。
*
它按键提供顺
序。
*
排序标准将是创建时提供的自然顺序或
`Comparator`
。
*
其中使用的键必须实现
`Comparable`
或接受指定的比较器。
*
该图中的键必须相互可比较。
*
使用
Map 接口 equals 方法比较两个键,而在 SortedMap 中使用 compare / compareTo 方法(来自 Comparable 或 Comparator
)。
*
使用
`Map`
接口
`equals`
方法比较两个键,而在
`SortedMap`
中使用
`compare`
/
`compareTo`
方法(来自
`Comparable`
或
`Comparator`
)。
*
需要由具体类实现的构造方法
*
无
Arg
构造器
*
具有
Comparator 单个
参数的构造器。
*
具有单个
参数的构造器作为 Map
。
*
具有单个
参数的构造器,如 SortedMap
。
*
SortedMap 是 Java Collection Framework
的一部分。
*
无
参
构造器
*
具有
单个
`Comparator`
参数的构造器。
*
具有单个
`Map`
参数的构造器
。
*
具有单个
`SortedMap`
参数的构造器
。
*
`SortedMap`
是 Java 集合框架
的一部分。
#
SortedMap
界面中的重要方法
#
`SortedMap`
界面中的重要方法
*
**`subMap(K fromKey, K toKey)`**
:返回此映射部分的视图,其元素范围从 fromElement(包括)到 toElement(不包括)。
*
**`headMap(K toKey)`**
:返回此映射部分的视图,其元素严格小于 toElement。
*
**`tailMap(K fromKey)`**
:返回此图的一部分,其元素大于或等于 fromElement 的视图。
\ No newline at end of file
*
**`subMap(K fromKey, K toKey)`**
:返回此映射部分的视图,其元素范围从
`fromElement`
(包括)到
`toElement`
(不包括)。
*
**`headMap(K toKey)`**
:返回此映射部分的视图,其元素严格小于
`toElement`
。
*
**`tailMap(K fromKey)`**
:返回此图的一部分,其元素大于或等于
`fromElement`
的视图。
\ No newline at end of file
docs/54.md
浏览文件 @
86e54a98
...
...
@@ -6,7 +6,7 @@
## 什么是序列化
Java 序列化是一个过程,其中
Object
的当前状态将保存在字节流中。 字节流是平台无关的,因此一旦在一个系统中创建了对象,便可以在其他平台上反序列化。
Java 序列化是一个过程,其中
对象
的当前状态将保存在字节流中。 字节流是平台无关的,因此一旦在一个系统中创建了对象,便可以在其他平台上反序列化。
## 序列化有什么用
...
...
@@ -23,7 +23,7 @@ Java 序列化是一个过程,其中 Object 的当前状态将保存在字节
Java 已经提供了开箱即用的方式(
`java.io.Serializable`
接口)来序列化对象。 如果要序列化任何类,则该类需要实现给定的接口。
**注**
:可序列化接口是标记接口。 因此,
Serializable
接口中没有任何方法。
**注**
:可序列化接口是标记接口。 因此,
`Serializable`
接口中没有任何方法。
## Java 类序列化代码
...
...
@@ -118,15 +118,15 @@ Last Name of Employee: Gautam
### 项目要点
*
**序列化**
接口需要使对象
*序列化*
。
*
暂时
[
实例变量
](
https://javabeginnerstutorial.com/core-java-tutorial/instance-variable-java/
)
并未以对象状态序列化。
*
如果
Super 类实现了 Serializable,则子类也可以自动进行 Serializable
。
*
如果无法对超类进行序列化,则在对子类进行反序列化时,将调用超类的默认
[
构造器
](
https://javabeginnerstutorial.com/core-java-tutorial/constructors-in-java/
)
。 因此,所有变量将获得默认值,引用将为
null
。
*
瞬态
[
实例变量
](
https://javabeginnerstutorial.com/core-java-tutorial/instance-variable-java/
)
并未以对象状态序列化。
*
如果
超类实现了
`Serializable`
,则子类也可以自动进行
`Serializable`
。
*
如果无法对超类进行序列化,则在对子类进行反序列化时,将调用超类的默认
[
构造器
](
https://javabeginnerstutorial.com/core-java-tutorial/constructors-in-java/
)
。 因此,所有变量将获得默认值,引用将为
`null`
。
在下一篇文章中,我们将讨论
[
瞬态变量
](
https://javabeginnerstutorial.com/core-java-tutorial/java-serialization-concept-example-part-ii/
"Java serialization concept and Example Part II"
)
的使用。
*
**序列化**
接口需要使对象
*序列化*
。
*
暂时
[
实例变量
](
https://javabeginnerstutorial.com/core-java-tutorial/instance-variable-java/
)
并未以对象状态序列化。
*
如果 Super 类实现了 Serializable,则子类也可以自动进行 Serializable。
*
如果无法对超类进行序列化,则在对子类进行反序列化时,将调用超类的默认
[
构造器
](
https://javabeginnerstutorial.com/core-java-tutorial/constructors-in-java/
)
。 因此,所有变量将获得默认值,引用将为 null。
\ No newline at end of file
*
瞬态
[
实例变量
](
https://javabeginnerstutorial.com/core-java-tutorial/instance-variable-java/
)
并未以对象状态序列化。
*
如果超类实现了
`Serializable`
,则子类也可以自动进行
`Serializable`
。
*
如果无法对超类进行序列化,则在对子类进行反序列化时,将调用超类的默认
[
构造器
](
https://javabeginnerstutorial.com/core-java-tutorial/constructors-in-java/
)
。 因此,所有变量将获得默认值,引用将为
`null`
。
\ No newline at end of file
docs/55.md
浏览文件 @
86e54a98
...
...
@@ -6,7 +6,7 @@
在本文中,我们将使用与上一篇文章相同的代码库。
## 使用
serialVersionUID
## 使用
`serialVersionUID`
您必须已经看到在源代码中使用了一个名为“
`serialVersionUID`
”的变量。 使用此变量有特定的原因。
...
...
@@ -16,14 +16,14 @@
*
如果可序列化的类具有显式的
`serialVersionUID`
,则此字段的类型应为
`long`
,并且必须是静态且最终的。
*
如果没有明确定义的
`serialVersionUID`
字段,则序列化运行时将计算该类的默认值。 随编译器的实现而有所不同。 因此建议定义
`serialVersionUID`
。
*
建议对
`serialVersionUID`
使用私有访问修饰符。
*
数组类无法声明显式的
serialVersionUID,因此它们始终具有默认的计算值,但是对于数组类,无需匹配 serialVersionUID
值。
*
如果已加载的接收器类的
serialVersionUID
与相应的发送器类之间存在差异,则将引发
`InvalidClassException`
。
*
数组类无法声明显式的
`serialVersionUID`
,因此它们始终具有默认的计算值,但是对于数组类,无需匹配
`serialVersionUID`
值。
*
如果已加载的接收器类的
`serialVersionUID`
与相应的发送器类之间存在差异,则将引发
`InvalidClassException`
。
## 瞬态的使用
我们可以使用
Serializable
保存对象的状态。 但是,如果我不想保存字段状态怎么办? 在这种情况下,可以像下面这样使用瞬态修改器。 序列化过程中不会保存瞬态字段状态,反序列化时会将默认值分配给同一变量。
我们可以使用
`Serializable`
保存对象的状态。 但是,如果我不想保存字段状态怎么办? 在这种情况下,可以像下面这样使用瞬态修改器。 序列化过程中不会保存瞬态字段状态,反序列化时会将默认值分配给同一变量。
使用瞬态变量更改
Employee
类。
使用瞬态变量更改
`Employee`
类。
```
java
package
com.jbt
;
...
...
@@ -44,7 +44,7 @@ public class Employee implements Serializable
}
```
如果您执行相同的类(
SerializaitonClass & DeserializationClass
),则输出将与之前的代码不同。
如果您执行相同的类(
`SerializaitonClass`
&
`DeserializationClass`
),则输出将与之前的代码不同。
```
java
Deserializing
Employee
...
...
...
@@ -52,13 +52,13 @@ First Name of Employee: Vivekanand
Last
Name
of
Employee:
null
```
如您所见,姓氏为
null
,因为在序列化过程中未保存该变量的状态。
如您所见,姓氏为
`null`
,因为在序列化过程中未保存该变量的状态。
## 类层次结构和可序列化
在这里,我将讨论
Serializable 接口对类层次结构的影响。 如果一个类实现了 Serializable
接口,则可以保存该类的状态。 但是,如果同一类扩展了另一个未实现可序列化接口的类,则不会保存超类的状态。
在这里,我将讨论
`Serializable`
接口对类层次结构的影响。 如果一个类实现了
`Serializable`
接口,则可以保存该类的状态。 但是,如果同一类扩展了另一个未实现可序列化接口的类,则不会保存超类的状态。
为了了解区别,我们将更新原始的
Employee 类。 现在,该类将扩展另一个类
*superEmployee*
。 该超类将不会实现 Serializable
接口。
为了了解区别,我们将更新原始的
`Employee`
类。 现在,该类将扩展另一个类
`superEmployee`
。 该超类将不会实现
`Serializable`
接口。
```
java
package
com.jbt
;
...
...
@@ -75,7 +75,7 @@ class superEmployee {
}
```
如果您一个接一个地执行“
SerializaitonClass”和“ DeserializationClass
”,那么输出将如下所示
如果您一个接一个地执行“
`SerializaitonClass`
”和“
`DeserializationClass`
”,那么输出将如下所示
```
java
Deserializing
Employee
...
...
...
@@ -85,9 +85,4 @@ Last Name of Employee: null
## 瞬态与静态变量
我已经写了一篇完整的文章。 请在此处访问
[
。
](
https://javabeginnerstutorial.com/core-java-tutorial/transient-vs-static-variable-java/
"Transient vs Static variable java"
)
## 自定义序列化过程
<
TO_DO
>
我已经写了一篇完整的文章。
[
请在此处访问
](
https://javabeginnerstutorial.com/core-java-tutorial/transient-vs-static-variable-java/
"Transient vs Static variable java"
)
。
docs/56.md
浏览文件 @
86e54a98
...
...
@@ -10,7 +10,7 @@
## 瞬态变量
如果您不想保存变量的状态,请在序列化时使用。 您必须将该变量标记为
Transient
。 环境将知道应忽略此变量,并且不会保存相同的值。
如果您不想保存变量的状态,请在序列化时使用。 您必须将该变量标记为
`Transient`
。 环境将知道应忽略此变量,并且不会保存相同的值。
> 即使概念是完全不同的,并且不进行储蓄的原因也不同,人们仍然对两者的存在感到困惑。 与这两种情况一样,变量值将不会保存。
...
...
@@ -106,13 +106,13 @@ public class DeserializationClass {
}
```
首先执行“
SerializaitonClass
”,您将获得以下输出。
首先执行“
`SerializaitonClass`
”,您将获得以下输出。
```
java
Serialized
data
is
saved
in
./
employee
.
txt
file
```
其次,执行“
DeserializationClass
”,您将获得以下输出
其次,执行“
`DeserializationClass`
”,您将获得以下输出
```
java
Deserializing
Employee
...
...
...
@@ -162,18 +162,20 @@ Company CEO: Jayshree
Company
Address:
null
```
非常仔细地查看输出。 此处已保存
companyName,companyCEO
的值,但未保存地址的值。 另外,检查这些变量的保存值。
非常仔细地查看输出。 此处已保存
`companyName`
,
`companyCEO`
的值,但未保存地址的值。 另外,检查这些变量的保存值。
公司名称:TATA
公司首席执行官:Jayshree
```
java
Company
Name:
TATA
Company
CEO:
Jayshree
```
在这两种情况下,此处存储的
case 值均来自 class(Employee class),而不是 Object(emp object)。 此外,即使是临时变量,也会保存 companyCEO 变量值。 因为 static
修饰符会更改此变量的行为。
在这两种情况下,此处存储的
`case`
值均来自类(
`Employee`
类),而不是对象(
`emp`
对象)。 此外,即使是临时变量,也会保存
`companyCEO`
变量值。 因为
`static`
修饰符会更改此变量的行为。
## 重点
1.
静态变量无法序列化。
2.
在反序列化时,如果在基类的初始化过程中提供了相同的值,则可用于静态变量。
*
这并不意味着静态变量将被序列化。 这仅意味着静态变量将使用相同的值初始化,并在加载类时分配(在这种情况下为
TATA
)。 如果之前未加载类(新 JVM)。 请注意示例代码。
*
这并不意味着静态变量将被序列化。 这仅意味着静态变量将使用相同的值初始化,并在加载类时分配(在这种情况下为
`TATA`
)。 如果之前未加载类(新 JVM)。 请注意示例代码。
*
如果类已经在 JVM 中加载并且静态变量值已更改,那么将显示更改后的值。
3.
如果将变量定义为“静态”和“瞬态”,则静态修饰符将控制变量的行为,而不是瞬态。
*
静态和瞬态是不同的。 在某些情况下,它们的行为看起来相同,但并非总是如此。 如果在加载类时为变量分配了一个值,则在反序列化类时该值将分配给静态变量,而不是瞬时的。 因此,如果您同时使用这两个修饰符和变量,那么从某种意义上来说,我要说的是静态将优先于瞬态。
...
...
@@ -181,7 +183,7 @@ Company Address: null
## 最终修饰符对序列化的影响
要查看
Final 修饰符的效果,我再次更改 Employee
类的代码。
要查看
`Final`
修饰符的效果,我再次更改
`Employee`
类的代码。
`Employee.java`
...
...
@@ -223,7 +225,7 @@ Company Address: DEL
## 界面和最终
我看到了一种情况,您可以序列化未序列化的
Interface
内部的变量。
我看到了一种情况,您可以序列化未序列化的
接口
内部的变量。
`Employee.java`
...
...
docs/57.md
浏览文件 @
86e54a98
#
serialVersionUID
的用途是什么
#
`serialVersionUID`
的用途是什么
> 原文: [https://javabeginnerstutorial.com/core-java-tutorial/use-serialversionuid/](https://javabeginnerstutorial.com/core-java-tutorial/use-serialversionuid/)
在这里,我将讨论在可序列化类中使用的变量
serialVersionUID
的重要性。
在这里,我将讨论在可序列化类中使用的变量
`serialVersionUID`
的重要性。
下面是一个使您了解变量的确切用法的示例。
## 示例程
式
码
## 示例程
序
码
Employee.java
`Employee.java`
```
java
package
com.jbt
;
...
...
@@ -23,7 +23,7 @@ public class Employee implements Serializable
}
```
SerializaitonClass.java
(此类将用于序列化)
`SerializaitonClass.java`
(此类将用于序列化)
```
java
package
com.jbt
;
...
...
@@ -53,7 +53,7 @@ public class SerializaitonClass {
}
```
DeserializationClass.java
(此类将用于反序列化)
`DeserializationClass.java`
(此类将用于反序列化)
```
java
package
com.jbt
;
...
...
@@ -84,7 +84,7 @@ public class DeserializationClass {
}
```
现在执行“
SerializationClass.java”,然后执行“ DeserializationClass.java”。 它将首先创建一个具有 Employee
对象状态的文件,然后在反序列化时从同一文件创建一个对象。 输出将如下所示。
现在执行“
`SerializationClass.java`
”,然后执行“
`DeserializationClass.java`
”。 它将首先创建一个具有
`Employee`
对象状态的文件,然后在反序列化时从同一文件创建一个对象。 输出将如下所示。
```
java
Serialized
data
is
saved
in
./
employee
.
txt
file
...
...
@@ -96,9 +96,9 @@ First Name of Employee: Vivekanand
Last
Name
of
Employee:
Gautam
```
现在让我们尝试从
Employee.java 文件中删除“ serialVersionUID”变量,然后再次运行“ SerializationClass.java”文件。 它将再次创建带有对象状态的“ employee.txt”文件。 现在让我们在 Employee
类中假设字符串地址中添加一个新变量。
现在让我们尝试从
`Employee.java`
文件中删除“
`serialVersionUID`
”变量,然后再次运行“
`SerializationClass.java`
”文件。 它将再次创建带有对象状态的“
`employee.txt`
”文件。 现在让我们在
`Employee`
类中假设字符串地址中添加一个新变量。
Employee.java
`Employee.java`
```
java
package
com.jbt
;
...
...
@@ -115,7 +115,7 @@ public class Employee implements Serializable
}
```
现在运行“
DeserializationClass.java
”并查看输出。
现在运行“
`DeserializationClass.java`
”并查看输出。
```
java
java
.
io
.
InvalidClassException
:
com
.
jbt
.
Employee
;
local
class
incompatible
:
stream
classdesc
serialVersionUID
=
5462223600
,
local
class
serialVersionUID
=
-
3607530122250644586
...
...
@@ -128,7 +128,7 @@ java.io.InvalidClassException: com.jbt.Employee; local class incompatible: strea
at
com
.
jbt
.
DeserializationClass
.
main
(
DeserializationClass
.
java
:
11
)
```
它将引发不兼容的异常。 因为给定的类
Employee.java
在序列化和反序列化过程之间进行了更改。 因此,系统无法识别它仍然是同一类。 为了使我们的系统了解到它是同一类,您必须在一个类中使用
`serialVersionUID`
变量。
它将引发不兼容的异常。 因为给定的类
`Employee.java`
在序列化和反序列化过程之间进行了更改。 因此,系统无法识别它仍然是同一类。 为了使我们的系统了解到它是同一类,您必须在一个类中使用
`serialVersionUID`
变量。
您可以尝试执行上述步骤,但保持
`serialVersionUID`
不变,并查看输出。 反序列化过程将正常进行。
...
...
@@ -139,11 +139,11 @@ java.io.InvalidClassException: com.jbt.Employee; local class incompatible: strea
*
如果没有明确定义的
`serialVersionUID`
字段,则序列化运行时将计算该类的默认值。 该值可以根据编译器的实现而变化。 因此,建议定义
`serialVersionUID`
。
*
建议对
`serialVersionUID`
使用私有访问修饰符。
*
不同的类可以具有相同的
`serialVersionUID`
。
*
数组类无法声明显式的
serialVersionUID,因此它们始终具有默认的计算值,但是对于数组类,无需匹配 serialVersionUID
值。
*
如果已加载的接收器类的
serialVersionUID
与相应的发送器类之间存在差异,则将引发
`InvalidClassException`
。
*
数组类无法声明显式的
`serialVersionUID`
,因此它们始终具有默认的计算值,但是对于数组类,无需匹配
`serialVersionUID`
值。
*
如果已加载的接收器类的
`serialVersionUID`
与相应的发送器类之间存在差异,则将引发
`InvalidClassException`
。
*
如果要禁止序列化同一类旧版本的新类,则应对同一类的不同版本使用不同的
`serialVersionUID`
。
##
@SuppressWarnings(“序列”)
##
`@SuppressWarnings("serial")`
如果您没有在应该序列化的类中提供
serialVersionId,则编译器将给出有关该序列的警告消息。 如果要覆盖此警告,则可以使用给定的注释。 使用后,编译器将不再报错缺少的 serialVersionUID
。
如果您没有在应该序列化的类中提供
`serialVersionId`
,则编译器将给出有关该序列的警告消息。 如果要覆盖此警告,则可以使用给定的注释。 使用后,编译器将不再报错缺少的
`serialVersionUID`
。
docs/59.md
浏览文件 @
86e54a98
...
...
@@ -30,7 +30,7 @@ public static final String FRIDAY = "Friday";
}
```
现在,
Schedule
类将如下所示:
现在,
`Schedule`
类将如下所示:
```
java
public
class
Schedule
{
...
...
@@ -41,9 +41,9 @@ private String workday;
}
```
我想您已经看到了这种方法的缺点:即使
Workdays
类中未定义工作日,也可以轻松地将工作日设置为“星期六”或“星期日”。 此解决方案不是价值安全的。 这不是我们想要实现的。
我想您已经看到了这种方法的缺点:即使
`Workdays`
类中未定义工作日,也可以轻松地将工作日设置为“星期六”或“星期日”。 此解决方案不是价值安全的。 这不是我们想要实现的。
为了解决这个问题,我们将
Workdays
类转换为一个枚举:
为了解决这个问题,我们将
`Workdays`
类转换为一个枚举:
```
java
public
enum
Workday
{
...
...
@@ -51,7 +51,7 @@ MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY
}
```
所需的打字次数更少,现在该解决方案是价值安全的。 我们只需要调整
Schredule
类:
所需的打字次数更少,现在该解决方案是价值安全的。 我们只需要调整
`Schredule`
类:
```
java
public
class
Schedule
{
...
...
@@ -69,7 +69,7 @@ public void setWorkday(Workday workday) {
## 有条件的枚举
枚举非常适合条件表达式(如果是语句或切换块)。 关于枚举的好处是它们是常量值,因此您可以将它们与
==运算符进行比较,该运算符比使用 equals()更优雅-并且避免了可能的 NullPointerExceptions。 顺便说一句:如果您查看 Enum 类 equals()
的实现,您将看到以下内容:
枚举非常适合条件表达式(如果是语句或切换块)。 关于枚举的好处是它们是常量值,因此您可以将它们与
`==`
运算符进行比较,该运算符比使用
`equals()`
更优雅-并且避免了可能的
`NullPointerExceptions`
。 顺便说一句:如果您查看
`Enum`
类
`equals()`
的实现,您将看到以下内容:
```
java
public
final
boolean
equals
(
Object
other
)
{
...
...
@@ -77,7 +77,7 @@ public final boolean equals(Object other) {
}
```
因此,请自由使用
==,因为这是 equals()
的默认实现。
因此,请自由使用
`==`
,因为这是
`equals()`
的默认实现。
让我们看一下如何使用它们的示例:
...
...
@@ -107,7 +107,7 @@ default:
## 迭代枚举
迭代枚举非常简单。 枚举类定义了一个称为
values()
的方法,该方法返回给定枚举的值。 最好是看一个例子:
迭代枚举非常简单。 枚举类定义了一个称为
`values()`
的方法,该方法返回给定枚举的值。 最好是看一个例子:
```
java
for
(
Workday
w
:
Workday
.
values
())
{
...
...
@@ -125,11 +125,11 @@ THURSDAY
FRIDAY
```
如您所见,
values()
的顺序与枚举本身中定义的顺序相同。 因此,Java 不会进行任何魔术排序。
如您所见,
`values()`
的顺序与枚举本身中定义的顺序相同。 因此,Java 不会进行任何魔术排序。
## 枚举字段
有时,您只想将枚举打印到控制台(或以某种 UI 形式显示)。 在上面的示例(工作日)中,您可以简单地使用枚举的名称,尽管有时“
TUESDAY”似乎很喊,而“ Tuesday”更可取。 在这种情况下,您可以添加和使用 Enum
对象的自定义字段:
有时,您只想将枚举打印到控制台(或以某种 UI 形式显示)。 在上面的示例(工作日)中,您可以简单地使用枚举的名称,尽管有时“
`TUESDAY`
”似乎很喊,而“
`Tuesday`
”更可取。 在这种情况下,您可以添加和使用
`Enum`
对象的自定义字段:
```
java
public
enum
Workday
{
...
...
@@ -155,9 +155,9 @@ private Workday(String representation) {
枚举字段很好,但是如何访问该字段? 我告诉过您,新的表示形式是表示该枚举的值,但是当前我们无法在枚举本身之外访问该属性。
除此之外,还有一个基本方法可用于所有枚举:
name()以字符串形式返回当前值的名称。 这意味着在基本情况下,您可以使用此方法显示枚举的值(例如,在 UI 或日志条目中)。
**当然**
也存在 toString()函数,但是有时开发人员会覆盖它,以使其对程序员更友好(或用户友好?)显示。 作为最佳实践,如果要显示枚举的名称,建议您使用 name()方法而不是 toString()
。
除此之外,还有一个基本方法可用于所有枚举:
`name()`
以字符串形式返回当前值的名称。 这意味着在基本情况下,您可以使用此方法显示枚举的值(例如,在 UI 或日志条目中)。
**当然**
也存在
`toString()`
函数,但是有时开发人员会覆盖它,以使其对程序员更友好(或用户友好?)显示。 作为最佳实践,如果要显示枚举的名称,建议您使用
`name()`
方法而不是
`toString()`
。
要从上面更改表示示例(当我们遍历
values()
时),只需编写一个函数,该函数将返回新的变量表示并在迭代中使用它:
要从上面更改表示示例(当我们遍历
`values()`
时),只需编写一个函数,该函数将返回新的变量表示并在迭代中使用它:
```
java
public
enum
Workday
{
...
...
@@ -197,13 +197,13 @@ Thursday
Friday
```
但这不是唯一可以实现枚举方法的用法。 在下一节中,我们将看到如何将
Enum 值映射到 String
并返回。
但这不是唯一可以实现枚举方法的用法。 在下一节中,我们将看到如何将
`Enum`
值映射到
`String`
并返回。
## 实现接口
关于枚举鲜为人知的一件事是它们可以实现接口。 这意味着,如果您需要不同枚举所需要的通用功能,则可以使用一个接口定义它,而枚举必须在该接口中实现方法。
一种这样的用例是使用 JPA 将枚举值存储在数据库中-尽管不是按名称或顺序(可通过
@Enumeration 和 EnumType
获得),而是通过短代码。
一种这样的用例是使用 JPA 将枚举值存储在数据库中-尽管不是按名称或顺序(可通过
`@Enumeration`
和
`EnumType`
获得),而是通过短代码。
在这种情况下,您可以创建一个接口,其中包含将枚举转换为数据库表示形式并将枚举转换回的方法。
...
...
@@ -223,7 +223,7 @@ public interface DatabaseEnum<T extends Enum<T>> {
}
```
该接口使用泛型(由
T 类型表示),并在 Strings
和枚举类型之间进行转换。
该接口使用泛型(由
`T`
类型表示),并在
`String`
和枚举类型之间进行转换。
要实现此界面,请扩展“工作日”示例:
...
...
@@ -266,7 +266,7 @@ public Workday fromDatabase(String representation) {
有时,您最终得到一个采用布尔表达式的方法(或者您仅获得一个告诉您使用布尔值的项目说明,但感觉很痒)。 在这种情况下,可以随意引入一个新的枚举并使用正确的值而不是布尔值。
例如,一旦我有了一个规范,告诉我必须创建一个带有一些参数的方法和一个布尔值,称为“
rightHandSide”。 实际上,“ rightHandSide”的默认值为 false
。 首先,我按照规范中的说明实现了该方法,但是这对我来说并不舒服,我认为这是摆脱这种冷酷感觉的另一种方法:
例如,一旦我有了一个规范,告诉我必须创建一个带有一些参数的方法和一个布尔值,称为“
`rightHandSide`
”。 实际上,“
`rightHandSide`
”的默认值为
`false`
。 首先,我按照规范中的说明实现了该方法,但是这对我来说并不舒服,我认为这是摆脱这种冷酷感觉的另一种方法:
```
java
public
void
someMethod
(
String
someParameter
,
boolean
rightHandSide
)
{
...
...
@@ -276,9 +276,9 @@ if(!rightHandSide) {
}
```
好吧,这似乎并不坏,但是如何扩展功能呢? 如果一方不重要怎么办? 在这种情况下,可以使用其他布尔参数扩展该方法,但从长远来看,它不会成功。 而且因为“
rightHandSide”的默认值为 false,所以我需要创建一个未提供参数的调用,并且使用 false
调用默认方法。
好吧,这似乎并不坏,但是如何扩展功能呢? 如果一方不重要怎么办? 在这种情况下,可以使用其他布尔参数扩展该方法,但从长远来看,它不会成功。 而且因为“
`rightHandSide`
”的默认值为
`false`
,所以我需要创建一个未提供参数的调用,并且使用
`false`
调用默认方法。
因此,我引入了一个名为
Side
的新枚举,并替换了布尔参数:
因此,我引入了一个名为
`Side`
的新枚举,并替换了布尔参数:
```
java
public
enum
Side
{
...
...
@@ -297,5 +297,5 @@ if(side == Side.RIGHT_HAND) {
## 结论
如您所见,
Enums
非常适合替换常量-有时也可以使用布尔方法参数。
如您所见,
枚举
非常适合替换常量-有时也可以使用布尔方法参数。
docs/62.md
浏览文件 @
86e54a98
...
...
@@ -4,10 +4,10 @@
可以以两种方式使用线程术语
*
类
*java.lang.Thread*
的实例
*
类
`java.lang.Thread`
的实例
*
执行线程
线程的
*实例
是一个对象,与 Java 中的其他任何对象一样,它包含在堆上生存和死亡的变量和方法。 但是*
执行线程
*是一个单独的进程,具有其*
栈
*调用** 。 即使您没有在程序中创建任何线程,一个线程也将在其中运行,然后 *
main()
*方法将启动该线程。*
线程的
*实例
*
是一个对象,与 Java 中的其他任何对象一样,它包含在堆上生存和死亡的变量和方法。 但是
*执行线程*
是一个单独的进程,具有其
*栈*
调用。 即使您没有在程序中创建任何线程,一个线程也将在其中运行,然后
`main()`
方法将启动该线程。
**注意**
:如果是线程,大多数事情都是不可预测的。
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录