基本类型
byte,short, int, long
float,double
char
boolean
char
# 注意 字符串类型是引用类型
String
# null 空值表示不存在
# 数组是引用类型,但数组元素是值类型
格式化输出
System.out.printf("%s improved %.1f %%", "canshu1", 25.5f);
// canshu1 improved 25.5 %
== 和 equals()
浮点数不能用==判断
引用类型用==判断是否为同一对象,用equals()判断是否逻辑相等
用equals()注意避免null
switch
switch(option) {
case 1:
//
break;
case 2:
//
break;
default:
//
}
do while
先循环,再判断
do while 至少循环一次
for 循环
for (int i = 0; i < 100; i++) {
//
}
for (int n : ns) {
// for each循环可以遍历数组
}
## beak和continue
break 提前退出循环
continue 提前退出本轮循环,直接继续下次循环
两者通常都配合if使用
## 数组循环
1.for
2.for...each
3.Array.toString()快速打印数组元素
## 数组排序
Arrays.sort
## 多维数组
int[][] ns = {
{1,2,3,4},
{4,5,6,7},
{8,9,10,11}
};
打印多维数组
Arrays.deepToString()
## 面向对象
class 用字段(field)封装了数据
指向实例的变量都是引用变量,不同实例有其各自独立的field
初始化顺序:1.初始化字段 2.执行构造方法代码
可以在一个构造方法中通过this()调用另一个构造方法
方法重载 Overload
方法名相同,但参数不同
1.类型不同
2.数量不同
重载方法返回值类型相同
继承
继承 In
继承是面向对象编程的代码复用方式
Java使用extends继承
被继承类:超类,父类,基类 继承类:子类,派生类
Java只允许继承一个类
Object是所有类的根类
protected修饰的字段和方法可以被子类访问
super表示父类
没有调用super()时编译器会自动生成super()语句
如果父类没有默认构造方法就必须显示调用super()
向上转型与向下转型 Upcasting Downcasting
子类类型可以安全地向上转型为父类类型
父类类型可以强制向下转型为子类类型(可能报错ClassCastException)
可以用instanceof判断类型
多态 Polymorphic
方法覆写:子类覆写父类的方法,Override
多态:
针对某个类型的方法调用,其真正执行的方法取决于运行时实际类型的方法
对某个类型调用方法,执行的方法可能是某个子类的覆写方法
允许添加更多类型的子类来扩展功能
final
用final修饰的方法不能被Override
用final修饰的类不能被继承
用final修饰的字段初始化后不能重新赋值
抽象类 Abstract Class
抽象方法:用abstract定义了方法签名,但没有语句
含有抽象方法的类称为抽象类
- 抽象类的作用:
被继承
强迫子类实现抽象方法
抽象方法相当于定义“规范” - 面向抽象编程的本质:
上层代码只定义规范
不需要子类即可编译
具体逻辑由不同子类实现,调用者不关心
接口 Inteface (接口只有抽象方法)
接口 interface
使用interface声明一个接口,接口只有抽象方法
实现interface使用implements
一个class可以实现多个interface
- 接口:
不能定义实例字段
不能定义普通方法
可以定义default方法
一个接口可以extends另一个接口,相当于扩展接口方法
接口层次代表抽象程度
接口也是数据类型,适用于向上转型和向下转型
静态方法和字段
静态字段和方法
用static修饰的字段:静态字段,属于class不属于实例
访问静态字段使用:类名.静态字段 不推荐使用实例变量.静态字段
用static修饰的方法:静态方法,属于class不属于实例
访问静态方法使用:类名.静态方法 不推荐使用实例变量.静态方法
静态方法不能访问this变量,但可以访问静态字段
静态方法常用于工具类和辅助方法
包 Package
package用于解决类名冲突:
Java完整类名=包名+类名 JVM只看完整类名 编译器编译后的class只含完整类名
包可以有多层结构 包没有父子关系
- 包作用域
位于同一个包的类,可以访问包作用域的字段和方法:
不用public、protected、private修饰的字段和方法就是包作用域。 - 引用其他类的方法
使用完整类名 先import,再使用类名
static import可以导入一个类的静态字段和静态方法,很少使用
查找class - 编译器查找class完整类名的步骤:
- 根据完整类名查找
- 查找当前package
- 查找import的class
- 查找java.lang的class
- 编译错误
作用域
- 访问权限
访问权限指一个类内部,能否引用另一个类以及它的字段和方法
访问权限有public、protected、private和package四种
final不是访问权限
最佳实践:最小化暴露对外方法 - 局部变量
方法内部定义的变量是局部变量(包括方法参数名)
局部变量作用域由所在语句块{...}决定
class和jar
- classpath
classpath是环境变量,指示JVM如何搜索class,路径和操作系统相关 - classpath设置方法:
在系统环境中设置(不推荐)
启动JVM时用-classpath或-cp设置(推荐)
Eclipse自动传入当前工程bin目录作为classpath - jar
jar包是zip格式的压缩文件,包含若干class文件
jar包相当于目录
使用jar包来避免大量目录和class文件 - 创建jar包:
JDK的jar命令
Maven等工具
压缩为zip然后改名为jar
jar包可以有一个特殊的/META-INF/MANIFEST.MF文件来指定Main-Class
字符串和编码
字符串
- Java字符串的特点:
字符串对象可以直接使用"..."表示
内容不可变
使用equals()判断是否相等 - 字符串常用操作:
是否包含子串:contains/indexOf/lastIndexOf/startsWith/endsWith
去除首尾空白字符:trim
提取子串:substring
大小写转换:toUpperCase/toLowerCase
替换子串:replace/replaceAll
分割:split
拼接:join - String和其他数据类型互相转换 String和char[]互相转换 String和byte[]互相转换(需要指定编码)
编码
ASCII
GB2312/GBK/GB18030
Unicode/UTF-8
建议总是使用UTF-8编码
StringBuilder
- StringBuilder
可以高效拼接String
是可变对象
可以进行链式操作
不要使用StringBuffer
包装类型
主要是为了将基本类型变成一个类
装箱和拆箱发生在编译阶段
JavaBean
JavaBean
JavaBean是一种Java编程规范:
- 目的:
方便IDE工具读写属性
传递数据
枚举属性 - JavaBean特点:
一组public getter/setter方法
boolean属性的读方法通常为isXxx()
属性可以是只读或只写的
属性只需要getter/setter方法,不一定需要实例字段 - 利用IDE可以快速生成属性方法
枚举类 (Enumeration)
Java使用enum定义常量类型,常量本身带有类型信息,可以使用==比较。
enum定义的类型是class,继承自java.lang.Enum
所有常量都是唯一引用实例
常量可用于switch语句
name()获取常量定义的字符串,注意不要使用toString()
ordinal()返回常量定义的顺序(无实质意义)
可以为enum类编写构造方法、字段、方法
构造方法必须为private
常用工具类
Math:数学计算
Random:生成伪随机数
SecureRandom:生成安全的随机数
BigInteger:表示任意大小的整数
BigDecimal:表示任意精度的浮点数
捕获异常
捕获异常使用try...catch
catch会捕获对应的Exception及其子类
多个catch子句从上到下匹配
顺序非常重要,子类必须在前
finally保证有无错误都会执行
finally可选
使用multi-catch捕获多种类型异常
反射
- class
class本身是一种数据类型(Type),class/interface的数据类型是Class,JVM为每个加载的class创建唯一的Class实例。
Class实例包含该class的所有信息,通过Class实例获取class信息的方法称为反射(Reflection) - 获取一个class的Class实例:
Class cls = String.class;
Class cls = "str".getClass();
Class cls = Class.forName("java.lang.String");
注意Class的==比较和instanceof的区别。 - 从Class实例获取class信息:
getName()
getSimpleName()
getPackage()
从Class实例判断class类型:
isInterface()
isEnum()
isArray()
isPrimitive()
创建class实例:
cls.newInstance()
JVM总是动态加载class,可以在运行期根据条件控制加载class。
Field
- 通过Class实例获取字段field信息:
getField(name):获取某个public的field(包括父类)
getDeclaredField(name):获取当前类的某个field(不包括父类)
getFields():获取所有public的field(包括父类)
getDeclaredFields():获取当前类的所有field(不包括父类) - Field对象包含一个field的所有信息:
getName()
getType()
getModifiers() - 获取和设置field的值:
get(Object obj)
set(Object, Object)
通过反射访问Field需要通过SecurityManager设置的规则。
通过设置setAccessible(true)来访问非public字段
Method
- 通过Class实例获取方法Method信息:
getMethod(name, Class...):获取某个public的method(包括父类)
getDeclaredMethod(name, Class...):获取当前类的某个method(不包括父类)
getMethods():获取所有public的method(包括父类)
getDeclaredMethods():获取当前类的所有method(不包括父类) - Method对象包含一个method的所有信息:
getName()
getReturnType()
getParameterTypes()
getModifiers() - 调用Method:
Object invoke(Object obj, Object... args)
通过设置setAccessible(true)来访问非public方法。
反射调用Method也遵守多态的规则。
Constructor
- 调用public无参数构造方法:
Class.newInstance() - 通过Class实例获取Constructor信息:
getConstructor(Class...):获取某个public的Constructor
getDeclaredConstructor(Class...):获取某个Constructor
getConstructors():获取所有public的Constructor
getDeclaredConstructors():获取所有Constructor - 通过Constructor实例可以创建一个实例对象:
newInstance(Object… parameters)
通过设置setAccessible(true)来访问非public构造方法。
继承关系
- 获取父类的Class:
Class getSuperclass()
Object的父类是null
interface的父类是null
-获取当前类直接实现的interface:
Class[] getInterfaces()
不包括间接实现的interface
没有interface的class返回空数组
interface返回继承的interface - 判断一个向上转型是否成立:
bool isAssignableFrom(Class)