一、基本介绍

  内部类是指在一个外部类的内部再定义一个类。类名不需要和文件夹相同。

  内部类可以是静态static的,也可用public,default,protected和private修饰;而外部顶级类即类名和文件名相同的只能使用public和default。

  注意:内部类是一个编译时的概念,一旦编译成功,就会成为完全不同的两类。对于一个名为Outer的外部类和其内部定义的名为Inner的内部类。编译完成后出现Outer.class和Outer$Inner.class两类。

二、分类

1、静态内部类

  类定义时加上static关键字。

  只可以访问外部类的静态成员和静态方法,包括了私有的静态成员和方法。

  被编译成一个完全独立的.class文件,名称为OuterClass$InnerClass.class的形式。

  生成静态内部类对象的方式为:

  OuterClass.InnerClass inner = new OuterClass.InnerClass();

public class Outer {
public static String sayStr=" say hello";
public static void main(String[] args){
Outer.StaticInner inner=new StaticInner();
inner.say();
}
public static class StaticInner{
public void say(){
//静态内部类只能访问外部内的静态成员和静态方法
System.out.println(sayStr);
}
}
}

2、成员内部类

  成员内部类也是定义在另一个类中,但是定义时不用static修饰。

  成员内部类和静态内部类可以类比为非静态的成员变量和静态的成员变量。

  被编译成一个完全独立的.class文件,名称为OuterClass$InnerClass.class的形式。

  它可以访问它的外部类的所有成员变量和方法,不管是静态的还是非静态的都可以。

  在外部类里面创建成员内部类的实例:

  this.new Innerclass();

  在外部类之外创建内部类的实例:

  (new Outerclass()).new Innerclass();

  在内部类里访问外部类的成员:

  Outerclass.this.member

public class Test {

    public static void main(String[] args) {
// 创建内部类对象时需要先创建外部对象
Outer.Inner inner=new Outer().new Inner();
inner.say();
} } class Outer{ private String sayStr="hello";
public class Inner{
public void say(){
System.out.println(Outer.this.sayStr);
}
}
}

3、局部内部类

  局部内部类定义在方法中,比方法的范围还小。是内部类中最少用到的一种类型。

  像局部变量一样,不能被public, protected, private和static修饰。

  只能访问方法中定义的final类型的局部变量。

  局部内部类在方法中定义,所以只能在方法中使用,即只能在方法当中生成局部内部类的实例并且调用其方法。

  被编译成一个完全独立的.class文件,名称为OuterClass$数字InnerClass.class的形式。 如果不同方法中局部内部内类名相同,被编译成class文件时用数字区分

public class LocalInnerTest {
public static void main(String[] args){
Outer outer=new Outer();
outer.doSomething();
}
} class Outer{
int a=1;
public void doSomething(){
int b=2;
final int c=3; class Inner{
int d=4;
public void work(){ //可以访问外部内的成员变量
System.out.println(a);
//不可以访问非final的局部变量
//System.out.println(b);
//可以访问final的局部变量
System.out.println(c);
//可以访问内部类自身所有变量
System.out.println(d);
}
}
//创建局部内部类的实例并调用方法
new Inner().work();
}
}

4、匿名内部类

  匿名内部类就是没有名字的局部内部类,不使用关键字class, extends, implements, 没有构造方法。

  匿名内部类隐式地继承了一个父类或者实现了一个接口

  匿名内部类使用得比较多,通常是作为一个方法参数。

  生成的.class文件中,匿名类会生成OuterClass$数字.class文件,数字根据是第几个匿名类而类推。

  匿名内部类不能定义任何静态成员、方法和类。

  匿名内部类不能是public,protected,private,static。

案例一:

import java.util.Date;
public class AnonymouseInnerClass { public String getStr(Date date){
return date.toLocaleString();
}
public static void main(String[] args){ AnonymouseInnerClass anon=new AnonymouseInnerClass();
String str=anon.getStr(new Date());
System.out.println(str);
//使用匿名内部类
str=anon.getStr(new Date(){
//使用了花括号,但是不填入内容,执行结果和上面的完全一致
//生成了一个继承了Date类的子类的对象
});
System.out.println(str); //使用匿名内部类,并且重写父类中的方法
str=anon.getStr(new Date(){
//重写父类中的方法
@Override
public String toLocaleString(){
return "hello "+super.toLocaleString();
}
});
System.out.println(str);
}
}

  案例二:

public class Anonymouse {
public static void main(String[] args){
Outer outer=new Outer(){
//重写show方法
@Override
public void show(){
System.out.println("Anonymouse:show");
}
};
outer.show();
}
}
class Outer{
public void show(){
System.out.println("Outer:show");
}
}

  案例三:

public class Anonymouse {
public static void main(String[] args){
Anonymouse anon=new Anonymouse();
anon.print(new Bird(){
@Override
public int fly() {
return 1000;
} public String getName(){
return "大雁";
}
});
}
public void print(Bird bird){
System.out.println(bird.getName()+"能飞"+bird.fly()+"米");
}
} abstract class Bird{
private String name; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public abstract int fly();
}

  案例四:

public class Anonymouse {
public static void main(String[] args){
//通过匿名内部类,实现eat方法
Bird bird=new Bird() {
@Override
public void eat() {
System.out.print("Anonymouse:eat");
}
};
//调用eat方法
bird.eat();
} }
abstract class Bird{
public abstract void eat();
}

案例五:

public class Anonymouse {
public static void main(String[] args){
//通过匿名内部类,实现eat方法
IBird bird=new IBird() {
@Override
public void eat() {
System.out.print("Anonymouse:eat");
}
};
//调用eat方法
bird.eat();
} }
interface IBird{
public void eat();
}

8、java内部类的更多相关文章

  1. Java内部类final语义实现

    本文描述在java内部类中,经常会引用外部类的变量信息.但是这些变量信息是如何传递给内部类的,在表面上并没有相应的线索.本文从字节码层描述在内部类中是如何实现这些语义的. 本地临时变量 基本类型 fi ...

  2. Java内部类详解

    Java内部类详解 说起内部类这个词,想必很多人都不陌生,但是又会觉得不熟悉.原因是平时编写代码时可能用到的场景不多,用得最多的是在有事件监听的情况下,并且即使用到也很少去总结内部类的用法.今天我们就 ...

  3. 黑马----JAVA内部类

    黑马程序员:Java培训.Android培训.iOS培训..Net培训 黑马程序员--JAVA内部类 一.内部类分为显式内部类和匿名内部类. 二.显式内部类 1.即显式声明的内部类,它有类名. 2.显 ...

  4. java 内部类 *** 最爱那水货

    注: 转载于http://blog.csdn.net/jiangxinyu/article/details/8177326 Java语言允许在类中再定义类,这种在其它类内部定义的类就叫内部类.内部类又 ...

  5. java内部类和匿名内部类

    内部类即是包含在类里面的又一个类. java内部类分为: 成员内部类.静态嵌套类.方法内部类.匿名内部类 . 内部类的共性 (1).内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.clas ...

  6. Java内部类小程序(成员内部类,静态内部类,匿名内部类)

    /** * 测试java内部类(成员内部类,静态内部类,匿名内部类) * 局部内部类不常用,就不写了. * @package :java05 * @author shaobn * @Describe ...

  7. [转] Java内部类详解

    作者:海子 出处:http://www.cnblogs.com/dolphin0520/ 本博客中未标明转载的文章归作者海子和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置 ...

  8. java内部类的作用分析

    提起Java内部类(Inner Class)可能很多人不太熟悉,实际上类似的概念在C++里也有,那就是嵌套类(Nested Class),关于这两者的区别与联系,在下文中会有对比.内部类从表面上看,就 ...

  9. 9)Java内部类(Inner Class)

      内部类:不可以有静态数据,静态方法或者又一个静态内部类      内部类的优点:隐藏类的细节,内部类可以声明为私有.内部类可以访问外部类的对象(包括private) 静态内部类:可以有静态数据,静 ...

  10. JAVA内部类(转)

    源出处:JAVA内部类 在java语言中,有一种类叫做内部类(inner class),也称为嵌入类(nested class),它是定义在其他类的内部.内部类作为其外部类的一个成员,与其他成员一样, ...

随机推荐

  1. linux升级mysql到5.7

    原文:http://blog.csdn.net/qing_gee/article/details/41774265 Linux升级MySQL版本到5.7. 1.下载Linux的5.7版本,主要需要两个 ...

  2. Selenium2+python自动化59-数据驱动(ddt)

    前言 在设计用例的时候,有些用例只是参数数据的输入不一样,比如登录这个功能,操作过程但是一样的.如果用例重复去写操作过程会增加代码量,对应这种多组数据的测试用例,可以用数据驱动设计模式,一组数据对应一 ...

  3. Java 8 中 HashMap 的性能提升

    HashMap是一个高效通用的数据结构,它在每一个Java程序中都随处可见.先来介绍些基础知识.你可能也知 道,HashMap使用key的hashCode()和equals()方法来将值划分到不同的桶 ...

  4. MapReduce编程基础

    MapReduce编程基础 1. WordCount示例及MapReduce程序框架 2.  MapReduce程序执行流程 3.  深入学习MapReduce编程(1) 4. 参考资料及代码下载 & ...

  5. 【转载】关于大数据库的一些不错的GitHub项目

    优秀大数据GitHub项目一览 http://blog.csdn.net/YaoXTao/article/details/50540485

  6. Informatica 常用组件Lookup缓存之二 使用永久查找高速缓存

    可以将"查找"转换配置为使用非永久或永久高速缓存.基于"查找高速缓存永久"属性的会话成功后,PowerCenter 将保存或删除查找高速缓存文件. 如果查找表在 ...

  7. Informatica 常用组件Filter之四 优化

    以下提示可提高过滤器性能: 在映射中先使用过滤器转换. 要使会话性能最忧化,应使过滤器转换尽可能靠近映射中的源.并不是将您准备放弃的行传递至映射,而是在随后从源至目标的数据流中过滤出不需要的数据. 使 ...

  8. Python并发编程-redis-3.0.5 源码安装

    1.简介 Remote Dictionary Server(Redis)是一个基于 key-value 键值对的持久化数据库存储系统.redis 和 Memcached 缓存服务很像,但它支持存储的 ...

  9. 跨平台app开发(引擎)工具的选择【转】

    跨平台app开发(引擎)工具的选择 1.html5执行速度慢,用户体验不好 2.原生应用开发,即ios和安卓分别开发,需要两种技术人员,后期代码维护困难,很难达到统一. 3.xamarin是一款c#的 ...

  10. spring cloud-给Eureka Server加上安全的用户认证

    前言 在前面的一篇文章中 spring cloud中启动Eureka Server 我们启动了Eureka Server,然后在浏览器中输入http://localhost:8761/后,直接回车,就 ...