1.类成员变量有默认初始值,局部变量必须初始化
2.super()必须出现在构造函数的第一句
3.多态:继承,然后覆盖方法;成员变量不能多态
4.父类对象 isinstanceof 子类对象 返回 True
5.final修饰的类不能被继承,修饰的方法不能被重写,修饰的变量不能被改变
6.程序中成员变量赋值的执行顺序:
(
1)声明成员变量的默认初始化
(
2)显式初始化、多个初始化块依次被执行(同级别下按先后顺序执行)
(
3)构造器再对成员进行初始化操作
(
4)通过”对象
.属性”或”对象
.方法”的方式,可多次给属性赋值
7.一个类中初始化块若有修饰符,则只能被
static修饰,称为静态代码块
(static block
),当类被载入时,类属性的声明和静态代码块先后顺序被执行,且只被执行一次。
static块通常用于初始化
static (类
)属性
class Person {
public static int total
;
static {
total
= 100;
}
……
}
8.非静态代码块:没有
static修饰的代码块
1.可以有输出语句。
2.可以对类的属性、类的声明进行初始化操作。
3.可以调用静态的变量或方法。
4.若有多个非静态的代码块,那么按照从上到下的顺序依
次执行。
5.每次创建对象的时候,都会执行一次。且先于构造器执行
静态代码块:用
static 修饰的代码块
1.可以有输出语句。
2.可以对类的属性、类的声明进行初始化操作。
3.不可以对非静态的属性初始化。即:不可以调用非静态的属
性和方法。
4.若有多个静态的代码块,那么按照从上到下的顺序依次执行。
5.静态代码块的执行要先于非静态代码块。
6.静态代码块只执行一次
9.含有抽象方法的类必须被声明为抽象类
10.不能用
abstract修饰属性、私有方法、构造器、静态方法、
final的方法
11.接口
(
1)接口中的所有成员变量都默认是由
public static final修饰的。
(
2)接口中的所有抽象方法都默认是由
public abstract修饰的。
(
3)接口中没有构造器。
(
4)接口采用多继承机制
12.Java
8中关于接口的改进
Java
8中,你可以为接口添加静态方法和默认方法。从技术角度来说,这是完全合法的,只是它看起来违反了接口作为一个抽象定义的理念。
(
1)静态方法:使用
static 关键字修饰。可以通过接口直接调用静态方法,并执行其方法体。我们经常在相互一起使用的类中使用静态方法。你可以在标准库中找到像Collection
/Collections或者Path
/Paths这样成对的接口和类。
(
2)默认方法:默认方法使用
default 关键字修饰。可以通过实现类对象来调用。我们在已有的接口中提供新方法的同时,还保持了与旧版本代码的兼容性。
比如:java
8 API中对Collection、List、Comparator等接口提供了丰富的默认方法。
public interface AA {
double PI
= 3.14;
public default void method() {
System
.out
.println("北京");
}
default String
method1() {
return "上海";
}
public static void method2() {
System
.out
.println(“hello lambda
!"
);
}
}
13.接口冲突的解决方式
比如有个类实现了两个接口,那两个接口都有getName方法,那么在本类中如何解决冲突?
class Test implements IntfaceA,InterfaceB
{
public String
getName(){
return InterfaceA
.super.getName();
}
}
14.内部类可以使用外部类的私有数据,因为它是外部类的成员,同一个类的成员之间可相互访问。而外部类要访问内部类中的成员需要
:内部类
.成员或者内部类对象
.成员。
15.和外部类不同,Inner
class可声明为
private或
protected;
Inner
class 可以声明为
static的,但此时就不能再使用外层类的非
static的成员变量;
16.Inner
class作为类:
可以声明为
abstract类 ,因此可以被其它的内部类继承
【注意】非
static的内部类中的成员不能声明为
static的,只有在外部类或
static的内部类中才可声明
static成员。
17.匿名内部类不能定义任何静态成员、方法和类,只能创建匿名内部类的一个实例。一个匿名内部类一定是在
new的后面,用其隐含实现一个接口或实现一个类。
new 父类构造器(实参列表)
|实现接口
(){
}
18.匿名内部类举例
interface A{
public abstract void fun1();
}
public class Outer{
public static void main(String
[] args
) {
new Outer().callInner(new A(){
public void fun1() {
System
.out
.println(“implement
for fun1"
);
}
});
}
public void callInner(A a
) {
a
.fun1();
}
}
19.创建用户自定义异常类
class MyException extends Exception {
static final long serialVersionUID
= 1L
;
private int idnumber
;
public MyException(String message
, int id
) {
super(message
);
this.idnumber
= id
;
}
public int getId() {
return idnumber
;
}
}
20.枚举类的属性
枚举类对象的属性不应允许被改动
, 所以应该使用
private final 修饰
枚举类的使用
private final 修饰的属性应该在构造器中为其赋值
若枚举类显式的定义了带参数的构造器
, 则在列出枚举值时也必须对应的传入参数
21.自定义 Annotation(注解)
定义新的 Annotation 类型使用 @
interface 关键字
Annotation 的成员变量在 Annotation 定义中以无参数方法的形式来声明
. 其方法名和返回值定义了该成员的名字和类型
.
可以在定义 Annotation 的成员变量时为其指定初始值
, 指定成员变量的初始值可使用
default 关键字
public @
interface MyAnnotation{
String
name() default “atguigu"
;
}
没有成员定义的 Annotation 称为标记
; 包含成员变量的 Annotation 称为元数据 Annotation
22.StringBuffer类
java
.lang
.StringBuffer代表可变的字符序列,可以对字符串内容进行增删。
很多方法与String相同,但StringBuffer是可变长度的。
StringBuffer是一个容器。
23.自定义泛型类
class Person<T>{
private T info
;
public T
getInfo(){
return info
;
}
public void setInfo(T info
){
this.info
= info
;
}
public Person(){}
public Person(T info
){
this.info
= info
;
}
}
24.对于泛型方法
方法,也可以被泛型化,不管此时定义在其中的类是不是泛型类。在泛型方法中可以定义泛型参数,此时,参数的类型就是传入数据的类型。
泛型方法的格式:
[访问权限
] <泛型
> 返回类型 方法名
([泛型标识 参数名称
]) 抛出的异常
public class DAO {
public <E> E
get(int id
, E e
){
E result
= null
;
return result
;
}}
25.通配符的使用
(
1)使用类型通配符:?
比如:List
<?> ,Map
<?,?>
List
<?>是List
<String>、List
<Object>等各种泛型List的父类。
(
2)读取List
<?>的对象list中的元素时,永远是安全的,因为不管list的真实类型是什么,它包含的都是Object。
(
3)写入list中的元素时,不行。因为我们不知道c的元素类型,我们不能向其中添加对象。
唯一的例外是null,它是所有类型的成员。
将任意元素加入到其中不是类型安全的:
Collection
<?> c
= new ArrayList<String>();
c
.add(new Object());
因为我们不知道c的元素类型,我们不能向其中添加对象。
add方法有类型参数E作为集合的元素类型。我们传给add的任何参数都必须是一个未知类型的子类。因为我们不知道那是什么类型,所以我们无法传任何东西进去。
唯一的例外的是null,它是所有类型的成员。
另一方面,我们可以调用
get()方法并使用其返回值。返回值是一个未知的类型,但是我们知道,它总是一个Object
26.有限制的通配符
<?>
允许所有泛型的引用调用
举例:
<? extends Number> (无穷小
, Number
]
只允许泛型为Number及Number子类的引用调用
<? super Number
> [Number
, 无穷大
)
只允许泛型为Number及Number父类的引用调用
<? extends Comparable>
只允许泛型为实现Comparable接口的实现类的引用调用
public static void printCollection3(Collection
<? extends Person> coll
){
Iterator
<?> iterator
= coll
.iterator();
while(iterator
.hasNext()){
System
.out
.println(iterator
.next());
} }
public static void printCollection4(Collection
<? super Person
> coll
){
Iterator
<?> iterator
= coll
.iterator();
while(iterator
.hasNext()){
System
.out
.println(iterator
.next());
} }
27.程序中打开的文件 IO 资源不属于内存里的资源,垃圾回收机制无法回收该资源,所以应该显式关闭文件 IO 资源。
28.缓冲流要“套接”在相应的节点流之上,对读写的数据提供了缓冲的功能,提高了读写的效率,同时增加了一些新的方法
对于输出的缓冲流,写出的数据会先在内存中缓存,使用
flush()将会使内存中的数据立刻写出
BufferedReader br
= null
;
BufferedWriter bw
= null
;
try {
br
= new BufferedReader(new FileReader("d:\\IOTest\\source.txt"));
bw
= new BufferedWriter(new FileWriter("d:\\IOTest\\destBF.txt"));
String str
= null
;
while ((str
= br
.readLine()) != null
) {
bw
.write(str
);
bw
.newLine();
} bw
.flush();
} catch (IOException e
) {
e
.printStackTrace();
}
finally {
try {
if (bw
!= null
) {
bw
.close();
}
} catch (IOException e
) {
e
.printStackTrace();
}
try {
if (br
!= null
) {
br
.close();
}
}
catch (IOException e
) {
e
.printStackTrace();
}
29.序列化:用ObjectOutputStream类保存基本类型数据或对象的机制
反序列化:用ObjectInputStream类读取基本类型数据或对象的机制
对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。当其它程序获取了这种二进制流,就可以恢复成原来的Java对象
序列化的好处在于可将任何实现了Serializable接口的对象转化为字节数据,使其在保存和传输时可被还原
30.对象的序列化
凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量:
private static final long serialVersionUID
;
serialVersionUID用来表明类的不同版本间的兼容性
如果类没有显示定义这个静态变量,它的值是Java运行时环境根据类的内部细节自动生成的。若类的源代码作了修改,serialVersionUID 可能发生变化。故建议,显示声明
简单来说,Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。
(InvalidCastException
)
31.序列化的使用例子
序列化
:将对象写入到磁盘或者进行网络传输。
要求对象必须实现序列化
ObjectOutputStream oos
= new ObjectOutputStream(new FileOutputStream("test3.txt"));
Person p
= new Person("韩梅梅",18,"中华大街",new Pet());
oos
.writeObject(p
);
oos
.flush();
oos
.close();
ObjectInputStream ois
= new ObjectInputStream(new FileInputStream("test3.txt"));
Person p1
= (Person
)ois
.readObject();
System
.out
.println(p1
.toString());
ois
.close();
31.转换流
InputStreamReader:用于将字节流中读取到的字节按指定字符集解码成字符。需要和InputStream“套接”。
OutputStreamWriter:用于将要写入到字节流中的字符按指定字符集编码成字节。需要和OutputStream“套接”。
public void testMyInput() throws Exception
{
FileInputStream fis
= new FileInputStream("dbcp.txt");
FileOutputStream fos
= new FileOutputStream("dbcp5.txt");
InputStreamReader isr
= new InputStreamReader(fis
,"GBK");
OutputStreamWriter osw
= new OutputStreamWriter(fos
,"GBK");
BufferedReader br
= new BufferedReader(isr
);
BufferedWriter bw
= new BufferedWriter(osw
);
String str
= null
;
while((str
= br
.readLine()) != null
){
bw
.write(str
);
bw
.newLine();
bw
.flush();
} bw
.close(); br
.close();}
32.Class 类
对象照镜子后可以得到的信息:某个类的属性、方法和构造器、某个类到底实现了哪些接口。对于每个类而言,JRE 都为其保留一个不变的 Class 类型的对象。一个 Class 对象包含了特定某个类的有关信息。
Class本身也是一个类
Class 对象只能由系统建立对象
一个类在 JVM 中只会有一个Class实例
一个Class对象对应的是一个加载到JVM中的一个
.class文件
每个类的实例都会记得自己是由哪个 Class 实例所生成
通过Class可以完整地得到一个类中的完整结构
33.反射的应用举例
String str
= "test4.Person";
Class
clazz = Class
.forName(str
);
Object obj
= clazz
.newInstance();
Field field
= clazz
.getField("name");
field
.set(obj
, "Peter");
Object obj2
= field
.get(obj
);
System
.out
.println(obj2
);
34.创建运行时类的对象
String name
= “atguigu
.java
.Person"
;
Class
clazz = null
;
clazz
= Class
.forName(name
);
Constructor con
= clazz
.getConstructor(String
.class,Integer
.class);
Person p2
= (Person
) con
.newInstance("Peter",20);
System
.out
.println(p2
);
35.待续