加入收藏 | 设为首页 |

conflict-阿里架构师详解Java内部类是怎么完成的

海外新闻 时间: 浏览:397 次

目录

  • 部分内部类
  • 匿名内部类

内部类(inner class)是界说在另一个类中的类。

  • 内部类办法能够拜访该类界说地点的效果域中的数据,包含私有的数据。
  • 内部类能够对同一个包中的其他类躲藏起来
  • 当想界说一个回调函数且不想编写很多代码时,运用匿名(anonymous)内部类比较快捷。

以下简略举例:

一个时钟需求两个参数:发布布告的时刻距离以及开关铃声的标志。

public class TalkingClock {
private int interval;
private boolean beep;
public TalkingClock(int interval, boolean beep){
this.interval = interval;
this.beep = beep;
}
public void start(){
ActionListener listener = new TimePrinter();
Timer timer = new Timer(interval, listener);
timer.start();
}
public class TimePrinter implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("At the tone, the time is " + new Date());
if (beep) {
Toolkit.getDefaultToolkit().beep();
}
}
}
public static conflict-阿里架构师详解Java内部类是怎么完成的void main(String[] args) {
TalkingClock clock = new TalkingClock(1000, true);
clock.start();
//keep program running until user selects "OK"
Jconflict-阿里架构师详解Java内部类是怎么完成的OptionPane.showMessageDialog(null, "Quit program?");
System.exit(0);
}
}

本代码首要想阐明的是作为内部类的TimePrinter能够 直接拜访 外部类TalkingClock的 私有成员变量 beep。

语法和用法咱们很简略就学会了,那么内部类是怎么完成直接拜访其他类的私有成员变量呢?咱们知道Java的私有成员变量只要类的实例自身能拜访。

在开始学习conflict-阿里架构师详解Java内部类是怎么完成的Java语法的时分,是把内部类作为该类的一个特点去回忆和了解的,因而,天然能够拜访私有变量。这个了解,现在看来是过错的。

内部类是一种编译器现象,与虚拟机无关。编译器将会把内部类翻译成用$分隔外部类名与内部类名的惯例类文件,而虚拟机对此一窍不通。

上述内部类被编译成TalkingClock$TimePrinter :

javap -private TalkingClock$TimePrinter.class 
Compiled from "TalkingClock.java"
public class com.test.java.clazz.innerclass.TalkingClock$TimePrinter implements java.awt.event.ActionListener {
final com.test.java.clazz.innerclass.TalkingClock this$0;
public com.test.java.clazz.innerclass.TalkingClock$TimePrinter(com.test.java.clazz.innerclass.TalkingClock);
public void actionPerformed(java.awt.event.ActionEvent);
}

能够发现conflict-阿里架构师详解Java内部类是怎么完成的,编译器给增加了新的静态办法 static boolean access$000(com.test.java.clazz.innerclass.TalkingClock) ;,明显,咱们能够经过类名调用这个办法来获取私有变量,相当于给增加了getter办法露出私有变量。

检查变异后的内部类的actionPerformed办法:

public void actionPerformed(ActionEvent e) {
System.out.println("At the tone, the time is " + new Date());
if (TalkingClock.access$000(this.this$0)) {
Toolkit.getDefaultToolkit().beep();
}
}

综上,内部类经过编译器修正代码,完成了对类的拜访。假如黑客在同包名下调用外部类的access$000,则是能conflict-阿里架构师详解Java内部类是怎么完成的够拜访到私有变量的,这算是一个风险的当地吧。

部分内部类

仔细观察示例代码,TimePrinter只在start办法里调用了,咱们能够把这个类缩小为部分内部类,即在办法内部声明内部类。

部分内部类能够拜访部分变量

咱们将上述demo修正下:

public void start(int interval, Boolean beep) {
class TimePrinter implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Every "+interval+", At the tone, the time is " + new Date());
if (beep) {
Toolkit.getDefaultToolkit().beep();
}
}
}
ActionListener listener = new 殷菁TimePrinter();
Timer timer = new Timer(interval, listener)conflict-阿里架构师详解Java内部类是怎么完成的;
timer.start();
}

部分类不能用public或private拜访阐明符进行阐明,它的效果被限定在声明这个部分类的块中。

上述demo,部分内部类TimePrinter会拜访部分变量interval和beep。同理,依旧是将这两个变量转化程内部类的成员变量,完成值的传递。

匿名内部类

public class AnonymousInnerClassTest {
@Data
static class Animal {
private String name;
public void sayHi(){
System.out.println("Hi " + name);
}
}
public static void main(String[] args) {
Animal animal = new Animal(){
@Override
public void sayHi() {
System.out.println("Wang");
}
}
;
animal.sayHi();
}
}

上述简略模仿一种Animal匿名类。编译后的成果为:

'AnonymousInnerClassTest$1.class' 'AnonymousInnerClassTest$Animal.class' AnonymousInnerClassTest.class

编译器生成了3个编译类。

AnonymousInnerClassTest

public class AnonymousInnerClassTest {
public AnonymousInnerClassTest() {
}
public static void main(String[] args) {
com.test.java.clazz.innerclass.AnonymousInnerClassTest.Animal animal = new 1();
animal.sayHi();
}
}

AnonymousInnerClassTest$1

import com.test.java.clazz.innerclass.AnonymousInnerClassTest.Animal;
final class AnonymousInnerClassTest$1 extends Animal {
AnonymousInnerClassTest$1() {
}
public void sayHi() {
System.out.println("Wang");
}
}

AnonymousInnerClassTestAnimal‘‘‘classAnonymousInnerClassTestAnimal‘‘‘classAnonymousInnerClassTestAnimal {private String name;

public void sayHi() {
System.out.println("Hi " + this.name);
}
public AnonymousInnerClassTest$Animal() {
}
//getter setter equals toString

即编译器生成一个包拜访权限的内部类AnonymousInnerClassTestAnimal,关于其匿名子类,又生成了final的AnonymousInnerClassTestAnimal,关于其匿名子类,又生成了final的AnonymousInnerClassTest1 ,假如还有第二个匿名类,则命名AnonymousInnerClassTest$2.

写在最终

点重视,不走失;继续更新Java相关技能及资讯文章

(此处已增加圈子卡片,请到今天头条客户端检查)

欢迎参加头条圈子,一同学习前进。

(此处已增加圈子卡片,请到今天头条客户端检查)
  1. 写出我的第一个结构:迷你版Spring MVC
  2. 透彻了解MyBatis规划思想之手写完成
  3. 透彻了解Spring业务规划思想之手写完成
  4. 了解数据库连接池底层原理之手写完成
  5. 手把手带你完成JDK动态署理
  6. 手写完成一个迷你版的Tomcat
  7. 自己着手写一个服务网关
  8. 手把手带你规划一个百万级的音讯推送体系
  9. 手把手带你秒杀架构实践(含完好代码)
  10. 解密Dubbo:自己着手编写一个较为完善的RPC结构(两万字干货)

想要进阶架构师,不仅仅仅仅懂得结构原理。下面,就让我手把手带你手写Spring MVC、Spring、Mybatis、秒杀架构、RPC等结构,让你提高架构思想,真实吃透!