一般在编写代码时可能会遇到这样的场景——在某些时候,我需要定义并某个类,但是只会使用这一次,或者是某个类对象只会使用一次,为它们专门取名可能会显的很麻烦。为了应对这种情况,Java中允许使用匿名对象和匿名内部类的方式来解决这个矛盾

匿名对象

普通的类对象在使用时会定义一个类类型的变量,用来保存new出来的类所在的地址。而匿名类取消掉了这个变量,这个地址由编译器来处理,并且在new出来之后,它占用的内存会有JVM自动回收掉。后续无法再使用了。

例如

public class Student{
public void classBegin(){
System.out.println("good morning teacher!");
}
} new Student().classBegin();

匿名对象最常用的方式是作为函数的参数,比如上述的打印语句 "good morning teacher!" 它就是一个匿名对象,由于字符串是以对象的形式存储的,所以这里实际上就是一个没有使用对象引用的匿名对象。

当然也可以将匿名对象作为函数的返回值。

内部类

内部类的种类:成员内部类、静态内部类、局部内部类、匿名内部类

成员内部类

java中允许在一个类中定义另一个类。例如

public class Car{
public class Engine{ }
}

上述例子在Car这个类中定义了一个Engine类,那么Car就是外部类,而Engine就是内部类。

使用内部类需要注意:外部类是包含内部类的,所以内部类可以看到外部类的所有属性和方法,包括private方法。但是反过来则不行;

使用内部类主要有两种方式:

  • 在外部类中使用内部类的成员(间接使用)。这种方法一般是在外部类的方法中创建内部类的对象,并调用对象的方法
  • 直接使用:根据上面的定义,可以这样使用 `Car.Engine eng = new Car().new Engine()

比如下面的例子

public class Car{
public class Engine{
public void start(){
System.out.println("引擎启动");
}
} //间接调用
public void start(){
System.out.println("打火");
new Engine().start();
} public static void main(String[] args){
new Car().start(); //直接调用
Car.Engine engine = new Car().new Engine();
engine.start();
}
}

当外部类和内部类的成员发生命名冲突的时候在内部类中可以使用 外部类.this.成员变量 来访问外部类的成员

比如说

public class Car{
public String type = "奥迪";
public class Engine{
public String type = "奥迪引擎";
public void start(){
System.out.println("引擎启动");
} public void carType(){
System.out.println(Car.this.type);
}
} //间接调用
public void start(){
System.out.println("打火");
new Engine().start();
} public static void main(String[] args){
Car car = new Car();
//直接调用
Car.Engine engine = new Car().new Engine();
engine.start();
engine.carType(); }
}

局部内部类

内部类不光可以直接定义在外部类中作为成员内部类,也可以定义在方法中,作为局部内部类

局部内部类也叫区域内嵌类,局部内部类与成员内部类类似,不过,区域内嵌类是定义在一个方法中的内嵌类

主要特定有:

  • 局部内部类只能在对应方法中访问,在方法外无效
  • 不能使用private,protected,public修饰符。
  • 不能包含静态成员
  • 局部内部类如果想要访问方法中的局部变量时,局部变量必须是常量。因为局部变量时分配在栈中,而局部内部类是分配在堆中的,有可能出现这样的情况,外部类的方法执行完了,内存被回收了,但是局部内部类可能还在,所以在访问局部变量时,做了一个拷贝将局部变量拷贝到局部内部类所在的堆中。为了保证数据的完整性,所以这里被拷贝的变量不允许再做修改。
public class carShow(){
public void showCar(){
final float price = 10000000f;
final String type = "奔驰"; class Car(){
public void show(){
System.out.println("这个车是" + type + ",售价:" + price);
}
}
}
}

静态内部类

内部类如果使用static声明,则此内部类就称为静态内部类。它可以通过 外部类 . 内部类 的方式来访问。由于静态内部类是与对象无关的,在使用静态类的成员时是不需要创建对象的。所以如果想要在静态内部类中来访问外部类的成员变量,必须通过外部类的对象实例来访问。

public class Company {
String companyNam;
static String country;
static class Clear{
String name;
public Clear() {
} public Clear(String name) {
super();
this.name = name;
} public void work(String name){
String na = new Company().companyNam="联想";
country="中国";
System.out.println(name+"为"+na+"打扫卫生,该公司属于"+country);
}
}
}

匿名内部类

如果一个内部类在整个操作中只使用一次的话,就可以定义为匿名内部类。匿名内部类也就是没有名字的内部类,这是java为了方便我们编写程序而设计的一个机制,因为有时候有的内部类只需要创建一个它的对象就可以了,以后再不会用到这个类,这时候使用匿名内部类就比较合适。

匿名内部类,一般都伴随着接口一起使用比如

public interface USB{
public abstract void open();
public abstract void close();
} public class Demo{
public static void main(String[] args){
USB usb = new USB(){
public void open(){}
public void close(){}
} usb.open();
usb.close(); //使用匿名内部类的匿名对象的方式
USB usb = new USB(){
public void open(){}
public void close(){}
}.open();
}
}

在Demo这个类的main方法中创建了一个局部的内部类,这个内部类没有名字,也就是创建了一个匿名内部类。


Java 学习笔记(8)——匿名对象与内部类的更多相关文章

  1. MongoDB学习笔记~以匿名对象做为查询参数,方便查询子对象

    回到目录 对于MongoDB的封装还在继续,对于不断追求简单的编程还在继续,对于喜欢代码的那么感觉,还在继续... 当你的mongo数据表里有子对象时,尤其是列表对象时,使用官方的驱动很是不爽,要记得 ...

  2. Java学习笔记23---内部类之局部内部类只能访问final的局部变量

    局部内部类是定义在方法体或代码块中的类,在笔记19中已有过简单介绍. 今天要讨论的是局部内部类为什么只能访问为常量的局部变量. 作者: 博客园--蝉蝉 请尊重作者劳动成果,转载请在标题注明“转载”字样 ...

  3. Java学习笔记(七):内部类、静态类和泛型

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

  4. Java学习笔记--类和对象

    1.介绍面向对象的编程          面向对象是现在主流的编程样例,它替代了以前C语言使用时的“结构体”,Java是一门面向对象的语言,所以需要熟悉面向对象的概念.面向对象的程序由很多对象组成,每 ...

  5. 【Java学习笔记】其他对象API

    System类 package p1; import java.util.Properties; import java.util.Set; public class SystemDemo { pri ...

  6. Java学习笔记之类和对象

    1.类是对象的抽象,对象是类的实例. 2.一个.java 文件,只能有一个公有类. 3.Java的默认访问权限是:default,即不加任何访问修饰符,该权限设置只能在同一包访问.   当前类 同一包 ...

  7. java学习笔记09-类与对象

    物以类聚,人以群分,我们把具有相似特性或品质的物体归为一类. 类:类是一种模板,它描述一类对象的行为和状态. 对象:对象是类的一个实例,有状态和行为. 比如在一支nba球队中,每个球员都有球衣号码,场 ...

  8. java学习笔记3--类与对象的基础

    本文地址:http://www.cnblogs.com/archimedes/p/java-study-note3.html,转载请注明源地址. 1.面向对象的程序设计方法概述 面向对象的程序设计 与 ...

  9. Effective Java 学习笔记之所有对象都通用的方法

    一.覆盖equals时请遵守通用约定 1.满足下列任何一个条件时,不需要覆盖equals方法 a.类的每个实例本质上都是唯一的.此时就是Object中equals方法所表达的含义. b.不关心类是否提 ...

随机推荐

  1. Codeforces 414B

    题目链接 附上代码: #include<cstdio> #include<cstring> #include<bits/stdc++.h> #define mod ...

  2. 【时光回溯】【JZOJ3568】【GDKOI2014】小纪的作业题

    题目描述 输入 输出 有M行,每个询问一行,输出结果mod 1,000,000,007的值. 样例输入 10 3 3 5 1 2 3 1 3 5 2 1 7 9 3 9 2 3 样例输出 10 19 ...

  3. WPF Binding ElementName方式无效的解决方法--x:Reference绑定

    原文:WPF Binding ElementName方式无效的解决方法--x:Reference绑定 需求: 背景:Grid的有一个TextBlock name:T1和一个ListBox,ListBo ...

  4. @hdu - 6329@ Problem K. Transport Construction

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定 n 个点,第 i 个点位于 (xi, yi). 在第 i ...

  5. @loj - 2092@ 「ZJOI2016」大森林

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 小 Y 家里有一个大森林,里面有 n 棵树,编号从 1 到 n. ...

  6. @codeforces - 1209H@ Moving Walkways

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 机场中常常见到滑行道:假如一个滑行道的运行速度为 s,你的行走速 ...

  7. LeetCode75 Sort Colors

    题目: Given an array with n objects colored red, white or blue, sort them so that objects of the same ...

  8. 《C语言深度解剖》学习笔记之关键字

    第一章 关键字 C语言共有32个关键字. 关键字   auto 声明自动变量 int 声明整型变量 long 声明长整型变量 char 声明字符型变量 float 声明浮点型变量 short 声明短整 ...

  9. oracle函数 current_timestamp

    [功能]:以timestamp with time zone数据类型返回当前会话时区中的当前日期 [参数]:没有参数,没有括号 [返回]:日期 [示例]select current_timestamp ...

  10. HTML 标签:常规元素和空元素

    HTML标签分为空元素和常规元素 其中空元素是自关闭的,不需要成对地添加关闭标签. 空元素包括:img,input,textarea,select,br,hr,command,link,keygen, ...