Java学习笔记

jdk5.0新增的新特性–可变个数的形参:

1、可变个数的形参的格式:数据类型 … 变量名。
2、当调用可变个数的形参方法时,传入的参数个数可以是0-n个。
3、可变个数形参方法与本类中方法名称相同,形参不同的方法构成重载。
4、可变个数形参方法与本类中方法名称相同,形参类型也相同的数组之间不构成重载,换句话说,就是二者不能共存(主要是因为编译器认为两种方法,是同样的一种)。
5、可变个数形参,在方法中只能声明在末尾,且只能存在一个。

代码块:

静态代码块和非静态代码块。
1、静态代码块:
(1)内部可以有输出语句。
(2)随着类的加载而执行。
(3)静态代码块,只能调用静态结构,不能调用非静态的结构。
(4)如果定义了多个静态代码块,则按照定义的顺序执行。(一般不这样用,直接用一个)
(5)静态代码块优先于非静态代码块执行。
作用:初始化类的一些属性。
2、非静态代码块:
(1)内部可以有输出语句。
(2)随着对象的创建而执行。
(3)非静态代码块,可以调用静态结构,也可以调用非静态结构。
(4)每创建一次对象就执行一次。
(5)如果定义了多个非静态代码块,则按照定义的顺序执行。(一般不这样用,直接用一个)
作用:可以在创建对象时对对象进行初始化。

final关键字:

1、final可以用开修饰类,方法,变量。
2、用来修饰类,此类不能被继承。比如,String,System,StringBuffer。
3、用来修饰方法,此方法不能被重写。
4、用来修饰变量(属性、局部变量),此时的变量称为常量,赋值之后,不能再改变。

abstract关键字:extends:继承

1、抽象方法只有方法的声明,没有方法体。
2、包含抽象方法的类一定是抽象类,但是,抽象类并不一定必须含有抽象方法。
3、若子类重写了父类的所有抽象方法,子类方可实例化,反之,该子类也是一个抽象类。
4、若子类没有重写父类的抽象方法,子类必须是抽象类。
5、一个子类只能继承一个父类,即单继承。
6、抽象类不能实例化。

interface关键字:implements:实现

1、java中,接口和类是并列的两种实现。
2、接口是不能够定义构造器的,即不能实例化。
3、定义接口中的成员:
(1)JDK7.0以前,只能定义全局常量和抽象方法
b)全局常量:public static final + 名称,但是书写时可以省略不写。
a)抽象方法:public abstract 返回值类型 + 名称,但是书写时可以省略不写。
(2)JDK8.0之后,除了能够定义全局常量和抽象方法之外,还可以定义静态方法,默认方法。
a)接口中定义的静态方法,只能通过接口去调,通过实现类或者实现类的对象是调不到的。
b)通过实现类的对象可以调用接口中的默认方法。如果实现类重写了默认方法,则调用时,调用的是重写之后的方法。
c)如果实现类继承的父类和实现的接口中声明了同名同参数的方法,子类在没有重写此方法时,默认调用的是父类中的方法。—>类优先原则
d)如果实现类实现了多个接口,且接口中声明了同名同参数的方法,那么在实现类没有重写此方法时,报错。---->接口冲突
e)如果实现类重写了,父类,接口中同名同参数的方法。那么可以对于父类,可以使用super.方法的形式对父类方法进行调用。对于接口,则使用接口.super.方法的形式调用。

异常:

Java程序在执行过程中的异常事件可以分为两类:Error、Exception。又分为编译时异常,运行时异常。
1、Error。Java虚拟机无法解决的严重问题。例如:JVM系统内部错误,资源耗尽等情况。一般不编写针对性代码进行处理。
2、Exception。其他因编程错误或偶然的外在因素导致的一般性问题。例如:空指针访问,试图读取不存在的文件,网络问题,数组角标越界等等。可以使用针对性代码进行处理。

异常的体系结构:

java.lang.Throwable(常见的异常)
|— java.lang.Error:一般不编写针对性代码进行处理。
|— java.lang.Exception:可以进行异常处理。
|— 编译时异常(checked)
|— IOException
|— FileNotFoundException
|— ClassNotFoundException
|— 运行时异常(unchecked,RuntimeException)
|— NullPointerException 空指针异常
|— ArrayIndexOutOfBoundsException 数组角标越界
|— ClassCastException 类型转换异常
|— NumberFormatException 数值类型转换异常
|— InputMismatchException 输入不匹配
|— ArithmaticException 算数异常

异常处理的方式:“抓抛模型”

(1)try-catch-finally
可以理解为:通过简单处理,自己能够解决。
(2)throws+异常类型
可以理解为:通过简单处理,自己解决不了,往上一级抛出。
“抛”:程序在运行过程中,一旦出现异常,就会在异常代码处生成一个异常类的对象。并将此对象抛出,其后的代码不再执行。
“抓”:(1)try-catch-finally
try{
//可能出现异常的代码
}catch(异常类型1 变量名1){
//处理异常的代码
}catch(异常类型2 变量名2){
//处理异常的代码
}
finally{
//一定会执行的代码
}
说明:
1)finally是可选的。
2)使用try将可能出现异常的代码包起来,一旦出现异常,就会生成一个异常类的对象,根据此对象的类型去catch中匹配。
3)一旦匹配到一个catch,就会进入该catch中执行,往后的catch不再执行(无finally),跳出try-catch结构。
4)catch中的异常类型,如果没有继承关系,谁定义在上谁在下没关系,如果有继承关系,则子类应该先声明,否则会报错,这是因为, 子类如果在下面,将不可到达。
5)常用的异常对象处理方式:String getMessage() 、 printStackTrace()。
6)在try结构中定义的变量,在异常结束后,不能够调用。
使用 try-catch-finally 处理编译时异常,使得程序在编译时不再报错,但是运行时可能报错,相当于将编译可能出现的异常,延迟 到了,运行时。
7)finally中是一定会执行的代码,即使catch中又出现了异常、try中有return、catch中有return。
8)像数据库连接,输入输出流,网络编程Socket等资源,JVM是不能自动回收的,这就需要我们手动关闭,此时资源释放就需要声明在 finally中。
(2)throws+异常类型
1)throws+异常类型 写在方法声明处,此方法执行时,可能抛出的异常类型,一旦方法执行出现了异常,就会创建一个异常类对象。此 对象满足 throws后的异常类型时,就会抛出。异常后代码将不再执行。谁调用了该方法,谁就处理该异常,或者继续往上级抛出。
(3)如果父类方法中抛出了异常,那么子类如果重写了父类中抛异常的方法,那么子类中该方法抛出的异常应小于父类中的异常类型。
(4)如果父类中没有方法使用throws抛出异常,那么子类中方法也不能使用throws抛异常。

自定义异常类:

(1)继承现有的异常类结构:Exception 、RuntimeException。
(2)提供全局的serialVersionID,序列号,标识唯一类。
(3)提供重载的构造器。

多线程:

(1)程序:用来完成特定任务,用某种语言编写的一组指令。即指静态代码,就是程序。
(2)进程:简单笼统的说就是运行中的程序。是一个动态的过程。
(3)线程:进程可进一步细化为线程,线程是一个程序内部的一条执行路径。若一个程序,同一时间并行的执行多个线程,就是支持多线程的。
多线程内存资源:每一个线程都会有自己的栈和程序计数器,而每一个进程有自己的方法区和堆,也就是说,多线程共享方法区和堆。
并行与并发:多个CPU同时执行多个任务,就好比多个人同时做不同的事。
并发:单个CPU同时执行多个任务。比如,秒杀,多个人同时做一件事。

多线程的优点:

(1)提高应用程序的响应,对图形化界面更有意义,可增强用户体验。
(2)提高计算机系统CPU的利用率。
(3)改善程序结构,将既长又复杂的程序分为多个线程,独立运行,易于理解和修改。

何时需要多线程:

(1)程序需要同时执行两个或多个任务。
(2)程序需要实现一些需要等待的任务时,如用户输入,文件读写操作,网络操作,搜索。
(3)需要一些后台运行的程序时。

线程的创建和使用:

方式一:继承于Thread类
(1)创建一个继承于Thread类的子类。
(2)重写Thread类中的run()方法。将此线程所要完成的任务写在run()方法中。
(3)创建一个Thread类子类的对象。
(4)用此对象调用start()方法。作用:启动线程,调用run()方法。
(5)注意,直接调用run()方法,将不会启动线程。
(6)不能让一个已经start的线程去再次start(),会报异常。需重新创建线程对象,调用start();
方式二:实现Runnable接口
(1)创建一个实现了Runnable接口的类。
(2)实现接口中的run()方法。
(3)创建实现类的对象。
(4)将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象。
(5)通过Thread类的对象调用start()方法。
两种方式的比较:开发中优先选择实现Runnable接口的形式,
原因:
(1)实现的方式没有类的单根继承性的局限性。
(2)实现的方式,更适合处理多个线程共享数据的问题。否则,共享的变量需要声明为static。
联系:
(1)Thread类也是实现了Runnable类。
(2)两种方式都需要重写run()方法,将线程要完成的任务放在run()方法中。

Thread类中常用的方法:

(1)start():启用线程,并调用线程中的run()方法。
(2)run(),需重写Thread中的run()方法,此方法中写线程要完成的任务。
(3)Thread.currentThread(),返回当前执行代码的线程。
(4)getName(),获取当前线程名字。
(5)setName(),设置当前线程名字。
(6)yield(),释放当前CPU的执行权。
(7)join(),在线程a中调用线程b的join方法,线程a进入阻塞状态,知道线程b执行完毕,线程a结束阻塞。
(8)stop(),已过时,当执行此方法时,强制结束当前线程。
(9)sleep(long millitime),使线程进入睡眠(阻塞状态)指定millitime毫秒,会抛异常,记得使用try-catch。
(10)isAlive(),判断线程是否还存活。

线程的优先级:

高优先级线程要抢占低优先级线程CPU资源,但这只是概率,并不意味着一定是高优先级的执行完以后低优先级的才能执行
1、MAX_PRIORITY:10
MIN_PRIORITY:1
NORM_PRIORITY:5 默认优先级
2、如果来获取和设置线程的优先级
getPriority();获取优先级
setPriority();设置优先级

线程的生命周期:

(1)新建:当一个线程创建后,新生的线程对象处于新建状态。
(2)就绪:处于新建状态的线程,start后,进入就绪状态,等待CPU。
(3)运行:当就绪状态的线程,被调度,并获得CPU资源,进入运行状态。run方法定义了线程的操作和功能。
(4)阻塞:在某种特殊情况下,被认为挂起或执行输入输出操作时,让CPU临时中止自己的执行,进入阻塞状态。例如使用join方法。
(5)死亡:线程完成了他的全部工作或线程被提前强制终止或出现异常导致结束。

线程的生命周期

线程的同步:

主要解决线程安全问题。
出现的原因:当某个线程运行过程中对共享数据进行操作,尚未完成时,其他线程也参与进来。就有可能造成线程安全。
如何解决:当一个线程A在操作共享数据时,其他线程不能参与进来,直到线程A操作完成。其他线程才可以操作共享数据,即使线程A出现了阻塞,其他现车给也不能操作。

在JAVA中通过同步机制,解决线程安全问题。
方式一:同步代码块。(解决了线程安全问题,但是,操作同步代码时只能有一个线程,其他线程等待,相当于是一个单线程,效率较低)

synchronized(同步监视器){
需要同步的代码
}

说明:(1)同步监视器,俗称:锁。任何一个类的对象都可以充当锁。(要求多个线程必须公用一个锁)。
(2)需要同步的代码就是操作共享数据的代码。
(3)同步监视器,可以是任何一个类的对象。实现Runnable类方式的多线程,可考虑使用this充当,继承方式的多线程,慎用this充当,可采用类 名称.calss的方式。(类名称.class的这种形式也是一个对象)
(4)特别注意,锁的唯一性!!!!

方式二:同步方法。
如果操做共享数据的代码完整的声明在一个方法中,不妨将该方法声明为同步的。即在方法返回值类型前加上synchronized。
同步方法,同样涉及到同步监视器。
非静态的同步方法,他的同步监视器是this。
静态的同步方法,他的同步监视器是他的类本身(类名称.class)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值