Java内部类的一些总结
作为刚入门Java的小白,这两天看到内部类,这里做一个总结,若有错误,欢迎指正~
内部类是指在一个外部类的内部再定义一个类。类名不需要和文件夹相同。
内部类分为: 成员内部类、局部内部类、静态嵌套类、匿名内部类 。
1.成员内部类
成员内部类是最普通的内部类,它的定义为位于另一个类的内部,形如下面的形式:
class Outter {
private int age = 12;
class Inner {
private int age = 13;
public void print() {
int age = 14;
System.out.println("局部变量:" + age);
System.out.println("内部类变量:" + this.age);
System.out.println("外部类变量:" + Outter.this.age);
}
}
}
public class test1 {
public static void main(String[] args) {
Outter out = new Outter();
Outter.Inner in = out.new Inner();
in.print();
}
}
运行结果:
局部变量:14
内部类变量:13
外部类变量:12
从本例可以看出:成员内部类,就是作为外部类的成员,可以直接使用外部类的所有成员和方法,即使是private的。虽然成员内部类可以无条件地访问外部类的成员,而外部类想访问成员内部类的成员却不是这么随心所欲了。在外部类中如果要访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问:
class Outter {
private int age = 12;
public Outter(int age) {
this.age = age;
getInInstance().print(); //必须先创建成员内部类的对象,再进行访问!
}
private Inner getInInstance() {
return new Inner();
}
class Inner {
public void print() {
System.out.println("内部类没同名,所以直接调用外部类成员变量:" + age);
}
}
}
public class test1 {
public static void main(String[] args) {
Outter out = new Outter(10);
}
}
运行结果:
内部类没同名,所以直接调用外部类成员变量:10
内部类可以拥有private访问权限、protected访问权限、public访问权限及包访问权限。
比如上面的例子,如果成员内部类Inner用private修饰,则只能在外部类的内部访问,如果用public修饰,则任何地方都能访问;如果用protected修饰,则只能在同一个包下或者继承外部类的情况下访问;如果是默认访问权限,则只能在同一个包下访问。
这一点和外部类有一点不一样,外部类只能被public和包访问两种权限修饰。
我个人是这么理解的,由于成员内部类看起来像是外部类的一个成员,所以可以像类的成员一样拥有多种权限修饰。要注意的是,成员内部类不能含有static的变量和方法。因为成员内部类需要先创建了外部类,才能创建它自己的。
2.局部内部类
局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。
定义在方法里的内部类:
class Outter {
private int age = 12;
public void Print(final int x) { //这里局部变量x必须设置为final类型!
class Inner {
public void inPrint() {
System.out.println(x);
System.out.println(age);
}
}
new Inner().inPrint();
}
}
public class test1 {
public static void main(String[] args) {
Outter out = new Outter();
out.Print(10);
}
}
运行结果:
10
12
本例中我们将内部类移到了外部类的方法中,然后在外部类的方法中再生成一个内部类对象去调用内部类方法。如果此时我们需要往外部类的方法中传入参数,那么外部类的方法形参必须使用final定义。
换句话说,在方法中定义的内部类只能访问方法中final类型的局部变量,这是因为在方法中定义的局部变量相当于一个常量,它的生命周期超出方法运行的生命周期,由于局部变量被设置为final,所以不能再内部类中改变局部变量的值。(这里看到网上有不同的解释,还没有彻底搞清楚==)
定义在作用域内的内部类:
class Outter {
private int age = 12;
public void Print(final boolean x) { //这里局部变量x必须设置为final类型!
if(x){
class Inner {
public void inPrint() {
System.out.println(age);
}
}
new Inner().inPrint();
}
}
}
public class test1 {
public static void main(String[] args) {
Outter out = new Outter();
out.Print(true);
}
}
运行结果:12
3.静态嵌套类
又叫静态局部类、嵌套内部类,就是修饰为static的内部类。声明为static的内部类,不需要内部类对象和外部类对象之间的联系,就是说我们可以直接引用outer.inner
,即不需要创建外部类,也不需要创建内部类。
class Outter {
private static int age = 12;
static class Inner {
public void print() {
System.out.println(age);
}
}
}
public class test1 {
public static void main(String[] args) {
Outter.Inner in = new Outter.Inner();
in.print();
}
}
运行结果:
12
可以看到,如果用static将内部内静态化,那么内部类就只能访问外部类的静态成员变量,具有局限性。
其次,因为内部类被静态化,因此Outter.Inner
可以当做一个整体看,可以直接 new 出内部类的对象(通过类名访问static,生不生成外部类对象都没关系)
4.匿名内部类
匿名内部类应该是平时我们编写代码时用得最多的,在编写事件监听的代码时使用匿名内部类不但方便,而且使代码更加容易维护。下面这段代码是一段Android事件监听代码:
scan_bt.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
});
history_bt.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
});
这段代码为两个按钮设置监听器,这里面就使用了匿名内部类。具体位置是这段:
new OnClickListener() {
@Override
public 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{
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
}
class Listener2 implements View.OnClickListener{
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
}
这种写法虽然能达到一样的效果,但是既冗长又难以维护,所以一般使用匿名内部类的方法来编写事件监听代码。同样的,匿名内部类也是不能有访问修饰符和static修饰符的。
匿名内部类是唯一一种没有构造器的类。正因为其没有构造器,所以匿名内部类的使用范围非常有限,大部分匿名内部类用于接口回调。匿名内部类在编译的时候由系统自动起名为Outter$1.class
。一般来说,匿名内部类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写。
Java内部类的一些总结的更多相关文章
- Java内部类final语义实现
本文描述在java内部类中,经常会引用外部类的变量信息.但是这些变量信息是如何传递给内部类的,在表面上并没有相应的线索.本文从字节码层描述在内部类中是如何实现这些语义的. 本地临时变量 基本类型 fi ...
- Java内部类详解
Java内部类详解 说起内部类这个词,想必很多人都不陌生,但是又会觉得不熟悉.原因是平时编写代码时可能用到的场景不多,用得最多的是在有事件监听的情况下,并且即使用到也很少去总结内部类的用法.今天我们就 ...
- 黑马----JAVA内部类
黑马程序员:Java培训.Android培训.iOS培训..Net培训 黑马程序员--JAVA内部类 一.内部类分为显式内部类和匿名内部类. 二.显式内部类 1.即显式声明的内部类,它有类名. 2.显 ...
- java 内部类 *** 最爱那水货
注: 转载于http://blog.csdn.net/jiangxinyu/article/details/8177326 Java语言允许在类中再定义类,这种在其它类内部定义的类就叫内部类.内部类又 ...
- java内部类和匿名内部类
内部类即是包含在类里面的又一个类. java内部类分为: 成员内部类.静态嵌套类.方法内部类.匿名内部类 . 内部类的共性 (1).内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.clas ...
- Java内部类小程序(成员内部类,静态内部类,匿名内部类)
/** * 测试java内部类(成员内部类,静态内部类,匿名内部类) * 局部内部类不常用,就不写了. * @package :java05 * @author shaobn * @Describe ...
- [转] Java内部类详解
作者:海子 出处:http://www.cnblogs.com/dolphin0520/ 本博客中未标明转载的文章归作者海子和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置 ...
- java内部类的作用分析
提起Java内部类(Inner Class)可能很多人不太熟悉,实际上类似的概念在C++里也有,那就是嵌套类(Nested Class),关于这两者的区别与联系,在下文中会有对比.内部类从表面上看,就 ...
- 9)Java内部类(Inner Class)
内部类:不可以有静态数据,静态方法或者又一个静态内部类 内部类的优点:隐藏类的细节,内部类可以声明为私有.内部类可以访问外部类的对象(包括private) 静态内部类:可以有静态数据,静 ...
- JAVA内部类(转)
源出处:JAVA内部类 在java语言中,有一种类叫做内部类(inner class),也称为嵌入类(nested class),它是定义在其他类的内部.内部类作为其外部类的一个成员,与其他成员一样, ...
随机推荐
- iOS:iOS开发中用户密码保存位置
原文来自简书:http://www.jianshu.com/p/4af3b8179136/comments/1294203 如果要实现自动登录,不必每次打开应用都去登录,我们势必要把密码保存到本地.一 ...
- ARM开发板系统移植-----kernel的编译
前面一篇文章http://www.cnblogs.com/linzizhang/p/4817336.html介绍了开发板上系统软件的第一部分--bootloader的编译方法. 背景:把bootloa ...
- [Machine Learning] 梯度下降(BGD)、随机梯度下降(SGD)、Mini-batch Gradient Descent、带Mini-batch的SGD
一.回归函数及目标函数 以均方误差作为目标函数(损失函数),目的是使其值最小化,用于优化上式. 二.优化方式(Gradient Descent) 1.最速梯度下降法 也叫批量梯度下降法Batch Gr ...
- partial函数-python学习
一个函数可以有多个参数,而在有的情况下有的参数先得到,有的参数需要在后面的情景中才能知道,python 给我们提供了partial函数用于携带部分参数生成一个新函数. def add(a,b,c=2) ...
- java 转html为pdf
最近有个需求转html为pdf . 用过itext . pd4ml ,都不理想,不是样式有问题,就是页面大小有问题. 或字体有问题. 解决办法是通过wkhtmltopdf工具 , 下载地址为:htt ...
- c# 中List<T> union 深入理解
http://www.cnblogs.com/qinpengming/archive/2012/12/03/2800202.html 借用 这个兄弟的代码 我就不献丑了 .我这里指记录下 public ...
- Apache添加虚拟主机目录
<VirtualHost 127.0.0.2:80> DocumentRoot d:/abcd ServerName 127.0.0.2:80</VirtualHost> &l ...
- jquery添加元素
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <head> ...
- Test for open live write
this is test document. this is test document. this is test document. this is test document. this is ...
- hadoop 异常处理实例(一)hadoop内存配置项
Exception in thread "main" java.io.IOException: Job failed! at org.apache.hadoop.mapred.Jo ...