内部类优点:1.可直接访问外部类的成员,包括私有。
之所以可以直接访问外部类的成员,是因为内部类中持有了一个外部类的引用,格式 外部类名.this
2.外部类要访问内部类必须要建立内部类对象
访问格式: 当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中。 可以直接建立内部类对象。
格式:外部类名.内部类名 变量名 =外部类对象.内部类对象;
Outer.Inner in =new Outer().Inner();
private 内部类
static:内部类就具备了static的特性,当内部类被static修饰后,只能直接访问外部类中的static策划那个元,出现了访问局限。
new Outer.Inner().Funcation();
Outer.Inner().funcation();
注意:当内部类中定义了静态成员,该内部类必须是static的。
当外部了中的静态方法访问内部类时,内部类也必须是static的。
当描述事物时,事物的内部还有十五,该事物用内部类来描述。因为内部事物在使用外部事物的内容。
内部类定义在局部时,
1.不可以被成员修饰符修饰
2.可以直接访问外部类中的成员,因为还持有外部类中的引用。但是不可以访问他所在的局部的变量。只能访问被final修饰的局部变量。
匿名内部类
1.匿名内部类其实就是内部类的间歇格式。
2.定义匿名内部类的前提:
内部类必须是继承一个类或者实现接口。
3.匿名内部类的格式: new 父类或者接口(){定义子类的内容}
4.其实匿名内部类就是一个你名子类对象,而且对象有点胖。乐意理解为内容的对象。
new AbsDemo()
{
void show(){
System.out.print("x="+x);
}
}.show();
多态子类只能调用父类方法
5.匿名内部类中定义的方法最好不要超过3个。
Java 中被 static 修饰的成员称为静态成员或类成员。它属于整个类所有,而不是某个对象所有,即被类的所有对象所共享。静态成员可以使用类名直接访问,也可以使用对象名进行访问。
异常
异常:就是程序在运行时初夏不正常情况。
异常由来:问题也是生活中一个具体的事物,也可以通过java的类的形式进行描述。并封装成对象。
其实就是java对不正常情况进行描述后的对象体现。
对于问题的划分:两种:一种是严重的问题,一种非严重的问题。
对于严重的,java通过Error类进行描述。
对于Error一般不编写针对习惯的代码对其进行处理。
对于非严重的,java通过Exception类进行描述。
对于Exception可以使用针对性的处理方式进行处理。
无论Error或者Exception都具有一些共性内容。
比如:不正常情况的信息,引发原因等。
Throwable
|--Error
|--Excaption
2.异常的处理
java 提供了特有的语句进行处理
try
{
需要被检测的代码;
}
catch(异常类 变量)
{
处理异常的代码;(处理方式)
}
finally
{
一定会执行的语句;
}
3. .getMessage()//异常名称:异常信息
.toString() //异常名称:异常信息,一擦很能够出现的位置
.printStackTrace() //异常名称,异常信息,异常出现的位置。
//其实jvm后人的异常处理机制,就是在调用printStackTrace方法。
打印异常的堆栈的跟踪信息。
throws Exception//异常声明
对多异常的处理
1.声明异常时,建议声明更为具体的异常。这样处理的可以更具体。
2.对方声明几个异常,就对应有几个catch块。不要定义多余的catch块
如果多个catch块中的异常出现继承关系,父类异常catch块放在最下面。
建议在进行catch处理时,catch中一定要定义具体处理方式。不要简单定义一句e.printStackTrace(),也不要简单的就书写一条输出语句。
自定义异常
用于对特有的问题进行自定义的封装。
必须要自定义类继承Excaption
继承Excaption原因:
一场体系有一个特点:因为异常类和异常地响都被抛出。
他们都具有可抛性是Throwable这个体系独有特点
只有这个体系中的类和对象才可以被throws和throw操作。
throws Exception{
throw Exception
}
thorws使用在函数上
throw使用在函数内
throws后面跟的异常类,可以跟多个。用逗号隔开。
throw后跟的是异常对象。
Exception中有一个特殊的子类异常RuntimeException运行时异常。
如果在函数内抛出该异常,函数上可以不用声明,编译一样通过。
如果在函数上声明了异常,调用者可以不用进行处理,编译一样能够通过
之所以不用在函数声明,是因为不需要让调用者处理。
当该异常发生,希望程序停止。因为在运行时,出现了无法继续运算的ing狂,希望停止程序后,对代码进行修正。
自定义异常时:如果该异常的发生,无法在继续进行运算,就让自定义异常继承RuntimeException
对于异常分两种:
1.编译被检测的异常
2.编译时不被检测的异常(运行时异常。RuntimeException以及其子类)
this:代表奔雷对象,哪个对象调用this所在函数,this就代表哪个对象。
final:
1.修饰类,变量(成员变量,静态变量,局部变量),函数。
2.修饰的类不可以被继承。
3.修师德函数不可以被覆盖
4.修饰的变量是一个常量,只能赋值一次。
5.内部类只能访问局部的final变量
多态 成员变量不覆盖 方法覆盖
throw单独存在,下面不要定义语句,因为执行不到
多个catch时,父类的catch要放在下面
静态调用静态
catch块中有return仍然执行final语句
包(package)
1.对类文件进行分类管理
2.给类提供多层命名空间
3.写在程序文件的第一行
4.类名的全程的是 包名.类名。
5.包也是一种封装形式。
jar包
java的压缩包
方便项目的携带
方便与使用,只要在classpath设置jar路径即可
数据可驱动,SSH框架等都是以jar包体现
进程:是一个正在执行中的程序
每一个进程执行都有执行一个执行顺序。该顺序是一个执行路径,或者叫一个控制单元。
线程:就是进程总的一个独立的控制单元。
线程在控制者进程的执行。
一个进程中至少有一个线程。
java VM 启动的时候会有一个进程java.exe
该进程中至少一个线程负责java程序的执行。
而且这个线程运行的代码存在于main方法中
该线程称之为主线程。
扩展:其实更细节说明jvm,jvm启动不知一个线程,还有负责垃圾回收机制的线程。
1.如何自定义的代码中,自定义一个线程呢?
通过先侧滑盖的第一种方式,继承Thread类
步骤:
1.定义类继承Thread。
2.复写Thread类中的run方法
目的:讲自定义代码存储在run方法。让线程运行。
3.调用线程的start方法
该方法两个作用,启动线程,调用run方法。
发现运行结果每一次都不同。
因为多个线程都获取cpu的执行权。cpu执行到谁,谁就运行。
明确I点,在某一时刻,只能有一个承训在运行。(多核除外)
cpu在做着快速的切换,以达到看上去是同时运行的效果。
我们可以形象的吧多线程的运行行为在互相抢夺cpu的执行权。
这就是多线程的一个特性:随机性,谁抢到谁执行,至于执行多长,cpu说了算。
为什么要覆盖run方法?
Thread类用于描述线程。
该类就定义一个功能,用于存储线程要运行的代码,该存储功能就是run方法。
也就是说Tread类中的run方法,用于存储先策划概念要运行的代码。
执行状态:被创建 运行 阻塞 冻结 临时 消亡
原来线程都有自己默认的名称(. getname())
Tread-编号 该编号从0开始
Tread.currentTread()==this 前一种调用方式是通用的
static Thread crrentThread():获取当前线程对象。
getName():获取线程名称
设置线程名称:setName或者构造函数。
创建线程的第二种方式:实现Runnable接口
步骤:
1.定义类实现Runnable接口
2.覆盖Runnable接口中的run方法
讲线程要运行的代码存放在该run方法中。
3.通过Thread类建立线程对象。
4.讲Runnable接口的子类对象作为实际参数传递给Thread类的构造函数。
为什么要将Runnable接口的子类对象传递给Thread的构造函数。
因为,自定义的润方法所属的对象是Runnable接口的子类对象。
所以要让线程去指定对象的run方法,就鼻息明确该run方法所属对象。
5.调用Thread类start方法发开启线程并调用Runnable接口子类的run方法。
实现方式和继承方式有什么区别?
实现方式好处:避免了单继承的局限性。
在定义线程时,建议使用实现方式。
两种方式区别:
继承Thread:线程代码存放Thread子类run方法中。
实现Runnable,线程代码存在接口的子类的run方法。
问题的原因:
当多条语句在操作同一个线程共享数据时,一个下城对多条语句只执行了一部分,还没有执行完,
解决方法:
对多条操作共享数据的语句,只能让一个线程读执行完。在执行过程中,其他线程不可以参与执行。
java对于多线程的安全问题提供了
就是同步代码块
synchronized(对象)
{
需要被同步的代码
}
对象如同锁,持有锁的线程可以在同步中执行。
没有持有锁的线程即时获取cpu的执行权,也进不去,因为没有获取锁。
同步的前提:
1,必须要有两个或者两个以上的线程。
2,必须是多个线程使用同一个锁。
必须保证同步中只能有一个线程在运行
好处:解决了多线程的安全问题。
弊端:多个线程需要判断锁,较为浪费资源。
如何找问题:
1,明确哪些代码是多线程运行代码。
2, 明确共享数据
3,明确多线程运行代码中哪些语句是操作共享数据的。
同步函数:用synchronized 修饰即可
同步函数用的是哪一个锁呢?
函数需要被对象调用,那么函数都有一个所属对象引用。就是this
所以同步函数使用的锁是this
如果同步函数被静态修饰后,使用的锁是什么呢?
通过验证,发现不在是this,因为就能够台方法中也不可以定义this。
静态进内存时,内存中没有奔雷对象,但是一定有该类对应的字节码文件对象。
类名.class 该对象的类型是Class
静态的同步方法,使用的锁是该方法所在类的字节码文件对象。 类名.class
懒汉式:延迟加载
懒汉式:
class Single
{
private static Single s=null;
private Single(){}
public static Single getInstance(){
if(s==null){
synchronized(Single.class){
if(s==null){
s=new Single();
}
}
}
return s;
}
}
死锁
同步中嵌套同步,而锁不同