Java的基本数据类型有8种,包括6种数字类型,1种字符类型和1种布尔类型。
数字类型包括4种整数类型和2种浮点数类型,4种整数类型是byte、short、int、long,2种浮点数类型是float和double。
字符类型是char,用于表示单个字符。
布尔类型是boolean,包括true和false两种取值。
基本数据类型 | 存储大小 | 取值范围 | 默认值 | 字节数 | 包装类 |
---|---|---|---|---|---|
byte | 8位有符号数 | -2^7 ~ 2^7-1 | 0 | 1 | Byte |
short | 16位有符号数 | -2^15 ~ 2^15-1 | 0 | 2 | Short |
int | 32位有符号数 | -2^31 ~ 2^31-1 | 0 | 4 | Integer |
long | 64位有符号数 | -2^63 ~ 2^63-1 | 0L | 8 | Long |
float | 32位,符合IEEE 754标准 | -3.402823e+38 ~ -1.401298e-45和1.401298e-45到3.402328e+38 | 0.0f | 4 | Float |
double | 64位,符合IEEE 754标准 | -1.797693e+308 ~ -4.9000000e-324和 4.9000000e-324 ~ 1.797693e+308 | 0.0d | 8 | Double |
char | 16位 | 0 ~ 2^16-1 | ‘\u0000’ | 2 | Character |
boolean | 1位 | true 和 false | false | 4或1 | Boolean |
注:
JVM规范中,boolean变量当作int处理,也就是4字节;而boolean数组当做byte数组处理,即boolean类型的数组里面的每一个元素占1个字节。
将小范围类型的变量装换为大范围类型称为拓展类型,不需要显性声明类型转换。将大范围类型的变量转换为小范围类型称为缩窄类型,必须显性声明类型转换,否则会导致编译错误。
1.字符类型和数字类型之间可以进行转换。
2.将数字类型转换成字符类型是,只使用整数的低16位(浮点 数类型将整数部分转换成字符类型)。
3.将字符类型转换数字类型时,字符的统一编码转换成指定的数值类型。如果字符的统一码超过了转换成的数值类型的取值范围,则必须显性声明类型转换。
2.方法
1.修饰符。
2.返回值类型。
3.方法名。
4.参数列表。
5.方法体。
是指在用一个类中的多个方法有相同的名称,但是方法签名不同。
方法签名:方法名和参数列表共同组成。因此被重载的方法必须具有不同的参数列表,而不能通过不同的修饰符和返回值类型进行方法的重载。
1.面向对象的概念
面向对象:将问题分解成对象,描述事物在解决问题的步骤中的行为。对象与属性的和行为是关联的。
优点:具有分装,继承,多态的特性,因而容易维护,复用和扩展,可以设计出低耦合的系统。
缺点:需要实例化对象,因此性能比面向过程低。
面向过程:将问题分解成步骤,然后按照步骤实现函数,执行 时依次调用函数。数据和对数据的操作是分离的。
2.构造方法
1.构造方法的名称必须与所在的类的名称相同。
2.构造方法没有返回类型,包括没有void。
3.构造方法通过new操作符调用,通过调用构造方法创建对象。
3.静态和实例
Java的类成员(成员变量,方法等)可以是静态的或实例的。使用关键字static修饰的类成员是静态的类成员,不适用关键字static修饰的类成员则是实例的类成员。
1.外部调用:从外部调用静态的类成员是,可以通过类名调用,也可以通过对象名调用。从外部调用实例的类成员,则只能通过对象名调用。
2.内部访问:静态方法只能访问静态的类成员,不能访问实例的类成员。实例方法既可以访问实例的类成员,也可以访问静态的类成员。
4.初始代码块
初始代码块属于类成员,在加载类时或创建对象时会隐式调用代码初始块。使用初始化块的好处是可以减少多个构造器类的重复代码。。
可以分为静态初始化块和非静态初始化块。前者在加载类时被隐式调用,后者在创建对象时被隐式调用。
1.如果有初始化块,则初始化块会在其他代码之前执行。具体而言,静态初始化块会在静态方法之前被执行,非静态初始化块会在构造器和实例方法之前被执行。
2.由于静态初始化块在加载类时被调用,因此静态初始化块会最先执行,且只会执行看一次。
3.由于非静态初始化块在创建对象是被调用,因此每次创建对象时都会执行非静态初始化块以及执行构造器。非静态初始化块的执行在静态初始化的执行之后,构造器执行之前。
1.执行父类的静态初始化块。
2.执行子类的静态初始化块。
3.执行父类的非静态初始化块。
4.执行父类的构造器。
5.执行子类的非静态初始化块。
6.执行子类的构造器。
5.关键字this
关键字this代表当前对象的引用。当前对象指的是调用类中的属性或方法的对象。
- 由于关键字this代表的是对象的引用,因此依赖于具体对象,而静态方法和静态初始化块不依赖于类的具体对象,因此静态方法和静态初始化块中不能使用关键字this。
6.可见性修饰符
修饰符 | 同一个类 | 同一个包 | 子类 | 全局 |
---|---|---|---|---|
pirvate | √ | |||
default | √ | √ | ||
protected | √ | √ | √ | |
public | √ | √ | √ | √ |
7.字符串
1.String 是不可变类型,每次对String的修改操作 都会创建新的String对象,导致效率低下且占用大量内存空间,因此String适用于字符串常量的情形,不适合需要对字符串进行大量修改的情形。
2.StringBuffer是可变类型,可以修改字符串的内容且不会创建新的对象,且StringBuffer是线程安全的,适用于多线程环境。
3.StringBuilder是可变类型,与StringBuffer相似,在单线程环境下StringBuilder的效率略高于StringBuffer,但是在多线程环境下StringBuilder不保证线程安全,因此StringBuilder不适合多线程环境。
8.继承
在面向对象程序设计中,可以从已有的类(父类)派生出新类(子类),称为继承。
关键字super指向当前类的父类。关键字super可以用于两种途径,一是调用父类的构造方法,二是调用父类的方法。
调用父类的构造方法,使用super()或super(参数),该语句必须是子类构造方法的第一个语句,且这是调用父类构造方法的唯一方式。
调用父类的方法,使用super。方法名(参数)
如果构造方法没有显式地调用同一个类中其他的构造方法或父类的构造方法,将隐性地调用父类的无参数构造方法,即编译器会把super()作为构造方法的第一个语句。
构造一个类的实例时,将会沿着继承链调用所有父类的构造方法,父类的构造方法在子类的构造方法之前调用,称为构造方法链
重载 | 方法 | |
---|---|---|
场合 | 同一个类 | 父类和子类 |
方法名称 | 相同 | 相同 |
方法签名 | 不同 | 相同 |
返回值类型 | 可以不同 | 相同或者子类返回值类型是父类返回值类型的子类 |
9.Object类的部分方法
public boolean equals(Object obj)
该方法检验俩个对象是否相等。该方法的默认实现使用==运算符检验两个对象是否相等,通常都需要在子类中重写该方法。
public native int hashCode()
该方法返回对象的散列吗。关键字native表示实现方法的编程语言不是Java。
散列码是一个整数,用于在散列集合中存储并能快速查找对象。
根据散列约定,如果两个对象相同,他们的散列码一定相同,因此如果在子类中重写了equals方法,必须在该子类中重写hashCode方法,以保证两个相等的对象对应的散列码是相同的。
两个相等的对象一定具有相同的散列码,俩个不同的对象也可能具有相同的散列码。实现hashCode方法时,应避免过多地出现俩个不同的对象也可能具有相同的散列码的情况。
protected void finalize() throws Throwable
该方法用于辣鸡回收。如果一个对象不再能被访问,就变成了辣鸡,fianlize方法会被该对象的辣鸡回收程序调用。该方法的默认实现不做任何事。(不要轻易重写该方法,容易导致垃圾回收出现问题,从而产生内存泄漏)
1.final属性不可变,指的是引用不可变,而不关心指向对象内容的变化,被final修饰的变量必须初始化
2.final方法不可被子类重写,可以实现inline(内联)的机制
3.final类不可以被继承(如String、StringBuffer),所有的方法不可以被重写,但其内的非final变量可以被修改
protected native Object clone() throws CloneNotSupportedException
该方法用于复制一个对象,创建一个有单独内存空间的新对象。
不是所有的对象都可以赋值,只有当一个类实现了java.lang.Cloneabel接口时,这个类的对象才能被复制。
该方法可能抛出CloneNotSupportedException异常
public final native Class> getClass()
该方法返回对象的元对象。元对象是一个包含类信息的对象,包括类名,构造方法和方法等。
一个类只有一个元对象,每一个对象都有一个元对象,同一个类的多个对象对应的元对象相同。
10.抽象类和接口
抽象类使用关键字abstract修饰。
抽象类可以包含抽象方法。抽象方法使用关键字abstract修饰,只有方法签名而没有实现,实现由子类提供。
抽象方法都是非静态的。
包含抽象方法的类必须声明为抽象类。
非抽象类不能包含抽象方法。如果一个抽象父类的子类不能实现所有的抽象方法,则该子类也必须声明为抽象类。
包含抽象方法的类必须声明为抽象类,但是抽象类可以不包含抽象方法。
接口使用关键字interface定义。接口只包含可见性为public的常量和抽象方法,不包含变量和具体方法。和抽象类一样,接口不能用new操作符创建实例。
1.抽象类的变量没有限制,接口只包含常量,即接口的所有变量必须是public static final。
2.抽象类包含构造方法,子类通过构造方法链调用构造方法,接口不包含构造方法。
3.抽象类的方法没有限制,接口的方法必须是public bastract的实例方法(从Java 8开始,接口方法可以有默认实现,从Java 9开始,接口内允许定义私有方法。
4.一个类只能继承一个父类,但是可以实现多个接口,一个接口可以继承多个接口。
Comparable接口:
Comparabel接口是拍戏接口。如果一个类实现了Comparable接口,则该类的对象可以排序。Comparable接口包含一个抽象方法compareTo,实现Comparable接口的类需要实现该方法,定义排序的依据。
Comparator接口:
Comparator接口是比较器接口。如果一个类本身不支持排序(即没有 实现Comparable接口),但是又需要对该类的对象排序,则可以通过实现Comparator接口的方式建立比较器。Comparator接口包含俩个抽象方法compare和equals,其中compare方法时必须在实现类中实现的,而equals方法在任何类中默认已经实现。
注:
如果需要对一个数组或列表中的多个对象进行排序,则可以将对象的类定义成实现Comparable接口,也可以在排序时定义Comparator比较器。
11.序列化和反序列化
把对象转换成字节序列的过程称为对象的序列化,吧字节序列恢复成对象的过程称为对象的反序列化。
只有当一个类实现了Serializable接口时,这个类的实例才是可序列化的。
将一个对象序列化时,会将该对象的数据域进行序列化,不会对静态数据域进行序列化。
在序列化的过程中,加了关键字transient的数据域将被忽略
12.序反射机制
Java反射机制的核心是在程序运行时动态加载类以及获取类的信息,从而使用类和对象的数据域和方法。
1.对象调用getClass方法,获取该对象所属的Class对象。
2.调用静态方法Class。forName,将类名做为参数,获得类名对应的Class对象。
3.对任意的Java类型T,调用T.class获得类型T对应的Class对象。
1.getName,该方法返回类的名字。
2.getFields,getMethods和getConstructors 方法分别返回类中所有的公有(即使用可见修饰符public修饰)的数据域,方法和构造方法。
3.getDeclaredFields,getDeclaredMethods和getDeclaredConstructors方法分别返回类中所有的数据域,方法和构造方法(包括所有可见修饰符)。
4.getField、getMethod 和 getConstructor 方法分别返回类中单个的公有(即使用可见修饰符 public 修饰)的数据域、方法和构造方法。
5.getDeclaredField、getDeclaredMethod 和 getDeclaredConstructor 方法分别返回类中单个的数据域、方法和构造方法(包括所有可见修饰符)。