前言

在项目开发过程中,我们需要用实体接收传递过来的参数,若前端传来的Json结构比较复杂,我们就需要用相对复杂的实体接收参数,即一个DTO引用另一个DTO,这时候如果我们建两个实体,看起来还是不够“简洁”。所以这里就用到了内部类。将内部复杂的结构放到内部类中处理。本文的重头戏,静态内部类粉墨登场了。

拾遗-什么是内部类

在Java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。广泛意义上的内部类一般来说包括这四种:成员内部类、局部内部类、匿名内部类和静态内部类。下面就先来了解一下这四种内部类的用法。

1.成员内部类

成员内部类是最普通的内部类,它的定义为位于另一个类的内部,形如下面的形式:

class Circle {double radius = 0;public Circle(double radius) {this.radius = radius;}class Draw {     //内部类public void drawSahpe() {System.out.println("drawshape");}}
}

这样看起来,类Draw像是类Circle的一个成员,Circle称为外部类。成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员)。

class Circle {private double radius = 0;public static int count =1;public Circle(double radius) {this.radius = radius;}class Draw {     //内部类public void drawSahpe() {System.out.println(radius);  //外部类的private成员System.out.println(count);   //外部类的静态成员}}
}

不过要注意的是,当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认情况下访问的是成员内部类的成员。如果要访问外部类的同名成员,需要以下面的形式进行访问:

外部类.this.成员变量
外部类.this.成员方法

虽然成员内部类可以无条件地访问外部类的成员,而外部类想访问成员内部类的成员却不是这么随心所欲了。在外部类中如果要访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问:

class Circle {private double radius = 0;public Circle(double radius) {this.radius = radius;getDrawInstance().drawSahpe();   //必须先创建成员内部类的对象,再进行访问}private Draw getDrawInstance() {return new Draw();}class Draw {     //内部类public void drawSahpe() {System.out.println(radius);  //外部类的private成员}}
}

成员内部类是依附外部类而存在的,也就是说,如果要创建成员内部类的对象,前提是必须存在一个外部类的对象。创建成员内部类对象的一般方式如下:

public class Test {public static void main(String[] args)  {//第一种方式:Outter outter = new Outter();Outter.Inner inner = outter.new Inner();  //必须通过Outter对象来创建//第二种方式:Outter.Inner inner1 = outter.getInnerInstance();}
}class Outter {private Inner inner = null;public Outter() {}public Inner getInnerInstance() {if(inner == null)inner = new Inner();return inner;}class Inner {public Inner() {}}
}

内部类可以拥有 private 访问权限、protected 访问权限、public 访问权限及包访问权限。比如上面的例子,如果成员内部类 Inner 用 private 修饰,则只能在外部类的内部访问,如果用 public 修饰,则任何地方都能访问;如果用 protected 修饰,则只能在同一个包下或者继承外部类的情况下访问;如果是默认访问权限,则只能在同一个包下访问。这一点和外部类有一点不一样,外部类只能被 public 和包访问两种权限修饰。我个人是这么理解的,由于成员内部类看起来像是外部类的一个成员,所以可以像类的成员一样拥有多种权限修饰。

2.局部内部类

局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。

class People{public People() {}
}class Man{public Man(){}public People getWoman(){class Woman extends People{   //局部内部类int age =0;}return new Woman();}
}

注意: 局部内部类就像是方法里面的一个局部变量一样,是不能有 public、protected、private 以及 static 修饰符的。

3.匿名内部类

匿名内部类应该是平时我们编写代码时用得最多的,在编写事件监听的代码时使用匿名内部类不但方便,而且使代码更加容易维护。下面这段代码是一段 Android 事件监听代码:

scan_bt.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stub}
});history_bt.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stub}
});

这段代码为两个按钮设置监听器,这里面就使用了匿名内部类。这段代码中的:

new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stub}
}

就是匿名内部类的使用。代码中需要给按钮设置监听器对象,使用匿名内部类能够在实现父类或者接口中的方法情况下同时产生一个相应的对象,但是前提是这个父类或者接口必须先存在才能这样使用。当然像下面这种写法也是可以的,跟上面使用匿名内部类达到效果相同。

private void setListener()
{scan_bt.setOnClickListener(new Listener1());       history_bt.setOnClickListener(new Listener2());
}class Listener1 implements View.OnClickListener{@Overridepublic void onClick(View v) {// TODO Auto-generated method stub}
}class Listener2 implements View.OnClickListener{@Overridepublic void onClick(View v) {// TODO Auto-generated method stub}

这种写法虽然能达到一样的效果,但是既冗长又难以维护,所以一般使用匿名内部类的方法来编写事件监听代码。同样的,匿名内部类也是不能有访问修饰符和 static 修饰符的。

匿名内部类是唯一一种没有构造器的类。正因为其没有构造器,所以匿名内部类的使用范围非常有限,大部分匿名内部类用于接口回调。匿名内部类在编译的时候由系统自动起名为 Outter$1.class。一般来说,匿名内部类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写。

4.静态内部类

静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字static。静态内部类是不需要依赖于外部类的,这点和类的静态成员属性有点类似,并且它不能使用外部类的非static成员变量或者方法,这点很好理解,因为在没有外部类的对象的情况下,可以创建静态内部类的对象,如果允许访问外部类的非static成员就会产生矛盾,因为外部类的非static成员必须依附于具体的对象。

public class Test {public static void main(String[] args)  {Outter.Inner inner = new Outter.Inner();}
}class Outter {public Outter() {}static class Inner {public Inner() {}}
}

能工巧匠-巧用内部类接受参数

为了解决解决接口复杂参数的解析问题,我们使用内部类进行接受。可以参考如下demo

Json参数格式

{"name":"美女","age":18,"school":{"schoolName":"北大","grade":2}
}

接收实体

@Data
public class User {private String name;private int age;private SchoolInfo schoolInfo;public static class SchoolInfo{private String schoolName;private int grade;}}

我们只要按照Json的格式定义好DTO格式就好。

小结

软件开发就像盖房子,我们得不断思考怎么设计房子才能更漂亮。更舒适。代码的整洁看着舒心,维护起来也方便。

SpringBoot巧用静态内部类优雅地接收参数相关推荐

  1. SpringBoot+Mybatis-plus:使用枚举接收参数并返回数据

    文章目录 SpringBoot+Mybatis-plus:使用枚举接收参数并返回数据 枚举的好处 枚举使用场景 枚举在项目中的使用 第一种形式 第二种形式 实体类的枚举字段保存到数据库,并且返回时自动 ...

  2. SpringBoot - Post请求-接收参数

    一.接收Form表单数据 1.1.基本的接收方法 1.下面样例 Controller 接收 form-data 格式的 POST 数据: package com.example.demo;import ...

  3. 使用 Spring Validation 优雅地进行参数校验

    引言 不知道大家平时的业务开发过程中 controller 层的参数校验都是怎么写的?是否也存在下面这样的直接判断? public String add(UserVO userVO) {if(user ...

  4. Spring Boot 如何优雅的校验参数?

    今天介绍一下 Spring Boot 如何优雅的整合JSR-303进行参数校验,说到参数校验可能都用过,但网上的教程大多是简单的介绍,所以我们今天详细看来一下 . 什么是 JSR-303? JSR-3 ...

  5. Struts2中Action接收参数

    Struts2中Action接收参数的方法主要有以下三种: Struts2中Action接收参数的方法主要有以下三种: 1.使用Action的属性接收参数:     a.定义:在Action类中定义属 ...

  6. 小程序 url 对象转字符串编码传参 url 字符串转对象解码接收参数

    url 对象转字符串编码传参 let info = encodeURI(JSON.stringify(this.data.info));wx.navigateTo({url: '/pages/part ...

  7. Struts2中action接收参数的三种方法及ModelDriven跟Preparable接口结合JAVA反射机制的灵活用法...

    Struts2中action接收参数的三种方法及ModelDriven跟Preparable接口结合JAVA反射机制的灵活用法 www.MyException.Cn   发布于:2012-09-15 ...

  8. java 注解报错_java注解验证接收参数 返回注解字段的错误

    1.在controller接口方法接收参数加上 @Valid注解 并且在实体类参数后紧跟 BindingResult bindingresul BindingResultMsgUtil工具类: pub ...

  9. 详细解析ASP.NET中Request接收参数乱码原理

    起因: 今天早上被同事问了一个问题:说接收到的参数是乱码,让我帮着解决一下.   实际情景:   同事负责的平台是Ext.js框架搭建的,web.config配置文件里配置了全局为"GB23 ...

  10. asp.net跳转并接收参数

    Server.Transfer("../Position/NewStaff.aspx?ReturnPage=1"); 下面这个比较好: response.write alert 好 ...

最新文章

  1. 轻松 [2007年4月22日]
  2. 读书笔记之《习惯的力量》
  3. Linux 技巧:让进程在后台可靠运行的几种方法
  4. Kaggle 入门练习 -- Titanic
  5. NOIP2014联合权值
  6. ExtJs 4.x Ajax简单封装
  7. amd cpu 安卓模拟器_夜神模拟器常见问题解答_v20201025
  8. docker下搭建JupyterNotebook远程登录
  9. OBIEE-----ClusterControler通信的问题
  10. c语言用星号编写矩形,c语言星号打印矩形三角形菱形等图案.doc
  11. 软考 软件设计师个人总结 (程序语言部分)
  12. 程序员高手和程序员菜鸟的区别是什么?
  13. matlab 显示程序进度条,matlab学习---------------进度条waitbar
  14. python多条曲线拟合成一条
  15. 微信小程序onShareTimeline()分享朋友圈功能
  16. 女人,想嫁他,就别跟他同居! (转载自网络)
  17. VS2019报错“常量中有换行符”及中文乱码问题解决
  18. 信息论与编码课件,希望传播给更多的人
  19. (unix网络编程)即时通讯工具二:服务端与客户端融合
  20. Android的语言设置(二)

热门文章

  1. DCDC的PCB布局常见错误及避免方式
  2. Visual Studio 2017 配置AnkhSVN
  3. C# - Poker Sort
  4. ps复制文字到html,【答疑】PS里文字复制粘贴快捷键是什么啊? - 视频教程线上学...
  5. python实现键盘自动输入
  6. 线性表文档之静态链表
  7. linux程序性能分析工具stap,《面向应用开发者的系统指南》CPU篇之使用systemtap分析进程的行为...
  8. 走进波分 -- 15.Optix OSN1800产品介绍
  9. android下注入技术详解
  10. IE插件加载问题调试