类内方法、成员、代码块的执行顺序

(1)父类静态成员和静态初始化块,按在代码中出现的顺序依次执行。
(2)子类静态成员和静态初始化块,按在代码中出现的顺序依次执行。
(3)父类实例成员和实例初始化块,按在代码中出现的顺序依次执行。
(4)执行父类构造方法。
(5)子类实例成员和实例初始化块,按在代码中出现的顺序依次执行。
(6)执行子类构造方法。

类中静态语句块仅在类加载时被执行一次
A:静态成员变量或静态代码块>main方法>非静态成员变量或非静态代码块>构造方法
B:think in java中提到构造器本身并没有任何返回值。
C: 构造方法的主要作用是完成对类的对象的初始化工作。
D: 一般在创建(new)新对象时,系统会自动调用构造方法
static关键字: static关键字可以修饰变量,方法,静态代码块。
                          静态变量:
                                          由static修饰的变量称为静态变量
                                          静态变量属于类,而不属于某个对象
                                          静态变量它的副本只有一个(静态变量在类中只加载一)
                         静态方法:
                                          在静态方法中只能调用静态变量和静态方法
                                          在非静态方法中,可以调用静态方法或者变量。
                                          在静态方法中不能使用this和super关键字。
                        静态代码块
                                          作用:用来给静态成员变量初始化
首先声明什么是静态方法:
  1. 用static修饰的方法
  2. 静态方法是使用公共内存空间的,就是说所有对象都可以直接引用,不需要创建对象再使用该方法。 
其次说明静态方法的使用:
  1. 在外部调用静态方法时,可以使用"类名.方法名"的方式,也可以使用"对象名.方法名"的方式。
  2. 而实例方法只有后面这种方式。
也就是说,只有调用静态方法时可以无需创建对象。

注意:
1.静态内部类才可以声明静态方法
2.静态方法不可以使用非静态变量
3.抽象方法不可以有函数体

类方法和实例方法

Java中以static关键字修饰的方法称为类方法,实例化一个类,引用的普通方法称为实例方法
在类方法中调用本类的类方法可直接调用。 实例方法也叫做对象方法。
类方法是属于整个类的,而实例方法是属于类的某个对象的
由于类方法是属于整个类的,并不属于类的哪个对象,所以类方法的方法体中不能有与类的对象有关的内容。即类方法体有如下限制: 
  1.  类方法中不能引用对象变量;
  2.  类方法中不能调用类的对象方法,可以间接通过生成对象来调用;
  3.  在类方法中不能使用super、this关键字。
  4. 类方法不能被覆盖。 
如果违反这些限制,就会导致程序编译错误。
与类方法相比,对象方法几乎没有什么限制
  1.  对象方法中可以引用对象变量,也可以引用类变量;
  2.  对象方法中可以调用类方法;
  3.  对象方法中可以使用super、this关键字。

对象的初始化方式:

1.new时初始化 ;
2.静态工厂 newInstance;
3.反射Class.forName();
4.clone方式;
5.反序列化;

方法在其他类中调用

静态方法:可以直接用如下形式调用 类名.方法名; 
普通public方法:必须实例化类,Test test = new Test(); test.method(); 
protected方法: 只能在子类以及基类中调用该方法,其他的非继承基类的类,是不能有访问权限的;
抽象方法:抽象方法必须被抽象类的实现类来实现,这样通过实现类实例化来调用该方法才可以。

多态成员访问特点(父类子类问题)

成员变量:编译看左边,运行看左边    
静态变量:编译看左边,运行看左边
成员方法:编译看左边,运行看右边    
静态方法:编译看左边,运行看左边

子类构造函数调用父类构造函数用super
子类重写父类方法后,若想调用父类中被重写的方法,用super
未被重写的方法可以直接调用。

抛出异常

throws用于在方法上声明该方法不需要处理的异常类型,用在方法上后面跟异常类名 可以是多个异常类
throw用于抛出具体异常类的对象,用在方法内 后面跟异常对象只能是一个异常类型实体.
try块必须和catch块或和finally同在,不能单独存在,二者必须出现一个. 
finally块总会执行,不论是否有错误出现.但是若try语句块或会执行的catch语句块使用了JVM系统退出语句,finally块就不会被执行了. 一般我们把关闭资源的代码放在finally里面 保证资源总是能关闭
throw和throws的区别
都可抛出异常
				
首先,是使用的位置,throws 只能跟在方法名和括号的后面,而 throw 只能出现在方法体内。

其次,throws 是一个声明(它声明这里可能出现异常,但未必一定出现),而 throw 是一个动作(它抛出也可以说它产生一个异常出现,只要执行到了这个关键字,异常必定出现)。

try语句

catch可以省略,try的形式有三种:
try-catch
try-finally
try-catch-finally
catch和finally语句不能同时省略!

执行顺序问题
1、不管有木有出现异常,finally块中代码都会执行;
2、当try和catch中有return时,finally仍然会执行;
3、finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,管finally中的代码怎么样,返回的值都不会改变,任然是之前保存的值),所以函数返回值是在finally执行前确定的;
4、finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值。
举例:
情况1:try{} catch(){}finally{} return;
显然程序按顺序执行。
情况2:try{ return; }catch(){} finally{} return;
程序执行try块中return之前(包括return语句中的表达式运算)代码;
再执行finally块,最后执行try中return;
finally块之后的语句return,因为程序在try中已经return所以不再执行。
情况3:try{ } catch(){return;} finally{} return;
程序先执行try,如果遇到异常执行catch块,
有异常:则执行catch中return之前(包括return语句中的表达式运算)代码,再执行finally语句中全部代码,
最后执行catch块中return. finally之后也就是4处的代码不再执行。
无异常:执行完try再finally再return.
情况4:try{ return; }catch(){} finally{return;}
程序执行try块中return之前(包括return语句中的表达式运算)代码;
再执行finally块,因为finally块中有return所以提前退出。
情况5:try{} catch(){return;}finally{return;}
程序执行catch块中return之前(包括return语句中的表达式运算)代码;
再执行finally块,因为finally块中有return所以提前退出。
情况6:try{ return;}catch(){return;} finally{return;}
程序执行try块中return之前(包括return语句中的表达式运算)代码;
有异常:执行catch块中return之前(包括return语句中的表达式运算)代码;
则再执行finally块,因为finally块中有return所以提前退出。
无异常:则再执行finally块,因为finally块中有return所以提前退出。
最终结论:任何执行try 或者catch中的return语句之前,都会先执行finally语句,如果finally存在的话。
如果finally中有return语句,那么程序就return了,所以finally中的return是一定会被return的,
编译器把finally中的return实现为一个warning。

equals和==的区别

java中的数据类型,可分为两类: 

1.基本数据类型
也称原始数据类型。byte,short,char,int,long,float,double,boolean 
他们之间的比较,应用双等号(==),比较的是他们的值。 
如果两边有包装类型,则先将包装类型装换成基本类型再比较值是否相等。
两边都为包装类型时,即为对象,比较的是地址。
2.复合数据类型(类) 
当他们用(==)进行比较的时候,比较的是他们在内存中的存放地址,所以,除非是同一个new出来的对象,他们的比较后的结果为true,否则比较后结果为false。 JAVA当中所有的类都是继承于Object这个基类的,在Object中的基类中定义了一个equals的方法,这个方法的初始行为是比较对象的内存地 址,但在一些类库当中这个方法被覆盖掉了,如String,Integer,Date在这些类当中equals有其自身的实现,而不再是比较类在堆内存中的存放地址了。
对于复合数据类型之间进行equals比较,在没有覆写equals方法的情况下,他们之间的比较还是基于他们在内存中的存放位置的地址值的,因为Object的equals方法也是用双等号(==)进行比较的,所以比较后的结果跟双等号(==)的结果相同。

Java异常

Java的异常分为两种,一种是运行时异常(RuntimeException),一种是非运行异常也叫检查式异常(CheckedException)。
1、运行时异常不需要程序员去处理,当异常出现时,JVM会帮助处理。常见的运行时异常有:
ClassCastException(类转换异常)
ClassNotFoundException
IndexOutOfBoundsException(数组越界异常)
NullPointerException(空指针异常)
ArrayStoreException(数组存储异常,即数组存储类型不一致)
还有IO操作的BufferOverflowException异常
2、非运行异常需要程序员手动去捕获或者抛出异常进行显示的处理,因为Java认为Checked异常都是可以被修复的异常。常见的异常有:
IOException
SqlException

加载驱动

加载驱动方法
1.Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
2. DriverManager.registerDriver(new com.mysql.jdbc.Driver());
3.System.setProperty("jdbc.drivers", "com.mysql.jdbc.Driver");
DriverManager.getConnection方法是获取链接的,而不是加载驱动的。

访问控制修饰符

接口和抽象类的异同

接口和抽象类对实体类进行更高层次的抽象,仅定义公共行为和特征。

语法维度 抽象类 接口
成员变量 无特殊要求  默认 public static final 常量
构造方法 有构造方法,不能实例化 没有构造方法,不能实例化
方法  抽象类可以没有抽象方法,但有抽象方法一定是抽象类  默认 public abstract,JDK8 支持默认/静态方法(可以有方法体),JDK9 支持私有方法(解决代码重复问题)
继承 单继承 多继承

抽象类、接口的修饰符

1、抽象类中的抽象方法(其前有abstract修饰)不能用private、static、synchronized、native访问修饰符修饰。原因如下:抽象方法没有方法体,是用来被继承的,所以不能用private修饰;static修饰的方法可以通过类名来访问该方法(即该方法的方法体),抽象方法用static修饰没有意义;使用synchronized关键字是为该方法加一个锁。。而如果该关键字修饰的方法是static方法。则使用的锁就是class变量的锁。如果是修饰类方法。则用this变量锁。但是抽象类不能实例化对象,因为该方法不是在该抽象类中实现的。是在其子类实现的。所以。锁应该归其子类所有。所以。抽象方法也就不能用synchronized关键字修饰了;native,这个东西本身就和abstract冲突,他们都是方法的声明,只是一个吧方法实现移交给子类,另一个是移交给本地操作系统。如果同时出现,就相当于即把实现移交给子类,又把实现移交给本地操作系统,那到底谁来实现具体方法呢?

2、接口是一种特殊的抽象类,接口中的方法不全是抽象方法(但其前的abstract可以省略),jdk1.8可以使用static修饰接口中的方法,而且static修饰的是实函数,所以接口中不能用的访问修饰符为private、protected、synchronized、native,因为接口可以让所有的类去实现(非继承),不只是其子类,但是要用public去修饰。接口可以去继承一个已有的接口。

类、方法、成员变量和局部变量的可用修饰符

修饰符

成员访求

构造方法

成员变量

局部变量

abstract(抽象的)

static (静态的)

public(公共的)

protected(受保护的)

 

private(私有的)

synchronized(同步的)

native(本地的)

transient(暂时的)

volatie(易失的)

final(不要改变的)


关键字



线程方法

两种方法的区别:
    1.start方法
         用 start方法来启动线程,是真正实现了多线程, 通过调用Thread类的start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到cpu时间片,就开始执行run()方法。但要注意的是,此时无需等待run()方法执行完毕,即可继续执行下面的代码。所以run()方法并没有实现多线程。
    2.run方法
         run()方法只是类的一个普通方法而已,如果直接调用Run方法,程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码。
其他方法:
    1.sleep()方法
        在指定时间内让当前正在执行的线程暂停执行,但不会释放“锁标志”。不推荐使用。
        sleep()使当前线程进入阻塞状态,在指定时间内不会执行。
    2.wait()方法
         在其他线程调用对象的notify或notifyAll方法前,导致当前线程等待。线程会释放掉它所占有的“锁标志”,从而使别的线程有机会抢占该锁。
         当前线程必须拥有当前对象锁。如果当前线程不是此锁的拥有者,会抛出IllegalMonitorStateException异常。
         唤醒当前对象锁的等待线程使用notify或notifyAll方法,也必须拥有相同的对象锁,否则也会抛出IllegalMonitorStateException异常。
         waite()和notify()必须在synchronized函数或synchronized block中进行调用。如果在non-synchronized函数或non-synchronized block中进行调用,虽然能编译通过,但在运行时会发生IllegalMonitorStateException的异常。
    3.yield方法 
         暂停当前正在执行的线程对象。
         yield()只是使当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。
         yield()只能使同优先级或更高优先级的线程有执行的机会。 
    4.join方法
         等待该线程终止。
         等待调用join方法的线程结束,再继续执行。如:t.join();//主要用于等待t线程运行结束,若无此句,main则会执行完毕,导致结果不可预测

注解

1.Java三大注解分别是@Override @Deprecated @Suppresswarnings
2.@Override 注解表名子类中覆盖了超类中的某个方法,如果写错了覆盖形式,编译器会报错
3.@Deprecated 表明不希望别人在以后使用这个类,方法,变量等等
4.@Suppresswarnings 达到抑制编译器产生警告的目的,但是不建议使用,因为后期编码人员看不懂编译器提示的警告,不能更好的选择更好的类去完成任务

Servlet

HttpServlet容器响应Web客户请求流程如下:

1)Web客户向Servlet容器发出Http请求;

2)Servlet容器解析Web客户的Http请求;

3)Servlet容器创建一个HttpRequest对象,在这个对象中封装Http请求信息;

4)Servlet容器创建一个HttpResponse对象;

5)Servlet容器调用HttpServlet的service方法,这个方法中会根据request的Method来判断具体是执行doGet还是doPost,把HttpRequest和HttpResponse对象作为service方法的参数传给HttpServlet对象;

6)HttpServlet调用HttpRequest的有关方法,获取HTTP请求信息;

7)HttpServlet调用HttpResponse的有关方法,生成响应数据;

8)Servlet容器把HttpServlet的响应结果传给Web客户。
doGet()  doPost() 是创建HttpServlet时需要覆盖的方法.

字节流、字符流

面向字符的输入流类都是Reader的子类

面向字符的输出流都是类 Writer 的子类

类加载器

jvm classLoader architecture :

Bootstrap ClassLoader/启动类加载器
主要负责jdk_home/lib目录下的核心 api 或 -Xbootclasspath 选项指定的jar包装入工作.

Extension ClassLoader/扩展类加载器
主要负责jdk_home/lib/ext目录下的jar包或 -Djava.ext.dirs 指定目录下的jar包装入工作

System ClassLoader/系统类加载器
主要负责java -classpath/-Djava.class.path所指的目录下的类与jar包装入工作.

User Custom ClassLoader/用户自定义类加载器(java.lang.ClassLoader的子类)

在程序运行期间, 通过java.lang.ClassLoader的子类动态加载class文件, 体现java动态实时类装入特性.

socket编程