https://www.jb51.net/program/330116r71.htm
问题场景
子类StudentResp继承父类PersonResp,子类也拥有了父类的属性。
给子类中继承的父类属性的赋值,但是打印了以后只会显示子类信息,父类信息不显示。
- 子类:学生类继承父类人员类
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
- 父类:人员类
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
代码中给子类以及继承的父类信息赋值然后打印
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
打印出来只有子类自己的属性,父类的属性没有出来
问题分析
单独获取子类中父类的信息(name跟age),观察打印看有没有值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
打印出来发现是有值的
确认了继承本身是没有问题的,继承的父类的值都可以给上,也能获取到,随后直接打开target对应目录下的StudentResp子类,观察编译后的代码
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 |
|
看到这里,大多数同学应该已经定位到出现问题的原因了。
最后的toString()方法可以明确的看到这里只取了子类本身的两个属性,并没有去获取父类的属性。
问题原因
通过看编译后的代码可以得出@Data不会打印继承的父类信息是因为该注解本身作用域的问题,@Data注解在编译时会自动给实体类添加@Setter,@Getter,@ToString等方法。
但是@Data注解的作用域只在当前类中,所以最终打印的时候只会打印出当前类(子类)的信息。
即使子类拥有的是全属性,但是打印不会显示父类信息。
解决方式
本文介绍两种解决方案。
- 第一种:在子类上添加@ToString(callSuper = true)注解,该注解会将父类的属性跟子类的属性一起生成toString;
- 第二种:不使用@Data注解,使用@Setter,@Getter注解,在父类中重写toString()方法并用JSON的方式打印。
1.子类添加@ToString(callSuper = true)注解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
打印子类
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
结果可以看到父类信息
再看看target中子类编译后的代码
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 |
|
可以明确的看到最后的toString()方法中多了一个super.toString()方法,将父类的信息打印出来
2.不使用@Data注解,使用@Setter,@Getter注解,在父类中重写toString()方法并用JSON的方式打印。
子类使用@Setter,@Getter注解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
父类中重写toString()方法并用JSON的方式打印
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
打印子类
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
结果也可以看到父类信息
总结
这个问题本身不算是个大问题,延伸出来更为重要的是我们解决问题的思路。因为从本质上来说属性本身都是存在的,只是没打印出来。
但是遇到这个问题的时候第一反应都是,明明继承了父类,为啥父类的值会没有,从而会带偏我们去解决问题方向,遇到此类问题,第一我们应该先确认问题的本质,到底有没有给上值,确认了已经给上值,就说明只是打印的问题,进而去编译后的代码中查看为啥没打印出来,最终定位到问题从而解决问题。