java中的内部类内部接口详解
简介
一般来说,我们创建类和接口的时候都是一个类一个文件,一个接口一个文件,但有时候为了方便或者某些特殊的原因,java并不介意在一个文件中写多个类和多个接口,这就有了我们今天要讲的内部类和内部接口。
内部类
先讲内部类,内部类就是在类中定义的类。类中的类可以看做是类的一个属性,一个属性可以是static也可以是非static的。而内部类也可以定义在类的方法中,再加上匿名类,总共有5种内部类。
静态内部类
我们在class内部定义一个static的class,如下所示:
@Slf4j
public class StaticInnerClass {
static class Inner {
void print() {
log.info("Inner class is: " + this);
}
}
public static void main(String[] args) {
StaticInnerClass.Inner inner = new StaticInnerClass.Inner();
inner.print();
}
}
因为static变量可以直接根据类名来存取,所以我们使用new StaticInnerClass.Inner()来实例化内部类。
非静态内部类
class中定义的类也可以是非静态的,如下所示:
@Slf4j
public class InnerClass {
class Inner {
void print() {
log.info("Inner class is: " + this);
}
}
public static void main(String[] args) {
InnerClass.Inner inner = new InnerClass().new Inner();
inner.print();
}
}
要访问到类的变量,需要实例化外部内,然后再实例化内部类:new InnerClass().new Inner()。
注意这里我们需要使用到两个new。
静态方法内部类
我们可以在静态方法中定义一个类,这个类其实就相当于方法中的变量,这个变量当然不能是static的。我们看下面的例子:
@Slf4j
public class StaticMethodInnerClass {
private static String x = "static x";
public static void print() {
class MyInner {
public void printOuter() {
log.info("x is " + x);
}
}
MyInner i = new MyInner();
i.printOuter();
}
public static void main(String[] args) {
StaticMethodInnerClass.print();
}
}
方法中的类,我们是无法在外部实例化的。
非静态方法的内部类
同样的非静态方法也可以定义内部类:
@Slf4j
public class MethodInnerClass {
private String x = "non static x";
public void print() {
class MyInner {
public void printOuter() {
log.info("x is " + x);
}
}
MyInner i = new MyInner();
i.printOuter();
}
public static void main(String[] args) {
new MethodInnerClass().print();
}
}
注意,这里需要先实例化外部类才可以继续调用。
匿名类
最后一个,匿名类,直接在需要的时候实例化的类。匿名类我们遇到了很多次了,比如在构建SortedSet的时候,可以传入自定义的Comparator,我们可以用匿名类来实现,也可以直接使用lambda表达式。
public class AnonymousClass {
public static void main(String[] args) {
SortedSet sortedSet1 = new ConcurrentSkipListSet(new Comparator(){
@Override
public int compare(Object o1, Object o2) {
return 0;
}
});
SortedSet sortedSet2 = new ConcurrentSkipListSet((o1, o2) -> 0);
}
}
内部接口
Inner Interface是指在接口中定义的接口。最常见的就是Map中的Entry了:
public interface Map<K, V> {
interface Entry<K, V> {
K getKey();
}
这里的内部接口一定是static的,因为接口是不能实例化的,所以为了访问到接口中的接口,必须定义为static。如果不指定,则默认就是static。
我们看一个该内部接口的实现:
public class MapImpl implements Map.Entry{
@Override
public Object getKey() {
return 0;
}
@Override
public Object getValue() {
return null;
}
@Override
public Object setValue(Object value) {
return null;
}
}
总结
本文讲解了5个内部类的实现和一个内部接口的应用。大家只要把内部的类或者接口看成一个变量,就可以很好的理解上面的内容了。
本文的例子https://github.com/ddean2009/learn-java-base-9-to-20
本文作者:flydean程序那些事
本文链接:http://www.flydean.com/inner-class-inner-interface/
本文来源:flydean的博客
欢迎关注我的公众号:程序那些事,更多精彩等着您!
java中的内部类内部接口详解的更多相关文章
- Java中「Future」接口详解
目录 一.背景 二.Future接口 1.入门案例 2.Future接口 三.CompletableFuture类 1.基础说明 2.核心方法 2.1 实例方法 2.2 计算方法 2.3 结果获取方法 ...
- “全栈2019”Java第八十三章:内部类与接口详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- Java 中的异常和处理详解
Java 中的异常和处理详解 原文出处: 代码钢琴家 简介 程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常.异常发生时,是任程序自生自灭,立刻退出终止,还是输出错误 ...
- Java中的Iterable与Iterator详解
在Java中,我们可以对List集合进行如下几种方式的遍历: List<Integer> list = new ArrayList<>(); list.add(5); list ...
- Java中23种经典设计模式详解
Java中23种设计模式目录1. 设计模式 31.1 创建型模式 41.1.1 工厂方法 41.1.2 抽象工厂 61.1.3 建造者模式 101.1.4 单态模式 131.1.5 原型模式 151. ...
- Java中的多线程技术全面详解
本文主要从整体上介绍Java中的多线程技术,对于一些重要的基础概念会进行相对详细的介绍,若有叙述不清晰或是不正确的地方,希望大家指出,谢谢大家:) 为什么使用多线程 并发与并行 我们知道,在单核机器上 ...
- JAVA中常见的阻塞队列详解
在之前的线程池的介绍中我们看到了很多阻塞队列,这篇文章我们主要来说说阻塞队列的事. 阻塞队列也就是 BlockingQueue ,这个类是一个接 口,同时继承了 Queue 接口,这两个接口都是在JD ...
- java中ReentrantLock核心源码详解
ReentrantLock简介 ReentrantLock是一个可重入且独占式的锁,它具有与使用synchronized监视器锁相同的基本行为和语义,但与synchronized关键字相比,它更灵活. ...
- java中Map及Map.Entry详解
Map是java中的接口,Map.Entry是Map的一个内部接口. Map提供了一些常用方法,如keySet().entrySet()等方法. keySet()方法返回值是Map中key值的集合:e ...
- 关于Java中进程和线程的详解
一.进程:是程序的一次动态执行,它对应着从代码加载,执行至执行完毕的一个完整的过程,是一个动态的实体,它有自己的生命 周期.它因创建而产生,因调度而运行,因等待资源或事件而被处于等待状态,因完成任务而 ...
随机推荐
- python各版本新特性
# py3.7 https://docs.python.org/zh-cn/3/whatsnew/3.7.html # py3.8 https://docs.python.org/zh-cn/3/wh ...
- 网络安全-Linux常用命令
安装上传下载的软件包 yum install lrzsz -y 下载:linux-->windows sz -y /etc/hosts 上传:windows-->linux rz -y 系 ...
- 【LeetCode二叉树#05】平衡二叉树
力扣题目链接(opens new window)](https://leetcode.cn/problems/balanced-binary-tree/) 给定一个二叉树,判断它是否是高度平衡的二叉树 ...
- CoaXPress 协议的CRC及其具体实现
CoaXPress CRC 在CXP协议中,CRC用在stream packet和control packet中,用于指示数据是否错误,如果是control packet, device发现CRC错误 ...
- 第126篇: 异步函数(async和await)
好家伙,本篇为<JS高级程序设计>第十章"期约与异步函数"学习笔记 ES8 的 async/await 旨在解决利用异步结构组织代码的问题. 为为此增加了两个新关键 ...
- 当 GraphQL 遇上图数据库,便有了更方便查询数据的方式
人之初,性本鸽. 大家好,我叫储惠龙(实名上网),你可以叫我小龙人,00 后一枚.目前从事后端开发工作. 今天给大家带来一个简单的为 NebulaGraph 提供 GraphQL 查询支持的 DEMO ...
- MES集成警报灯系统,Http远程控制系统设计
核心功能设计 警报灯实机演示:https://www.bilibili.com/video/BV1294y1M7f3?p=2 接受服务器发送http·post请求远程控制警报灯,可接入MES等系统. ...
- cache 本地&分布式(-redis) & JSON对象转换
本地缓存 最简单的cache, 做一个map就行 private final Map<String,List<User>> cache=new HashMap<>( ...
- 用户不在 sudoers 文件中。此事将被报告
在终端,进入root模式 vim /etc/sudoers 在 sudo (ALL:ALL) ALL下 添加 用户名 (ALL:ALL) ALL
- jquery之ajax中文乱码解决方案
$.ajax({ dataType : 'json',type : 'POST',url : 'http://localhost/test/test.do',data : {id: 1, type: ...