JAVA小记
第二章
1.从容量大的数据转换成容量小的数据必须要进行强制类型转换
2.转换前数据类型的位数必须比转换后的低
3.所有引用类型的默认值都是null
4.switch()语句中的表达式类型:它的值必须是byte/short/int/char/enum或String型
第三章:
1.JAVA重载具有二义性
2.static变量是一块内存,该类的每个对象对静态变量的改变都会影响到其他对象。静态变量通常使用类名进行访问。
3.接口中的常量和默认方法都被实现类继承,但是静态方法不能被子接口继承,也不能被类继承
4.接口也可以有对象,new一个实现它的类。然后这个对象就可以实现类所继承和接口本身就有的方法了。
5.如果多个父接口中有同名的变量,则子接口中不能继承。但是子接口可以重新定义一个同名的变量。
6.默认方法:default关键字 若子接口中定义了与从父接口那里继承来的默认方法的话,父接口的默认方法被隐藏。
7.如果一个类继承一个父类并实现一个接口,而且从父类和接口继承了同样的方法,那么就采用“类比接口优先”原则,即只继承父类的方法,而忽略来自接口的默认方法。
8.final类型的变量必须进行初始化,因为系统不会给它默认值。
final类型的方法不能够被重写
final类型的类不能被继承,即不能拥有自己的子类
9.缺省访问修饰符的话,则称包可访问的,即可以被同一个类和同一个包中的类访问
10.初始化时静态变量、静态初始块是最先被分配内存初始化的
11.继承:子类不继承父类的private方法和构造方法,默认使用父类不带参数的构造方法,即若是子类中不写关于super(参数)的语句则系统自动在其构造方法的开头添上一句super(),如果要用父类的方法则在最开始就要写上super(参数),或者子类的构造方法也可以调用子类中其他的构造方法,这时就要用this(参数),不过也要放在构造方法的第一句,且this和super不能并存。
子类不继承父类的静态成员和private成员
子类继承的static方法不能覆盖它
12.静态方法只能调用静态成员变量,实例方法可以调用当前的实例变量也可以对静态变量进行操作。
13.子类上转型成父类之后,父类调用的方法是子类继承或覆盖的方法,但是不能用子类特有的方法。
14.如果使用final修饰方法的参数,则参数的值在方法体中只能被使用而不能被改变
15.静态内部类只能访问外部的静态成员
16.内部类:
(1)成员内部类:是不被static修饰的,可以访问外部类的所有成员,包括私有成员。成员内部类用this表示内部类实例的引用,如要获得外部类实例的引用,需要用MyOuter.this 成员内部类不能定义static方法和变量
(2)局部内部类:不能在局部块之外的地方访问,因此也不能有任何访问修饰符。局部内部类可以访问外层类的实例变量、方法的参数、访问方法的final局部变量。局部内部类不能用static修饰,不能用public private protected等修饰,但可以用final abstract修饰。static方法中定义的局部变量可以访问外部类的static成员,不能访问外部类的实例成员。
(3)匿名内部类:没有名字也没有构造方法,它不需要使用extends或implements,在定义的时候就直接new创建了,用的是继承的类名或者实现的接口名。
(4)静态内部类:用static修饰但不是成员变量,放在外部类的内部。静态内部类可以定义静态成员而成员内部类不可以;静态内部类只能访问外层类的静态变量而成员内部类可以访问外部类的静态和实例成员;静态内部类实例不需要先创建一个外层类的实例而 创建成员内部类实例,必须先创建一个外部类的实例。静态内部类不存在任何对外层类实例的引用,所以静态内部类中的方法不能使用this来访问外层类的实例成员,但是这些方法可以访问外层类的static成员。
(5) 在类的内部还能定义内部接口,内部接口的隐含属性是static的。
17.一个源文件只能有一个public类(或接口、枚举等),该源文件的名字必须跟这个public类的类名相同。
18.枚举:为了使用枚举类型,需要创建一个该类型的引用,并将某个枚举实例赋值给它。
枚举类型既是Object类的子类又实现了Comparable接口。
for(Direction a:Direction.values()) A.values()返回的是包含这个枚举类型的所有常量的数组
A.name() 返回的是枚举常量名 A.ordinal() 返回的是枚举常量的顺序值
19.注解:
Deprecated:标志方法或类型已经被弃用
SuppressWarnings:只是编译器阻止某些类型的警告
SuppressWarnings(value={"unchecked","serial","deprecation"})
20.异常:
Exception类异常分为两类:非检查异常和检查异常
非检查异常:RuntimeException类及其子类。编译器不用对它处理。
但是,为了保证程序能够正常运行,要么避免非检查异常,要么对非检查异常进行处理。
程序运行时发生非检查异常时运行时系统会把异常对象交给默认的异常处理程序,在控制台显示异常的内容及发生的位置。
常见非检查异常:NullPointerException/ArithmeticException(除数为0的时候产生的)/ClassCastException/ArrayIndexOutOfBoundsException/NumberFormatException等等
检查异常:除了RnutimeException类及其子类以外的类。程序必须捕获或者声明抛出。
try-catch-finally语句:
catch块:catch(ArithmeticException e){ //就是异常类型(如ArithmeticException) 和异常引用名e
...........;
}
catch块排列顺序必须按照从特殊到一般的顺序,即子类异常放前面,父类异常放后面;
catch块中可以不写任何语句,只要有一对大括号,就认为异常被处理了,程序编译就不会出现错误,编译后的程序正常运行。catch块内的语句只有在真的异常产生时才会执行。
finally语句不论异常产生与否都要执行,即使是用了return语句,但当catch语句里用了System.exit()方法时不用执行finally而是直接终止程序的运行
catch块和finally块都不能单独使用,必须配合try使用
声明方法抛出异常:
异常不在该方法中处理而是在调用该方法的方法中处理。
returnType methodName([paramlist]) throws ExceptionList{
//方法体
}
try和catch、finally都在调用该方法的方法中写,try该方法,然后后面写catch、finally
若父类的方法使用throws抛出了异常那么子类覆盖该方法的时候也可以使用throws声明异常,但是该异常必须是父类异常或父类异常的子类
如果所有的方法里都没有处理异常的方法,则控制台显示异常和异常发生的位置
用throw语句抛出异常:
之前的异常都是由程序产生并自动抛出的,但是可以创建一个异常对象并用throw 语句抛出,或将捕获到的异常对象用throw 语句再次抛出。
throw throwableInstance;
public class Demo{
public static void method()throws IOException{
try{
throw new IOException("文件未找到");
}catch(IOException e){
System.out.println("捕获到异常");
throw e;
}
public static void main(String args[]){
try{
method();
}catch(IOException e){
System.out.println("再次捕获"+e);
}
try-with-resources语句
避免在资源(如文件流)不需要时忘记将其关闭
try(resource-specification){
//使用资源
}
只有实现了java.long.AutoCloseable接口的那些资源才可自动关闭
例如:try(Door door=new Door();Window window=new Window()){
..............;
..............;
}catch( ){
............
}finally{
............
}
door和window两个对象就是可自动关闭的资源,抛出异常之后,程序控制转到异常处理代码,在此之前,程序将调用两个资源的close()方法将door和window关闭,然后才进行异常处理。且关闭的顺序是从后往前依次关闭。
21.断言:
关键字assert
两种类型:assert 表达式(返回值是bool)
assert 表达式:基本数据类型或者Object类型的值
布尔值是false的时候抛出(带有消息的)AssertionError异常
断言默认情况下是关闭的,得用-ea或者-enableassertions来开启,用-da或者-disableassertions关闭
D:\study>javac -ea AsserationDemo
D:\study>javac -ea:package1 -da:Class1 AsserationDemo
22.接口的继承和类的继承关于上转型的问题:
子类的对象上转型成父类的对象之后,父类对象使用被子类覆盖的同名方法时,实现的是子类覆盖之后的方法;
而父类的变量是不能够被子类覆盖的,“覆盖”的概念仅仅是对于方法而言的,若子类覆盖父类同名变量则程序会报错。
而实现了某个接口的类(有可能还实现了其他的接口)对象上转型成接口对象之后,该接口对象是可以使用类中的所有被覆盖和继承来的方法的,尽管某个方法是从其他接口继承而来的也可以使用
23.泛型:
JAVA中大多数的类和接口都是泛型的
泛型就是带一个或多个类型参数的类或接口,注意类型参数只能代表引用型类型不能是原始类型(如int/char等的就不行)
泛型类:public class Node<T>{
private T value;
public Node(T value){
this.value=value;
}
在进行泛型类对象实例化的时候应该是:Node<Integer> a=new Node<Integer>(8);或者是Node<int> a=new Node<>(8);
泛型接口:public interface Entry<K,V>{
public K getKey();
public V getValue();
}
public class Pair<K,V>implements Entry<K,V>{
...............
}
实例化创建两个Pair实例:Pair<Integer,String> p1=new Pair<>(20,"twenty?);
Pair<String,String> p2=new Pair<>("china","Beijing")l
泛型方法:
类的成员方法和构造方法都可以定义为泛型的方法
注意:泛型方法必须在方法返回值之前指定泛型
public static <K,V> boolean compare(Pair<K,V> p1,Pair <K,V>){
..................;
}
这里的泛型方法是静态的,即可以直接使用类名进行访问该方法compare。
调用泛型方法的时候,由于已经明确指定了该泛型方法的参数类型:Pair<Integer,String> p1=new Pair<>(1,"A"); Pair<Integer,String> p2=new Pair<>(2,"b"),所以参数类型可以省略,即可将:Util.<Integer,String>compare(p1,p2)简写成 Util.compare(p1,p2);