-
JAVA语言特点:跨平台性
因为JVM虚拟机,同一个Java程序在三个不同的操作系统中都可以运行
-
垃圾回收:在C/C++中,由程序员负责,Java有自动回收机制。
注意:Java程序有自动回收机制,会出现内存泄露和溢出吗?yes
-
JDK:Java开发工具包(包括JRE)
-
JRE:Java运行环境
-
JVM:Java虚拟机
1、文档注释
-
单行注释
-
多行注释
-
文档注释
/** */ //注意:两个**号
使用 javadoc 解析 生成java文档
2、变量
整形
- byte 1字节
- short 2字节
- int 4字节
- long 8字节
浮点
-
float 4字节 精度有限
-
double 4字节
注:Java中浮点默认使用double ,声明float变量时,后面要加F /f
字符型
- char 2字节
布尔
- boolean
3、对象的三大特性
- 封装
- 继承
- 多态:一个事物的多种形态。一个对象体现多种形态 父类的引用指向指向子类的对象。
Person p = new Person();
有了对象的多态性之后,内存中实际是加载了的,但是父类不能调用子类的方法属性。
解决方法:使用强制转换(向上转型),子类强制转换为父类;
instanceof关键词
使用:判断A对象是否是B对象的实例,是true,否false。
在需要强制好装换的时候使用。
4、Object类的使用
- 所有类的父类
- Object类只申明了一个空参构造器
- 含有finalize()方法,在对象被回收之前自动调用此方法,提醒虚拟机回收。一般不要手动调用,交给垃圾回收机制。
- 程序员可以通过System.gc()或者Runtime.getRuntime().gc()来通知回收,但是不一定立马回收。
方法:equals() / toString() / getClass() / hashCode() /clone() / finalize() /wait() /notify() / notifyAll()
4.1 equals方法
-
==和equals()的区别(面试题)
-
==运算符
-
可以使用在基本数据类型和引用数据类型中。
-
如果比较的是基本数据类型,那么就是比较存储的值是否相同。
如果比较的是引用数据类型,那么比较的是两个对象的地址值是否相同,即两个引用是否指向同一个对象实体。
-
注意:
String s1 = "BB"; String s2 = "BB"; s1==s2 //true
原因:字符串会放入常量池,
当执行String s2 = "BB";时,先在常量池中查找是否有相同的常量,如果有则直接将引用指向已有的常量,不会再重新添加。使用new String("BB")不会导致这个问题。
-
-
equals()方法的使用
-
是一个方法,非运算符
-
适用于引用数据类型
-
Object类中equals()方法的定义(内部使用==比较)
public boolean equals(Object obj) { return (this == obj); }
-
像String,Date,File,包装类都重写了equals()方法,他们比较的是两个对象的实体内容是否相同,而不是引用对象是否相同。
-
自定义类使用equals()方法也通常比较两个对象的实体类是否相同,需要对Object类的方法进行重写(可参照String类重写)
手动重写的规则:比较对象里面的属性是否相同(age,name)
-
实际开发中,一般不手动重写,可使用编译器自动生成。
*面试回答:
-
==可以比较基本数据类型和引用数据类型,对于基本数据类型比较的是值,引用数据类型比较的是内存地址。
-
对于equals()方法,父类方法中默认使用==比较,当自定义类中需要使用equals,则需要重写equals。注意:常用的String File Date 包装类已经帮我们重写好了,可直接使用。
-
通常情况下,重写比较的是类中相应的属性是否相同。
-
-
4.2 toString()
- 当我们输出一个对象的引用时,默认调用toString()方法
- 像String,Date,File,包装类都重写了toString()方法
- 自定义类可以重写此方法。
5、包装类的使用
理解:基本数据类型不具有对象的特征,继承封装多态等,希望基本数据类型也具有这些特征,所以引出包装类。
基本数据类型 | 包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
boolean | Boolean |
char | Character |
基本数据类型、包装类、String三者之前的转换
- 基本转包装(可不记,有自动拆装箱)
int num =10 ;
Integer in = new Integer(num);
-
包装转基本(原因包装类不可以做加减乘除)
Integer in1 = new Integer(12); in1.intValue();
-
自动拆箱和装箱
jdk5.0的新特性
- 自动装箱-->基本到包装
- 自动拆箱-->包装到基本
-
基本、包装转String
-
连接运算 直接
int num= 10; num+"";
-
调用String.valueOf(num);
-
-
String转基本、包装
调用包装类的parseXxx()
6、static
-
用来修饰:属性、方法、代码块、内部类
-
按照是否使用static修饰 ,分为静态属性和非静态属性。
静态变量:多个对象同用一个属性,当一个对象修改静态属性后,其他对象的相同静态属性也相应修改。
-
静态变量随着类的加载而加载,可通过 “类.属性” 调用
静态变量早于对象的创建
由于类只加载一次,所以静态变量在内存中也只存在一份,存在方法区的静态域中。
实例变量与静态变量内存的解析:
-
静态方法中,只能调用静态方法与属性
非静态方法中,可以调用静态方法与静态属性,非静态方法与非静态属性。原因归结于 他们的生命周期。
-
使用static注意点:
- 静态方法中不能使用this、super关键词 原因:初始化时没有对象
-
在开发中如何声明属性或方法是否使用static?
- 属性可以被多个对象所共享,不会随着对象的不同而不同。
- 操作静态属性的方法 、工具类中的方法。
单例设计模式
概念:采取一定的方法在整个软件系统中,某个类只能存在一个实例对象。
实现步骤:
-
私有化构造器,防止其他类new该对象。
-
在类中创建该类的静态实例。
-
提供一个外部获取该实例的静态方法。
-
恶汉式 vs 懒汉式
恶汉式:
- 坏处:对象加载(生命周期)的时间过长,可能用不到。
- 线程安全
懒汉式:
- 好处:延迟对象的创建,随用随造。
- 线程不安全
//恶汉式 class Bank{ //私有化构造器 private Bank(){} //实例化对象 private static Bank instance = new Bank(); //提供外界访问 private static Bank getInstance(){ return instance; } } //懒汉式(啥时候用啥时候造) 不安全 需要修改! class Bank{ private Bank(){} private static Bank instance = null; private static Bank getInstance(){ if (instance == null){ instance = new Bank(); } return instance; } }
单例模式的优点:只产生一个实例,减少系统的开销。
应用场景:
- 网站计数器
- 应用程序的日志应用
- 数据库连接池(造一个池)
- 读配置文件的类
- Application .....
7、代码块(初始化块)
- 作用:用户初始化类,对象
- 只能使用static修饰
- 非静态代码块
- 内部可以有输出语句
- 随着对象的创建而执行,每次创建都会执行一次
- 作用:可以在创建对象时,对对象的属性等进行初始化
- 块内能调用静态属性、静态方法和非静态属性和非静态方法。
- 静态代码块
- 内部可以有输出语句
- 随着类的加载而执行,而且只执行一次
- 作用:初始化类的信息
- 如果一个类中定义了多个代码块,则谁先定义则谁先执行
- 块内能调用静态属性、静态方法。
- 非静态代码块
静态代码块、代码块、构造器执行顺序:由父及子 ,静态先行 静态代码块>代码块>构造器
赋值的先后顺序 :在类中静态代码块和定义谁先写 就谁先赋值。
8、final
-
可以用来修饰类,变量,方法
类:不可以被其他类继承
方法:不可以被重写
变量:不可改变
- 修饰属性:变成“常量” 可以显式/代码块/构造器中赋值
- 修饰局部变量:变成常量,赋值后不可再次操作。
9、抽象类和抽象方法
abstract关键词
- 可用来修饰类、方法
- 不可用来修饰属性,构造器等
- abstract不能用来修饰private方法,因为子类继承后不可重写。
- 不能用来修饰静态方法,final方法,final的类(矛盾)
- 抽象类:
- 不可实例化
- 抽象类中一定要有构造器,便于子类实例化
- 开发中一般都会提供子类,让子类实例化。
- 抽象方法:
- 抽象方法只有声明,没有方法体。
- 包含抽象方法的类,一定是一个抽象类。反之抽象类中,不一定有抽象方法。
- 子类继承抽象类,则必须实现父类的抽象方法。如果没有实现父类全部抽象方法,这个子类一定也是抽象类。
匿名类
Person p = new Person(){
....
}
意义:只用一次,后面不再使用,方便。
模板方法的设计模式
解决的问题:
- 一部分是确定的,一部分是不确定的,子类去实现这个不确定的
- 开发中,一些是不确定、易变的,把它抽象成方法,让子类去实现。
10、接口
-
java不支持多继承,所以提出接口概念。
-
接口和类是一个并列的结构。
-
将几个类具有的相同行为的特征,把它们抽取出来。比如手机、电脑等数码产品都有USB功能。
-
定义接口中的成员
JDK7之前,只能定义全局常量和抽象方法:
- 全局常量:public static final,但书写时可以不写,默认。
- 抽象方法:public abstract
JDK8:除了定义全局常量和抽象方法,还可以定义静态方法,默认方法。
-
接口中定义的静态方法只能通过接口来调用。子类实现后不能调用。
-
默认方法,子类实现(重写)后可调用。实现类可重写接口中的默认方法。
-
如果子类(或实现类)继承的父类和实现的接口中声明了同名同参数的方法,那么子类在没有冲洗而此方法的情况下,默认调用的是父类中同名同参的方法-->类优先原则
interface A{ default void P(){ System.out.println("抽象类"); } } class SubA implements A{ @Override public void P() { System.out.println("子类继承抽象类"); } } class Sub extends SubA implements A{ public static void main(String[] args) { new Sub().P(); //结果输出:子类继承抽象类 } }
-
如果子类中实现了多个接口,而接口中含有多个同名同参数的方法,那么会引起接口冲突,实现类必须实现这个方法。
-
在实现类中调用接口中被重写的方法
接口.super.方法名 A.super.P();
-
接口中不可以定义构造器,因为不可实例化。
-
如果一个类,没有实现接口中的抽象方法,那么这个类是抽象类。全部实现后,该类可以实例化。
-
Java可以实现多个接口。弥补Java单继承的缺陷。
-
接口与接口之间可以多继承。
-
接口是一种规范,体现了多态性。JDBC中多数使用了接口。
-
接口的应用:代理模式、工厂模式
面试题:
interface A{
int x= 0;
}
class B{
int x= 1;
}
class C extends B implements A{
public void Px(){
// 编译不通过
System.out.println(x);
// System.out.println(A.x);
// System.out.println(super.x);
}
public static void main(String[] args) {
new C().Px();
}
}
11、内部类
概念:Java允许在一个类中再声明类。
内部类的分类:成员内部类(静态,非静态) vs 局部内部类(方法、代码块、构造器)
- 成员内部类
-
作为类:
- 可定义属性、方法、构造器
- 可以被final修饰
- 可以abstract修饰
-
作为外部类的成员
- 可以调用外部类的结构
- 可以被static修饰
- 可以被四种权限修饰
-
实例化静态内部类实例
PersonD.Dog dog = new PersonD.Dog();
-
实例化非静态内部类实例
Person p = new Person(); Person.Bird bird = new p.new Bird();
- 局部内部类
返回实现一个实现了Comparaable接口类的对象
在局部内部类的方法中,如果调用局部内部类方法里面的局部变量,那么这个变量必须声明为final。(尚硅谷p370)
抽象类和接口有哪些共同点和区别(面试)
相同:不能实例化、都可以被继承
不同:抽象:有构造器 单继承 接口:不能声明构造器、多继承
12、异常
Error:Java虚拟机无法解决的严重问题。
Exception:编程错误或外在因素导致。
- 编译时异常
- 运行时异常
抓抛模型:
抛(手动生成异常对象)
抓(处理异常)
Java异常处理的方式(抓):
-
方式一:try-catch-finally
-
方式二:throws+加异常类型
try-catch使用注意:
- catch中的异常类型如果满足子父类关系,则要求子类一定声明在父类上面。否则报错
- 处理编译时异常。
- 使用finally,如果有try_catch中返回值,则先执行finally内的方法,再返回。
finally使用环境:像数据库,io,网络编程等需要我们手动去释放连接,jvm不会自动回收。
throws
写在方法的声明出,指明可能会出现的异常,抛给它的上一级处理。
重写方法异常抛出的规则
子类重写的方法抛出的异常不大于父类被重写方法的异常类型。
例如:在多态的使用中,将子类的对象赋值给父类,当子类方法中抛出异常,父类才能解决。
开发中如何选择使用try-catch和throws
- 如果在父类被重写的方法中,没有使用throws,那么它的子类也不能使用throws。
- 执行的方法中,先后调用了另外几个方法,这几个方法是递进关系的,一个方法出错,会影响整个解决整个结果时,建议这几个方法抛出异常,在调用时一起处理。
throw
手动抛出异常
自定义异常类
- 继承现有的异常结构:RuntimeException、Exception
- 提供全局异常:serialVersionUID
- 提供重载的构造器