一般在编写代码时可能会遇到这样的场景——在某些时候,我需要定义并某个类,但是只会使用这一次,或者是某个类对象只会使用一次,为它们专门取名可能会显的很麻烦。为了应对这种情况,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)——匿名对象与内部类的更多相关文章
-
MongoDB学习笔记~以匿名对象做为查询参数,方便查询子对象
回到目录 对于MongoDB的封装还在继续,对于不断追求简单的编程还在继续,对于喜欢代码的那么感觉,还在继续... 当你的mongo数据表里有子对象时,尤其是列表对象时,使用官方的驱动很是不爽,要记得 ...
-
Java学习笔记23---内部类之局部内部类只能访问final的局部变量
局部内部类是定义在方法体或代码块中的类,在笔记19中已有过简单介绍. 今天要讨论的是局部内部类为什么只能访问为常量的局部变量. 作者: 博客园--蝉蝉 请尊重作者劳动成果,转载请在标题注明“转载”字样 ...
-
Java学习笔记(七):内部类、静态类和泛型
内部类 在Java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类.广泛意义上的内部类一般来说包括这四种:成员内部类.局部内部类.匿名内部类和静态内部类.下面就先来了解一下这四种 ...
-
Java学习笔记--类和对象
1.介绍面向对象的编程 面向对象是现在主流的编程样例,它替代了以前C语言使用时的“结构体”,Java是一门面向对象的语言,所以需要熟悉面向对象的概念.面向对象的程序由很多对象组成,每 ...
-
【Java学习笔记】其他对象API
System类 package p1; import java.util.Properties; import java.util.Set; public class SystemDemo { pri ...
-
Java学习笔记之类和对象
1.类是对象的抽象,对象是类的实例. 2.一个.java 文件,只能有一个公有类. 3.Java的默认访问权限是:default,即不加任何访问修饰符,该权限设置只能在同一包访问. 当前类 同一包 ...
-
java学习笔记09-类与对象
物以类聚,人以群分,我们把具有相似特性或品质的物体归为一类. 类:类是一种模板,它描述一类对象的行为和状态. 对象:对象是类的一个实例,有状态和行为. 比如在一支nba球队中,每个球员都有球衣号码,场 ...
-
java学习笔记3--类与对象的基础
本文地址:http://www.cnblogs.com/archimedes/p/java-study-note3.html,转载请注明源地址. 1.面向对象的程序设计方法概述 面向对象的程序设计 与 ...
-
Effective Java 学习笔记之所有对象都通用的方法
一.覆盖equals时请遵守通用约定 1.满足下列任何一个条件时,不需要覆盖equals方法 a.类的每个实例本质上都是唯一的.此时就是Object中equals方法所表达的含义. b.不关心类是否提 ...
随机推荐
-
[原创]java WEB学习笔记109:Spring学习---spring中事物管理
博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好 ...
-
WCF 自托管、无配置文件实现jsonp(跨域)的访问
以下内容基于WCF4.0,本文将对比讨论配置文件方案和无配置文件方案的实现方式. WCF4.0加入了对RESTFU和标准终结点的支持,这为实现跨域提供了简单的方式. 一.有配置文件的情况: 首先我们先 ...
-
UINavigationController 导航控制器 ,根据文档写的一些东西
今天讲了导航控制器UINavigationController 和标签栏视图控制器UITabBarController 先来说一说导航视图控制器 UINavigationController 导航控 ...
-
Filebeat中文指南
Filebeat中文指南 翻译自:https://www.elastic.co/guide/en/beats/filebeat/current/index.html 译者:kerwin 鸣谢:tory ...
-
编译安装zabbix
1. 说明:本例用源码包来安装zabbix,但是zabbix的后台数据库在这里选择mysql,然而mysql的安装方式不在选择源码了,而是选择已经编译好的通用linux包(tar包) zabbix源码 ...
-
轻量级别的Cache和反向代理软件---Varnish
1.Varnish描述 1.1 Varnish的结构与特点 Varnish是一个轻量级别的Cache和反向代理软件,先进的设计理念和成熟的设计框架是Varnish的主要特点: 基于内存进行缓存,重启后 ...
-
关于String的对象创建
1)String String是Java中的字符串类,属于引用数据类型.所以String的对象存放的是引用的地址.在底层是一个字符型数组. String是不可变的.所谓的不可变是指一个对象有了一个引用 ...
-
Java异常处理-----抛出处理
抛出处理 定义一个功能,进行除法运算例如(div(int x,int y))如果除数为0,进行处理. 功能内部不想处理,或者处理不了.就抛出使用throw new Exception("除数 ...
-
VS窗体换肤
1.首先我们要下载一个皮肤 vs窗体皮肤下载官网:http://irisskin.software.informer.com/download/ 2.创建一个lib文件夹 把下载好的引用放到里面 3. ...
-
vs报错找不到错在哪里!Validation failed for one or more entities
今天在处理Entity Framework修改数据库时,报错: Validation failed for one or more entities. See 'EntityValidationErr ...