java内部类原理与用法详解
作者:XINGKONG_04 发布时间:2022-12-04 14:41:25
本文实例讲述了java内部类原理与用法。分享给大家供大家参考,具体如下:
概念
内部类:可以包含在另外一个类中的类
外部类:包含内部类的类
每个内部类都会被编译为一个独立的类,生成一个独立的字节码文件。
内部类可以方便地访问外部类的私有变量,内部类也可以声明为private从而实现对外完全隐藏。
分类
java中的四种内部类(根据定义的位置和方式划分)
-静态内部类
-成员内部类
-方法内部类
-匿名内部类
分类介绍
-静态内部类
特征:在类的内部中存在另一个类,且该类被static修饰
使用范围:在外部类内,可以直接使用内部类,在外部类范围以外使用外部类名.静态内部类名
的方式使用内部类
public class StaticOuter {
private static int shared = 100;
public static class StaticInner{
public void staticInnerMethod() {
System.out.println("Static Inner Method" + shared);
}
}
StaticInner si1 = new StaticInner();
public void test() {
StaticInner si = new StaticInner();
si.staticInnerMethod();
}
public static void main(String[] args) {
StaticOuter so = new StaticOuter();
so.test();
//在外部类范围内
StaticInner si1 = new StaticInner();
si1.staticInnerMethod();
//合法
StaticOuter.StaticInner si2 = new StaticOuter.StaticInner();
si2.staticInnerMethod();
}
}
//在外部类范围外
class Test{
StaticOuter.StaticInner si2 = new StaticOuter.StaticInner();
}
访问范围
静态内部类只能访问外部类中的static变量和方法。
静态内部类也可以访问外部类中的private变量。
静态内部类中可以定义静态变量和静态方法。
-成员内部类
语法:成员内部类作为外部类的一个成员存在
使用方法:
如何新建一个内部类的实例:不能直接使用外部类.内部类的方式,每个成员内部类对象对应一个外部类实例,因此需要先创建一个外部类实例,然后才能生成内部类的实例(如下面代码)
访问范围:
成员内部类可以访问外部类中的静态变量和方法,也可以访问实例变量和方法。但是书写格式有两种:
(1)直接访问;
(2)外部类.this.xxx
,主要针对外部类和内部类的出现变量重名或者方法重名的情况。
成员内部类也可以访问外部类的私有变量
成员内部类中不可以定义静态变量和静态方法(final变量例外,它等同于常量),在后面的方法内部类和匿名内部类中也是不能存在静态的变量和方法的,这是因为静态变量和静态方法作为类型的属性和方法,一般是独立使用的,而成员内部类和一个对一个的外部类实例关联,一般不会独立使用,所以这样的使用意义不大。(这算是一种规定吧)。
public class OriginalClass {
private static int t1 = 100;
private int t2 = 200;
class OriginalInner{
public void test() {
/*
* 不合法的表示,在成员内部类中不可以定义静态的变量和方法
public static int inner = 100;
public static void print() {
}
*/
//合法的final变量
public static final int inner1 = 300;
System.out.println("OriginalInner:"+ t1);//直接访问外部类静态变量
System.out.println("OriginalInner:"+ t2);//直接访问外部类成员变量
action();//直接访问外部类方法
System.out.println("OriginalInner:"+ OriginalClass.this.t1);//
System.out.println("OriginalInner:"+ OriginalClass.this.t2);
OriginalClass.this.action();
}
}
public void action() {
System.out.println("originalinner action");
}
public static void main(String[] args) {
//new一个内部类
OriginalClass oc = new OriginalClass();
OriginalInner oi = oc.new OriginalInner();
oi.test();
}
}
-方法内部类
语法:存在于方法体内部的类
使用范围:方法内部类只能在定义的方法内被使用
访问范围:
如果包含内部类的方法是实例方法,那么可以访问外部类的静态变量和方法,也可以访问实例变量和方法;
如果包含内部类的方法是静态方法,那么只能访问外部类的静态变量和方法。
方法内部类还可以直接访问方法的参数和方法中的局部变量,但是这些变量必须声明为final。为什么需要声明为final呢?这是因为方法内部类操作的并不是外部的变量,而是它自己的实例变量,只是这些变量的值和外部一样,对这些变量赋值,并不会改变外部的值,为避免混淆,所以干脆强制规定必须声明为final。
我们知道被final修饰的基本类型变量的值是不能被修改的,被final修饰的数组或者引用类型变量的引用是不能修改的,即只能指向一个对象或者是数组,但是我们可以修改对象中的成员变量值或者是数组中元素的值。
其实使用final来修饰参数以及局部变量的目的还是保证方法内部类外面的元素不会在方法内部类中被修改,相当于限制一个作用域的功能,保证方法内部类内部的的修改不会影响方法内部类外面的同名变量值。
public class FunctionOuter {
private static int s= 100;
private int s1 = 20;
public void print(final int param) {
final int in = 300;
class FunctionInner{
public void innertest() {
System.out.println("FunctionInner:s="+s);
System.out.println("FunctionInner:s1="+s1);
System.out.println("FunctionInner:in"+ in);
test();
}
}
FunctionInner fi = new FunctionInner();
fi.innertest();
System.out.println("print:in"+in);
}
public void test() {
System.out.println("FunctionOuter:"+s);
}
public static void main(String[] args) {
FunctionOuter fo = new FunctionOuter();
fo.print(900);
}
}
-匿名内部类
语法:匿名内部类没有单独的类定义,它在创建对象的同时定义类
new 父类(参数列表){
//匿名内部类实现部分
}
new 父接口(){
//匿名内部类实现部分
}
匿名内部类只能使用一次,用来创建一个对象。没有名字,没有构造方法,但是可以根据参数列表,调用对应的父类构造方法。
在匿名内部类中可以定义实例变量和方法,以及初始化代码块,初始化代码块可以起到构造方法的作用,只是构造方法可以有多个,但是初始化代码块只能有一块,因为没有构造方法,它自己无法接受参数,如果必须要参数,则应该是用其他内部类。
匿名内部类可以访问外部类的所有变量和方法,可以访问方法中的final参数和局部变量
更多java相关内容感兴趣的读者可查看本站专题:《Java面向对象程序设计入门与进阶教程》、《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》、《Java文件与目录操作技巧汇总》和《Java缓存操作技巧汇总》
希望本文所述对大家java程序设计有所帮助。
来源:https://blog.csdn.net/XINGKONG_04/article/details/81181192


猜你喜欢
- 概述memcache是一套开放源的分布式高速缓存系统。由服务端和客户端组成,以守护程序(监听)方式运行于一个或多个服务器中,随时会接收客户端
- C#编写winform程序时,用到的,格式强转,存储到数据库,数据库连接那块就不写了希望对大家有帮助,欢迎评论互相分享技术!//日期格式强制
- 什么是JWTJSON Web Token(JWT)是一个开放的标准(RFC 7519),它定义了一个紧凑且自包含的方式,用于在各方之间以JS
- 1.实现如图所示的单选效果由于Android提供的单选按钮radiobutton只能单行或单列显示,且样式并不美观,故可用GridView进
- 基础编程模型和数据抽象把描述和实现算法所用到的语言特性,软件库和操作系统特性总称为基础编程模型。编写递归代码注意的点:1. 递归总有一个最简
- 本文实例讲述了java实现单词搜索迷宫游戏。分享给大家供大家参考。具体分析如下:我们在杂志上,经常能够看到找单词的小游戏,在一个二维表格中,
- 一、默认静态资源路径类路径下:staticpublicresources这几个目录为默认静态资源访问的目录二、增加静态资源路径前缀动态资源和
- 一.IDEA开发环境1.pom文件设置<properties> <maven.compiler.
- 我们平时在日常项目中经常会遇到图片的上传和访问的情景,平时我们可能习惯于把图片传到resource或者项项目中的某个位置,这样会有一个缺点,
- 由于所爬取的网站需要验证码,通过网页的开发人员工具【F12】及在线http post,get接口测试请求工具(http://coolaf.c
- 为什么要自定义缓存注解?Spring Cache本身提供@Cacheable、@CacheEvict、@CachePut等缓存注解,为什么还
- 前言以下内容科班同学学过UML和数据库的应该比较熟悉数据模型:数据模型是对数据库特征的抽象,也就是用户从数据库中看到的模型,例如一张数据表或
- 一直想在持续集成方向学习并研究一番,近期正准备结合jmeter+ant+jenkins做自动化接口测试,在学习的同时,正好实践一番,毕竟实践
- 一、 添加 maven 依赖<dependency> <groupId>com.google.guava
- PostMapping接收json参数后返回404问题描述js中传递json数据给后端,后端可以正常接收参数,但返回404。js
- 随着对多线程学习的深入,你可能觉得需要了解一些有关线程共享资源的问题. .NET framework提供了很多的类和数据
- 🌱1. 什么是反射机制?首先大家应该先了解两个概念,编译期和运行期,编译期就是编译器帮你把源代码翻译成机器能识别的代码,比如编译器把java
- 概述从今天开始, 小白我将带大家开启 Jave 数据结构 & 算法的新篇章.栈栈 (Stack) 是一种运算受限的线性表, 遵循先进
- 前言Spring Seuciry相关的内容看了实在是太多了,但总觉得还是理解地不够巩固,还是需要靠知识输出做巩固。相关版本:java: jd
- 本文实例讲述了Java使用备忘录模式实现过关类游戏功能。分享给大家供大家参考,具体如下:一.模式定义备忘录模式,在不破坏封闭的前提下,捕获一