先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Golang全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip1024b (备注go)
正文
使用Maven导入依赖:
com.google.code.gson
gson
2.8.5
Gradle导入依赖:
compile group: ‘com.google.code.gson’, name: ‘gson’, version: ‘2.8.5’
========================================================================
使用Gson的第一步是创建一个Gson对象,创建爱你Gson对象有两种方式:
-
使用 new Gson()
-
创建GsonBuilder实例,使用 create() 方法
1.1、new Gson()
示例如下:
Gson gson = new Gson();
1.2、GsonBuilder.build()
示例如下:
GsonBuilder builder = new GsonBuilder();
Gson gson = builder.create();
下面会用到这个实体类:
public class Employee {
private int id;
private String firstName;
private String lastName;
private String email;
//省略getter/setter,构造方法,toSting方法
}
在Gson中的序列化即将Java对象转换为其JSON表示形式。 为了进行序列化,首先需要一个Gson对象,该对象可以处理转换。 接下来,需要调用函数toJson()方法并传入Employee对象。
Employee emp = new Employee(1001, “Lokesh”, “Gupta”, “howtodoinjava@gmail.com”);
Gson gson = new Gson();
String jsonString = gson.toJson(emp);
System.out.println(jsonString);
运行结果:
在Gson进行反序列指的是将JSON字符串转换为Java对象。 为了进行反序列化,我们需要使用Gson对象调用fromJson()函数,并在解析完成后传递两个参数,即JSON字符串和所需的Java类型。
String jsonString = “{‘id’:1001, ‘firstName’:‘Lokesh’, ‘lastName’:‘Gupta’, ‘email’:‘howtodoinjava@gmail.com’}”;
Gson gson = new Gson();
Employee empObject = gson.fromJson(jsonString, Employee.class);
System.out.println(empObject);
运行结果:
默认情况下,Gson以紧凑格式打印JSON,即字段名称及其值,对象字段以及JSON输出中数组内的对象等之间将没有空格。
{“id”:1,“firstName”:“Lokesh”,“lastName”:“Gupta”, “emailId”:“howtogoinjava@gmail.com”}
但是,这种紧凑的JSON可能很难阅读。因此,GSON提供了一个漂亮的打印选项,可以在其中打印JSON,以便于更加方便阅读。
Gson gson = new GsonBuilder()
.setPrettyPrinting()
.create();
Employee employeeObj = new Employee(1, “Lokesh”, “Gupta”, “howtogoinjava@gmail.com”);
System.out.println(gson.toJson(employeeObj));
运行结果:
5、JSON array --> Java array/list
5.1 、 JSON array -->Java对象
users.json:
[
{
“name”: “Alex”,
“id”: 1
},
{
“name”: “Brian”,
“id”: 2
},
{
“name”: “Charles”,
“id”: 3
}
]
User.java:
public class User
{
private long id;
private String name;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return “User [id=” + id + “, name=” + name + “]”;
}
}
将json数组反序列化为Java对象数组:
String userJson = "[{‘name’: ‘Alex’,‘id’: 1}, "
-
"{‘name’: ‘Brian’,‘id’:2}, "
-
“{‘name’: ‘Charles’,‘id’: 3}]”;
Gson gson = new Gson();
User[] userArray = gson.fromJson(userJson, User[].class);
for(User user : userArray) {
System.out.println(user);
}
运行结果:
5.2 、JSON array–>List
将json数组反序列化为根–到Java对象列表:
String userJson = "[{‘name’: ‘Alex’,‘id’: 1}, " + "{‘name’: ‘Brian’,‘id’:2}, " + “{‘name’: ‘Charles’,‘id’: 3}]”;
Gson gson = new Gson();
java.lang.reflect.Type userListType = new TypeToken<ArrayList>() {
}.getType();
ArrayList userArray = gson.fromJson(userJson, userListType);
for (User user : userArray) {
System.out.println(user);
}
运行结果:
5.3 、JSON array–>成员变量
如果Json数组是非根对象,则Gson可以将JSON数组解析为成员变量。我们可以按通常的方式使用fromJson()方法,将json数组解析为所需的Java数组或列表。
department.json:
{
“id” : 1,
“name” : “HR”,
“users” : [
{
“name”: “Alex”,
“id”: 1
},
{
“name”: “Brian”,
“id”: 2
},
{
“name”: “Charles”,
“id”: 3
}
]
5.3.1、数组类型成员变量
Department.java:
public class Department {
private long id;
private String name;
private User[] users;
//省略getter/setter、构造方法、toString方法
}
JsonArrayToMemberArray.java:
String departmentJson = "{‘id’ : 1, "
-
“‘name’: ‘HR’,”
-
“‘users’ : [”
-
"{‘name’: ‘Alex’,‘id’: 1}, "
-
"{‘name’: ‘Brian’,‘id’:2}, "
-
“{‘name’: ‘Charles’,‘id’: 3}]}”;
Gson gson = new Gson();
Department department = gson.fromJson(departmentJson, Department.class);
System.out.println(department);
运行结果:
5.3.2、List类型成员变量
将json数组反序列化为List类型成员变量。
Department2.java:
public class Department2 {
private long id;
private String name;
private List users;
//省略getter/setter、构造方法、toString方法
}
转换:
String departmentJson = "{‘id’ : 1, "
-
“‘name’: ‘HR’,”
-
“‘users’ : [”
-
"{‘name’: ‘Alex’,‘id’: 1}, "
-
"{‘name’: ‘Brian’,‘id’:2}, "
-
“{‘name’: ‘Charles’,‘id’: 3}]}”;
Gson gson = new Gson();
Department2 department = gson.fromJson(departmentJson, Department2.class);
System.out.println(department);
运行结果:
6.1、Set–>JSON
使用Gson.toJson()方法将HashSet序列化为JSON:
Set userSet = new HashSet();
userSet.add(“Alex”);
userSet.add(“Brian”);
userSet.add(“Charles”);
Gson gson = new Gson();
String jsonString= gson.toJson(userSet);
System.out.println(jsonString);
运行结果:
6.2、JSON–>Set
使用Gson.fromJson()方法和TypeToken将JSON反序列化为HashSet:
String jsonString = “[‘Alex’,‘Brian’,‘Charles’,‘Alex’]”;
Gson gson = new Gson();
java.lang.reflect.Type setType = new TypeToken<HashSet>(){}.getType();
Set userSet = gson.fromJson(jsonString, setType);
System.out.println(userSet);
运行结果:
Gson中实现的默认行为是忽略空对象字段。
例如,如果在Employee对象中未指定电子邮件(即email为null),则电子邮件将不会被序列化JSON输出。Gson会忽略null字段,因为此行为允许使用更紧凑的JSON输出格式。
7.1、如何在序列化时允许空值
要配置Gson实例以输出null,我们必须使用GsonBuilder对象的serializeNulls()。
Gson gson = new GsonBuilder()
.serializeNulls()
.create();
应用程序随着时间变化,模型类也随之变化。有时候更新/删除字段可能会被打断。
所有这些更改都可以使用@Since注释进行标记,以跟踪模型类,在这些系统使用反序列化JSON数据进行交换时,与其他系统的应用程序交互不会中断。
8.1、@Since注解
在Gson中,可以使用@Since注释维护同一对象的多个版本。可以在类,字段以及将来的方法中使用此注释。它采用单个参数– ignoreVersionsAfter。
当我们为Gson实例配置版本号“ M.N”时,所有标记有版本大于M.N的类字段都将被忽略。例如,如果我们将Gson配置为版本号“ 1.2”,则所有版本号更高的字段(例如1.3、1.4…)都将被忽略。
@Since(1.2)
private String email;
8.2、如何使用@Since注解编写版本化的类
在Employee类下面,我们对三个字段进行了版本控制,即firstName,lastName和email。
public class Employee
{
private Integer id;
@Since(1.0)
private String firstName;
@Since(1.1)
private String lastName;
@Since(1.2)
private String email;
}
8.3、创建具备版本支持的Gson实例
要创建使用过@Since注解的Gson实例,需要使用GsonBuilder.setVersion()方法:
Gson gson = new GsonBuilder()
.setVersion(1.1)
.create();
8.4、实例
8.4.1、 具备版本支持的序列化
让序列号以上的Employee对象序列化。
Employee employeeObj = new Employee(1, “Lokesh”, “Gupta”, “howtogoinjava@gmail.com”);
Gson gson = new GsonBuilder()
.setVersion(1.1)
.setPrettyPrinting()
.create();
System.out.println(gson.toJson(employeeObj));
输出:
{
“id”: 1,
“firstName”: “Lokesh”,
“lastName”: “Gupta”
}
8.4.2、具备版本支持的反序列化
我们将JSON字符串反序列化为版本号为Employee的对象。
String json = "{‘id’: 1001, "
-
“‘firstName’: ‘Lokesh’,”
-
“‘lastName’: ‘Gupta’,”
-
“‘email’: ‘howtodoinjava@gmail.com’}”;
Gson gson = new GsonBuilder()
.setVersion(1.1)
.setPrettyPrinting()
.create();
Employee employeeObj = gson.fromJson(json, Employee.class);
System.out.println(employeeObj);
输出:
Employee [id=1001, firstName=Lokesh, lastName=Gupta, email=null]
在此Gson @SerializedName示例中,演示在序列化和反序列化过程中更改json和java对象之间的字段名称。
9.1、@SerializedName
默认情况下,我们假设Java模型类和JSON将具有完全相同的字段名称。
但有时情况并非如此,某些名称有所不同。现在我们必须将json中的someName映射到Java类中的someOtherName。这是@SerializedName注解用到的地方。
@SerializedName注解指示带注解的成员变量应使用提供的名称值作为其字段名称序列化为JSON。此注解将覆盖可能一直在使用GsonBuilder类的任何FieldNamingPolicy,包括默认的字段命名策略。
请注意,在此注解中指定的值必须是有效的JSON字段名称。
注解包含属性
-
value –序列化或反序列化时所需的字段名称。
-
alternate–反序列化时字段的备用名称。除了“值”属性外,它还提供了更多可能的名称。如果有多个字段匹配一个属性,则Gson将使用最后处理的那个。
9.2、序列化期时更改字段名称
让我们以只有四个字段的Employee类为例。我们要创建一个JSON,其中“ email”被写为字段名“ emailId”:
public class Employee
{
private Integer id;
private String firstName;
private String lastName;
@SerializedName(value = “emailId”, alternate = “emailAddress”)
private String email;
}
让我们序列化一个Employee实例并查看JSON输出:
Employee emp = new Employee(1001, “Lokesh”, “Gupta”, “howtodoinjava@gmail.com”);
Gson gson = new GsonBuilder().setPrettyPrinting().create();
System.out.println(gson.toJson(emp));
输出:
{
“id”: 1001,
“firstName”: “Lokesh”,
“lastName”: “Gupta”,
“emailId”: “howtodoinjava@gmail.com”
}
9.3、反序列化时更改字段名称
在将JSON反序列化为Java类的过程中映射不同的字段名称:
Json:
{
“id”: 1001,
“firstName”: “Lokesh”,
“lastName”: “Gupta”,
“email”: “howtodoinjava@gmail.com”,
“emailAddress”: “admin@gmail.com”
}
Main.java:
String json = “{‘id’: 1001,”
-
“‘firstName’: ‘Lokesh’,”
-
“‘lastName’: ‘Gupta’,”
-
“‘email’: ‘howtodoinjava@gmail.com’,”
-
“‘emailAddress’: ‘admin@gmail.com’}”;
Gson gson = new GsonBuilder().setPrettyPrinting().create();
Employee emp = gson.fromJson(json, Employee.class);
System.out.println(emp);
输出:
Employee [id=1001, firstName=Lokesh, lastName=Gupta, email=admin@gmail.com]
Gson允许我们从Java类中排除或忽略不希望包含在序列化和反序列化中的字段。
Gson支持许多内置机制,用于排除顶级类,字段和字段类型。
10.1、@Expose注解
GSON @Expose注解(com.google.gson.annotations.Expose)可用于标记对象序列化或反序列化时是否公开(包括活不包括)的字段。
@Expose注释在要显式指定应进行序列化或反序列化的所有字段的编程方式中很有用。
10.1.1. 怎么用 @Expose
@Expose是可选的,并提供两个配置参数:
-
serialize –如果为true,则在序列化时会在JSON中写出带有此注解的字段。
-
deserialize –如果为true,则从JSON反序列化带有此注解的字段。
@Expose(serialize = false)
private String lastName;
@Expose (serialize = false, deserialize = false)
private String emailAddress;
10.1.2、创建Gson实例
如果我们使用 new Gson() 创建Gson并执行toJson() 和 fromJson() 方法,则@Expose将不会对序列化和反序列化产生任何影响。要使用此批注,我们必须使用GsonBuilder类及其excludeFieldsWithoutExposeAnnotation()方法创建Gson实例。
Gson gson = new GsonBuilder()
.excludeFieldsWithoutExposeAnnotation()
.create();
10.2、用修饰符排除字段
10.2.1、transient 字段
默认情况下,如果我们仅将字段标记为瞬时态,则Gson会将字段从序列化和反序列化中排除。
请记住,它无法阻止单向转换。它同时阻止了两者。
transient 具有与@Expose相同的效果(serialize = false,deserialize = false)。
@Expose(serialize = false)
private String lastName;
private transient String emailAddress;
10.2.2、其他修饰符
通过使用GsonBuilder的excludeFieldsWithModifiers()方法,我们可以排除具有某些公共修饰符的字段。
例如,我们要排除一个类的所有静态成员,我们可以这样创建Gson对象:
Gson gson = new GsonBuilder()
.excludeFieldsWithModifiers(Modifier.STATIC)
.create();
我们可以使用任意数量的Modifier常量来“ excludeFieldsWithModifiers”方法。例如:
Gson gson = new GsonBuilder()
.excludeFieldsWithModifiers(Modifier.STATIC,
Modifier.TRANSIENT,
Modifier.VOLATILE)
.create();
10.3、排除策略
如果以上任何一种技术都不适合我们,那么我们可以创建自己的策略。
ExclusionStrategy用于确定是否应将字段或顶级类作为JSON输出/输入的一部分进行序列化或反序列化。
-
对于序列化,如果shouldSkipClass(Class)或shouldSkipField(fieldAttributes)方法返回true,则该类或字段类型将不属于JSON输出。
-
对于反序列化,如果shouldSkipClass(Class)或shouldSkipField(fieldAttributes)方法返回true,则不会将其设置为Java对象结构的一部分。
例如,在ExclusionStrategy定义下面,将排除所有使用@Hidden注释注释的字段:
//public @interface Hidden {
// some implementation here
//}
// Excludes any field (or class) that is tagged with an “@Hidden”
public class HiddenAnnotationExclusionStrategy implements ExclusionStrategy
{
public boolean shouldSkipClass(Class<?> clazz) {
return clazz.getAnnotation(Hidden.class) != null;
}
public boolean shouldSkipField(FieldAttributes f) {
return f.getAnnotation(Hidden.class) != null;
}
}
要使用此排除策略,在GsonBuilder对象中进行设置:
GsonBuilder builder = new GsonBuilder();
builder.setExclusionStrategies( new HiddenAnnotationExclusionStrategy() );
Gson gson = builder.create();
===============================================================================
对于简单的用例,使用’Gson gson = new Gson();’ 标准配置就足够了。 但是,如果打算自定义Gson的行为,则可以使用GsonBuilder自定义的配置来创建新的Gson实例。
GsonBuilder类提供一个.create()方法,该方法返回一个Gson实例。
Gson gson = new GsonBuilder().create();
1、GsonBuilder.setPrettyPrinting()–漂亮地打印JSON
默认情况下,Gson将创建紧凑的JSON字符串。这对于减少通过网络传输的数据量非常有用。
但是,这种紧凑的JSON对开发人员进行开发/调试应用程序时不友好。使用漂亮的打印来格式化JSON输出:
Gson gson = new GsonBuilder()
.setPrettyPrinting()
.create();
FieldNamingPolicy枚举在序列化期间为JSON字段名称提供了几种标准命名约定。
它有助于Gson实例将Java字段名称正确转换为所需的JSON字段名称。
注意:以下任何命名约定均不会影响以@SerializedName注释的字段。我们将验证使用User类的每个策略生成的名称。
User.java:
public class User
{
private int id;
private String first_Name;
private String lastName;
private String _email;
}
如何使用FieldNamingPolicy:
User user = new User(1, “Lokesh”, “Gupta”, “admin@howtodoinjava.com”);
Gson gson = new GsonBuilder()
.setFieldNamingPolicy(FieldNamingPolicy.IDENTITY)
.setPrettyPrinting().create();
System.out.println(gson.toJson(user));
以下演示每种命名策略下转换的不同的名称。
2.1、FieldNamingPolicy.IDENTITY
使用此命名策略字段名称不变。这个是默认的策略:
{
“id”: 1,
“first_Name”: “Lokesh”,
“lastName”: “Gupta”,
“_email”: “admin@howtodoinjava.com”
}
2.2、FieldNamingPolicy.LOWER_CASE_WITH_DASHES
Gson会将Java字段名称从其驼峰大小写形式修改为小写的字段名称,其中每个单词都用破折号(-)分隔。
{
“id”: 1,
“first_-name”: “Lokesh”,
“last-name”: “Gupta”,
“_email”: “admin@howtodoinjava.com”
}
2.3、FieldNamingPolicy.LOWER_CASE_WITH_DOTS
Gson会将Java字段名称从其驼峰大小写形式修改为小写的字段名称,其中每个单词都用点(.)分隔:
{
“id”: 1,
“first_.name”: “Lokesh”,
“last.name”: “Gupta”,
“_email”: “admin@howtodoinjava.com”
}
2.4、FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES
Gson会将Java字段名称从其驼峰大小写形式修改为小写的字段名称,其中每个单词都用下划线(_)分隔。
{
“id”: 1,
“first__name”: “Lokesh”,
“last_name”: “Gupta”,
“_email”: “admin@howtodoinjava.com”
}
2.5、 FieldNamingPolicy.UPPER_CAMEL_CASE
Gson将确保序列化为JSON格式的Java字段名称的第一个“字母”大写:
{
“Id”: 1,
“First_Name”: “Lokesh”,
“LastName”: “Gupta”,
“_Email”: “admin@howtodoinjava.com”
}
2.6、FieldNamingPolicy.UPPER_CAMEL_CASE_WITH_SPACES
Gson将确保在将Java字段名称的第一个“字母”序列化为JSON格式时将其大写,并且单词之间将使用空格分隔:
{
“Id”: 1,
“First_ Name”: “Lokesh”,
“Last Name”: “Gupta”,
“_Email”: “admin@howtodoinjava.com”
}
3、GsonBuilder.serializeNulls()——空值的序列化
默认情况下,Gson会在序列化过程中忽略null值。但是,有时我们想序列化具有空值的字段,以便它必须出现在JSON中。为此,可以使用serializeNulls()方法:
Employee employeeObj = new Employee(1, “Lokesh”, “Gupta”, null);
Gson gson = new GsonBuilder()
.serializeNulls()
.setPrettyPrinting().create();
System.out.println(gson.toJson(employeeObj));
输出:
{
“id”: 1,
“firstName”: “Lokesh”,
“lastName”: “Gupta”,
“emailId”: null
}
4、GsonBuilder.setExclusionStrategies()
ExclusionStrategy用于确定是否应将字段或顶级类作为JSON输出/输入的一部分进行序列化或反序列化。
-
对于序列化,如果shouldSkipClass(Class)方法返回true,则该类或字段类型将不会在JSON中输出。
-
对于反序列化,如果shouldSkipClass(Class)返回true,则不会将其设置为Java对象结构的一部分。
shouldSkipField(attribute)方法也是相同的规则。
在下面的示例中,使用@NPI注解和属于Account类的实例的成员字段不会进行序列化和反序列化。
Gson gson = new GsonBuilder()
.setExclusionStrategies(new ExclusionStrategy() {
@Override
public boolean shouldSkipField(FieldAttributes f) {
return f.getAnnotation(NPI.class) != null;
}
@Override
public boolean shouldSkipClass(Class<?> clazz) {
return clazz.getAnnotation(Account.class) != null;
}
})
.setPrettyPrinting()
.create();
5、GsonBuilder.setLenient()——宽松的JSON语法规则
在反序列化期间,Gson使用了一个宽松的JsonReader类。这意味着它仅接受兼容的JSON输入。
如果JSON违反结构规则之一,它将抛出MalformedJsonException。如果我们将lenient设置为true,则它将忽视某些违规行为,并尝试读取格式不正确的JSON。
Gson gson = new GsonBuilder()
.setLenient()
.setPrettyPrinting().create();
==============================================================================
使用Gson JsonReader类,该类是基于拉式的流JSON解析器。它有助于将JSON作为令牌流读取。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Go)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
;
System.out.println(gson.toJson(employeeObj));
输出:
{
“id”: 1,
“firstName”: “Lokesh”,
“lastName”: “Gupta”,
“emailId”: null
}
4、GsonBuilder.setExclusionStrategies()
ExclusionStrategy用于确定是否应将字段或顶级类作为JSON输出/输入的一部分进行序列化或反序列化。
-
对于序列化,如果shouldSkipClass(Class)方法返回true,则该类或字段类型将不会在JSON中输出。
-
对于反序列化,如果shouldSkipClass(Class)返回true,则不会将其设置为Java对象结构的一部分。
shouldSkipField(attribute)方法也是相同的规则。
在下面的示例中,使用@NPI注解和属于Account类的实例的成员字段不会进行序列化和反序列化。
Gson gson = new GsonBuilder()
.setExclusionStrategies(new ExclusionStrategy() {
@Override
public boolean shouldSkipField(FieldAttributes f) {
return f.getAnnotation(NPI.class) != null;
}
@Override
public boolean shouldSkipClass(Class<?> clazz) {
return clazz.getAnnotation(Account.class) != null;
}
})
.setPrettyPrinting()
.create();
5、GsonBuilder.setLenient()——宽松的JSON语法规则
在反序列化期间,Gson使用了一个宽松的JsonReader类。这意味着它仅接受兼容的JSON输入。
如果JSON违反结构规则之一,它将抛出MalformedJsonException。如果我们将lenient设置为true,则它将忽视某些违规行为,并尝试读取格式不正确的JSON。
Gson gson = new GsonBuilder()
.setLenient()
.setPrettyPrinting().create();
==============================================================================
使用Gson JsonReader类,该类是基于拉式的流JSON解析器。它有助于将JSON作为令牌流读取。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Go)
[外链图片转存中…(img-HLpHO9F7-1713311897693)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!