青花小记

这个人很懒,只想写写代码做做饭

0%

Java 中,可以在一个类的内部定义另外一个类,这个内部定义的类,就称为内部类

内部类是一种非常有用的特性,它允许你把一些逻辑相关的类组织在一起,并控制位于内部的类的可见性

当生成一个内部类的对象时,此对象与创建它的外部类的对象之间就有了一种联系,所以它能访问其外部类对象的所有成员,而不需要任何特殊条件;此外,内部类还拥有其外部类的所有元素的访问权

如果想从外部类的非静态方法之外的任意位置创建某个内部类的对象,那么必须具体的制定这个对象的类型: OuterClassName.InnerClassName

创建内部类的对象时,需要使用外部类的对象去创建该内部类的对象

1
2
3
4
5
6
7
8
9
10
public class Outer {

class Inner{

}

public static void main(String[] args) {
Inner inner = new Outer().new Inner();
}
}

在拥有外部类的对象之前,是不能创建内部类对象的,这是因为内部类对象会暗中的链接到创建它的外部类对象上;但是如果你创建的是静态内部类,那么它就不需要对外部类对象的引用

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Outer {

static class Inner{
public void test() {
System.out.println("静态内部类创建测试!");
}
}

public static void main(String[] args) {
Inner inner = new Inner();
inner.test();
}
}

输出:

静态内部类创建测试!

如果是其他的外部类中创建 Inner 内部类的对象,则:

1
2
3
4
5
6
7
public class Test {

public static void main(String[] args) {
Outer.Inner inner = new Outer.Inner();
inner.test();
}
}

输出:

静态内部类创建测试!

内部类,隐藏实现细节

方法和作用域内的内部类-局部内部类

可以在方法里面或者任意的作用域内定义内部类

方法内的内部类常常用于回调

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public interface LocalInner {

String value();
}

public class Outer {

public LocalInner getLocalInner(){
class MyLocalInner implements LocalInner{

private String value = "local inner";

@Override
public String value() {
return value;
}
}
return new MyLocalInner();
}
public static void main(String[] args) {
Outer outer = new Outer();
LocalInner localInner = outer.getLocalInner();
String value = localInner.value();
System.out.println(value);
}
}

输出结果:

1
local inner

匿名内部类

比较常见的匿名内部类就是创建线程时用到的匿名内部类

1
2
3
4
5
6
7
8
9
10
11
public class Test {

public Runnable thread(){
return new Runnable(){
@Override
public void run() {

}
};
}
}

匿名内部类末尾有个分号,这个分号不是用来标记内部类结束的;实际上,它标记的是表达式的结束

如果定义一个匿名内部类,并且希望它使用一个在其外部定义的对象,那么编译器会要求其参数引用是 final 的;否则,将出现编译错误

在匿名类中不可能有命名构造器(因为它根本没名字),但是可以通过实例初始化,达到为匿名内部类创建一个构造器的效果

计算机中的常用单位

位 bit

计算机中的最小单元,缩写为b,值为0或1,表示一位的二进制信息

字节 byte

计算机中的基本单位,缩写为B,1字节 = 8位,即1byte = 8bit

千字节 KB

1KB = 1024B

兆字节 MB

1MB = 1024KB

吉字节 GB

又称千兆字节, 1GB = 1024MB

其他单位

TB 万亿字节 太字节

PB 千万亿字节 拍字节

EB 百亿亿字节 艾字节

ZB 十万亿亿字节 泽字节

YB 一亿亿亿字节 尧字节

BB 一千亿亿亿字节

NB

DB

转化时,都以1024计算

基础类型及其包装类型

基本类型 存储空间大小 最大值 最小值 包装类类型
boolean - - - Boolean
char 16bit Unicode 0 Unicode 2^16-1 Character
byte 8bit -128 127 Byte
short 16bit -2^15 2^15-1 Short
int 32bit -2^31 2^31-1 Integer
long 64bit -2^63 2^63-1 Long
float 32bit IEEE754 IEEE754 Float
double 64bit IEEE754 IEEE754 Double

boolean

boolean所占用的存储空间的大小没有明确指定,仅定义为能取字面值true和false

char

即Unicode字符

char类型的字符中包含某些特殊字符,即转义字符

常见的转义字符如下

  • \b 退格
  • \t 制表
  • \n 换行
  • \r 回车
  • " 双引号
  • ' 单引号
  • \\ 反斜杠

整型

Java中,整形的默认类型为int,默认值为0

byte和short主要用于特定的应用场合,如底层的文件处理

long类型的字面值都应该加L加以区分,如11L表示的long类型的11,而11则表示的是int类型的11

浮点型

float为单精度浮点型。默认值是0.0F

double是双精度浮点型,默认值是0.0

浮点型的默认类型是double

同long类型类似,float的表示要在字面量后方加F进行区分

float和double都不能表示精确的值,如货币,主要原因是浮点数值采用二进制系统表示,而在二进制系统中无法精确的表示分数1/10,这就好像十进制无法精确的表示1/3一样。如果想要进行高精度的计算,可以使用BigDecimal类,该类大体上也属于“包装类”,但是并没有对应的基础类型。

Double的特殊值

Double.POSITIVE_INFINITY 正无穷大

Double.NEGATIVE_INFINITY 负无穷大

Double.NaN 非数字

注意:不能使用 x == Double.NaN 的方法检测一个特定值是否等于Double.NaN,可以使用Double.isNaN()方法