内部类一般分为两种:静态内部类和非静态内部类。
1. 什么叫做静态内部类
static声明的内部类称为静态内部类。静态内部类在行为上就是一个顶级类,它嵌套在一个顶级类中以方便打包。
和静态方法一样,静态内部类不能直接引用外部类的实例变量和方法,只能通过对象的引用来使用它们。
public class TestNest {
private String abc="123";
public String getAbc() {
return abc;
}
/**
* 静态内部类
*/
static class NestClazz {
public void test() {
//需要创建外部类对象
TestNest testNest = new TestNest();
System.out.println(testNest.abc);
System.out.println(testNest.getAbc());
}
}
public static void main(String[] args) {
//使用静态内部类
TestNest.NestClazz nestClazz=new TestNest.NestClazz();
nestClazz.test();
}
}
2. 为什么存在静态内部类
静态内部类在行为上本身就是一个顶级类,那么为什么要使用静态内部类呢?
比如A,B两个类,B有点特殊,虽然可以单独存在,但只能被A使用。那么此时应该怎么办?若是将B并入到A中,复杂性提高,搞得A违反单一职责,如果B独立,又可以被其他类依赖,不符合设计的本意。若设计为A.B,其他类就不能依赖B了。
静态内部类没有必要单独存放一个文件,并且它只能被所在的外部类使用,并且它可以直接被用于 外部类名+内部类名获取。
3. 静态内部类案例
静态内部类一个典型的使用案例便是建筑者设计模式,而lombok插件中,使用@Builder注解,便可以为POJO类增加建造者模式。
源代码:
@Builder(toBuilder = true)
@Getter
public class Address {
private String address;
private String phone;
}
编译后的class代码:
public class Address {
private String address;
private String phone;
Address(String address, String phone) {
this.address = address;
this.phone = phone;
}
public static AddressBuilder builder() {
return new AddressBuilder();
}
public AddressBuilder toBuilder() {
return new AddressBuilder().address(this.address).phone(this.phone);
}
public String getAddress() {
return this.address;
}
public String getPhone() {
return this.phone;
}
/**
* 静态内部类。该内部类只能被外部类使用。
*/
public static class AddressBuilder {
private String address;
private String phone;
public AddressBuilder address(String address) {
this.address = address;
return this;
}
public AddressBuilder phone(String phone) {
this.phone = phone;
return this;
}
//真正创建对象
public Address build() {
return new Address(this.address, this.phone);
}
public String toString() {
return "Address.AddressBuilder(address=" + this.address + ", phone=" + this.phone + ")";
}
}
}
测试方法:
public class Test {
public static void main(String[] args) {
//而实际上我们创建的是一个静态内部类对象
Address.AddressBuilder addressBuilder = Address.builder().address("a").phone("b");
Address build = addressBuilder.build();
}
}
4. mybatis与静态内部类
若类B只能被类A使用,并且不希望将类B并入到类A中(会导致类的复杂性提高)。也不希望将B独立,会造成项目的冗余,便可以使用静态内部类,来尽可能的提高代码的可读性。
但是代码可读性提高的同时,如何进行mybatis的赋值?
POJO类:
将People对象中的Certificates(证件)信息抽取为一个静态内部类。
@Getter
@Builder(toBuilder = true)
public class People {
/**
* 编号
*/
private String id;
/**
* 姓名
*/
private String name;
/**
* 证件信息
*/
private Certificates certificates;
/**
* 证件信息静态内部类
*/
@Getter
@Builder(toBuilder = true)
static class Certificates {
/**
* 证件编号
*/
private String certNo;
/**
* 身份证正面照
*/
private String certBeforeImg;
/**
* 身份证反面照
*/
private String certAfterImg;
}
}
普通方法的赋值:
public static void main(String[] args) {
People.Certificates certificates = People.Certificates.builder().certNo("1273821653821").certAfterImg("a.img").certBeforeImg("b.img").build();
People people = People.builder().id("001").name("tom").certificates(certificates).build();
System.out.println(JSON.toJSONString(people));
}
对象中的属性为其他对象,此时我们需要自定义返回参数:resultMap
而此时对应关系为1:1,我们需要使用association来完成映射。 额搜神a神
<resultMap type="com.inner.People" id="PeopleInfo">
<id column="id" property="id" />
<result column="name" property="name" />
<association property="certificates" javaType="com.inner.People.Certificates">
<id column="cert_no" property="certNo" />
<result column="cert_before_img" property="certBeforeImg" />
<result column="cert_after_img" property="certAfterImg" />
</association>
</resultMap>
<select id="getPeopleInfo" resultMap="PeopleInfo" parameterType="String">
select id,name,cert_no,cert_before_img,cert_after_img from people where id= #{id}
</select>