Java基础知识

概述

本篇主要是对java基础的使用场景的总结

常见使用场景

  1. 静态内部类和非静态内部类的使用场景

    • 静态内部类可以有静态成员(方法和属性),而非静态内部类则不能有静态成员(成员或属性)
    • 静态内部类只能够访问外部类的静态成员和静态方法,而非静态内部类则可以访问外部类的所有成员(方法和属性)
  2. 静态代码块和代码块的使用场景

    • 静态代码块,在虚拟机加载类的时候就会加载执行,而且只执行一次;
    • 非静态代码块,在创建对象的时候(即new一个对象的时候)执行,每次创建对象都会执行一次
  3. LinkHashmap使用场景

    • 如果需要输出的顺序和输入的相同,那么用LinkedHashMap 可以实现,它还可以按读取顺序来排列
    • 如果您要按自然顺序或自定义顺序遍历键,那么TreeMap会更好
  4. 接口里定义的成员变量为什么是 public static final

    接口提供的统一的抽象, 所以接口中的属性必然是常量,只能读不能改,这样才能为实现接口的对象提供一个统一的属性

  5. 项目中日志如何使用

    假设我们有些日志是debug级别, 那么应该如下

    1
    2
    3
    if (logger.isDebugEnabled()) {
    logger.debug("Initializing filter '" + filterConfig.getFilterName() + "'");
    }
  6. 用户自定义系统属性

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    @Slf4j
    public class TestController {

    public static void main(String[] args) {
    System.setProperty("blog.host", "http://idea360.cn");
    String property = System.getProperty("blog.host");
    if (log.isInfoEnabled()) {
    log.info(property);
    }

    }
    }
  7. 获取系统环境变量

    1
    2
    Map<String, String> getenv = System.getenv();

序列化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
package com.example.demoboot.jackson;

import com.fasterxml.jackson.annotation.JsonAlias;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.format.annotation.DateTimeFormat;

import java.time.LocalDateTime;

/**
* @author cuishiying
* @date 2021-01-22
*/
@Slf4j
@Data
public class User {

/**
* Json反序列化: 将Json Data转化为Java Object
* Json的序列化: 将Java Object转化为JSON Data
*
* 将java中[name]字段序列化为json中的[NAME]字段.
* 注意: 反序列化时也必须用[NAME]字段, 否则会报: UnrecognizedPropertyException: Unrecognized field "name"
*/
@JsonProperty("NAME")
private String name;

/**
* 将json中的age_alias字段反序列化为java的[age]字段
*/
@JsonAlias("age_alias")
private Integer age;

/**
* @DateTimeFormat 是将String转换成Date,一般前台给后台传值时用
* @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") 将Date转换成String, 一般后台传值给前台时
* 东八区(UTC/GMT+08:00)比世界协调时间(UTC)/格林尼治时间(GMT)快8小时
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime date;

/**
* 18:06:17.194 [main] INFO com.example.demoboot.jackson.User - 序列化: {"age":17,"date":"2022-01-08 18:06:16","NAME":"当我遇上你"}
* 18:06:17.226 [main] INFO com.example.demoboot.jackson.User - 反序列化: User(name=当我遇上你, age=17, date=2022-01-08T18:01:38)
*/
public static void main(String[] args) throws Exception{
User user = new User();
user.setName("当我遇上你");
user.setAge(17);
user.setDate(LocalDateTime.now());

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
String json = objectMapper.writeValueAsString(user);
log.info("序列化: {}", json);

String json1 = "{\"age_alias\":17,\"date\":\"2022-01-08 18:01:38\",\"NAME\":\"当我遇上你\"}";
User user1 = objectMapper.readValue(json1, User.class);
log.info("反序列化: {}", user1);
}
}

日期格式化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.example.demoboot.jackson;

import lombok.extern.slf4j.Slf4j;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
* @author cuishiying
* @date 2021-01-22
*/
@Slf4j
public class DateTest {

public static final DateTimeFormatter YYYY_MM_DD_HH_MM_SS_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

public static void main(String[] args) {
LocalDateTime beginTime = LocalDateTime.parse("2022-01-04 12:00:00", YYYY_MM_DD_HH_MM_SS_FORMAT);
log.info("beginTime: {}", beginTime);
String format = beginTime.format(YYYY_MM_DD_HH_MM_SS_FORMAT);
log.info("format: {}", format);
}
}

日期全局配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package com.example.demoboot.jackson;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.TimeZone;

/**
* @author cuishiying
* @date 2021-01-22
*/
@Configuration
public class JacksonConfig implements WebMvcConfigurer {

/**
* 默认日期时间格式
*/
public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

/**
* 默认日期格式
*/
public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";

/**
* 默认时间格式
*/
public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";

/**
* 使用此方法, 以下 spring-boot: jackson时间格式化 配置 将会失效 spring.jackson.time-zone=GMT+8
* spring.jackson.date-format=yyyy-MM-dd HH:mm:ss 原因: 会覆盖 @EnableAutoConfiguration 关于
* WebMvcAutoConfiguration 的配置
*/
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();

ObjectMapper objectMapper = converter.getObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
objectMapper.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE);

// 忽略json字符串中不识别的属性
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// 忽略无法转换的对象
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
// PrettyPrinter 格式化输出
objectMapper.configure(SerializationFeature.INDENT_OUTPUT, true);
// 指定时区
objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));
// 日期类型字符串处理
objectMapper.setDateFormat(new SimpleDateFormat(DEFAULT_DATE_TIME_FORMAT));

// LocalDateTime系列序列化和反序列化模块,继承自jsr310,我们在这里修改了日期格式
SimpleModule simpleModule = new SimpleModule();
// LocalDateTime时间格式化
simpleModule.addSerializer(LocalDateTime.class,
new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)));
// LocalDate时间格式化
simpleModule.addSerializer(LocalDate.class,
new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)));
// LocalTime时间格式化
simpleModule.addSerializer(LocalTime.class,
new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));
// LocalDateTime时间格式化
simpleModule.addDeserializer(LocalDateTime.class,
new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)));
// LocalDate时间格式化
simpleModule.addDeserializer(LocalDate.class,
new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)));
// LocalTime时间格式化
simpleModule.addDeserializer(LocalTime.class,
new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));

objectMapper.registerModule(simpleModule);

converter.setObjectMapper(objectMapper);
converters.add(0, converter);
}

}

或者

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Configuration
public class JacksonConfig {

private static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

public LocalDateTimeSerializer localDateTimeDeserializer() {
return new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT));
}

@Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
return builder -> builder.serializerByType(LocalDateTime.class, localDateTimeDeserializer());
}

}

或者

1
2
3
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;

枚举

字符串转枚举

1
2
3
public enum SqlCommandType {
INSERT,UPDATE,DELETE,SELECT;
}
1
SqlCommandType sqlCommandType = SqlCommandType.valueOf("select".toUpperCase(Locale.ENGLISH));

别名管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class TypeAliasRegistry {

private final Map<String, Class<?>> TYPE_ALIASES = new HashMap<>();

public TypeAliasRegistry() {
// 构造函数里注册系统内置的类型别名
registerAlias("string", String.class);

// 基本包装类型
registerAlias("byte", Byte.class);
registerAlias("long", Long.class);
registerAlias("short", Short.class);
registerAlias("int", Integer.class);
registerAlias("integer", Integer.class);
registerAlias("double", Double.class);
registerAlias("float", Float.class);
registerAlias("boolean", Boolean.class);
}

public void registerAlias(String alias, Class<?> value) {
String key = alias.toLowerCase(Locale.ENGLISH);
TYPE_ALIASES.put(key, value);
}

public <T> Class<T> resolveAlias(String string) {
String key = string.toLowerCase(Locale.ENGLISH);
return (Class<T>) TYPE_ALIASES.get(key);
}

}

最后

本文到此结束,感谢阅读。如果您觉得不错,请关注公众号【当我遇上你】,您的支持是我写作的最大动力。