java新学者(二)
2021-01-16 04:16
标签:异常 模块 sys 条件 就会 nbsp 流向 内存 有一个 一。构造方法的特点 二。抽象类和抽象方法的特点是什么? 三。方法重载和方法重写是什么?有什么区别? 四。使用继承有什么特点?继承的优点是什么? 五。多态的特点?有什么优点? 六。多态的实现方式是什么? 七。如何编写接口? 八。接口的作用是什么? 九。接口和抽象类有什么异同? 十。什么是异常,你是如何理解的? 十一。如何处理异常,异常的关键字是什么? 十二。常见的异常的种类有哪些? 十三。如何使用log4j记录日志? 十四。常见的集合有哪些?他们有什么常用的方法 十五。list,set,map各有什么异同? 十六。和数组类型采用相同结构的是哪个集合? ArraysList 十七。什么是foreach循环? 十八。线程与进程的区别? 十九。实现线程有哪几种方法? 二十。线程的生命周期是什么? 二十一。简单解释一下线程休眠,线程强制执行,线程礼让以及他们的实现方法 二十三。什么是流?流的常见种类有哪些?使用流的过程中需要注意哪些问题? 二十四。脏读,虚读,不可重复读 java新学者(二) 标签:异常 模块 sys 条件 就会 nbsp 流向 内存 有一个 原文地址:https://www.cnblogs.com/304979850w/p/12928348.html创建新的对象
A a =new A ();
1.抽象类使用abstract修饰;
2、抽象类不能实例化,即不能使用new关键字来实例化对象;
3、含有抽象方法(使用abstract关键字修饰的方法)的类是抽象类,必须使用abstract关键字修饰;
4、抽象类可以含有抽象方法,也可以不包含抽象方法,抽象类中可以有具体的方法
5、如果一个子类实现了父类(抽象类)的所有抽象方法,那么该子类可以不必是抽象类,否则就是抽象类;
6、抽象类中的抽象方法只有方法体,没有具体实现
1.重写(override)是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!
2.重载(overloading)如果有两个方法的方法名相同,但参数不一致,哪么可以说一个方法是另一个方法的重载。
区别 :方法的重写(Overriding)和重载(Overloading)是java多态性的不同表现,重写是父类与子类之间多态性的一种表现,重载可以理解成多态的具体表现形式。
(1)方法重载是一个类中定义了多个方法名相同,而他们的参数的数量不同或数量相同而类型和次序不同,则称为方法的重载(Overloading)。
(2)方法重写是在子类存在方法与父类的方法的名字相同,而且参数的个数与类型一样,返回值也一样的方法,就称为重写(Overriding)。
(3)方法重载是一个类的多态性表现,而方法重写是子类与父类的一种多态性表现。
(1)继承关系是传递的。若类C继承类B,类B继承类A,则类C既有从类B那里继承下来的属性百与方法,也有从类A那里继承下来的属性与方法,还可以有自己新定义的属性和方法。继承来的属性和方法尽管是隐式的,但仍是类C的属性和方法。继承是在一些比较一般的类的基础上构造、建立和扩充新类的最有效的手段。
(2)继承简化了人们对度事物的认识和描述,能清晰体现相关类间的层次结构关系。 (3)继承提供了软件复用功能。若类B继承类A,那么建立类B时只需要再描述与基类(类A)不同的少量特征(数据成员和成员方法)即可。这种做法能减小代码和数据的冗余度,大大增加程序的重用性。
(4)继承通过增强一致性来减少模块间的接口和界版面,大大增加了程序的易维护性。权
(5)提供多重继承机制。从理论上说,一个类可以是多个一般类的特殊类,它可以从多个一般类中继承属性与方法,这便是多重继承。Java出于安全性和可靠性的考虑,仅支持单重继承,而通过使用接口机制来实现多重继承。
多态的定义:指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用)
作用:消除类型之间的耦合关系。
优点:1.可替换性:多态对已存在的代码具有可替换性。
2.可扩充性:多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。实际 上新加子类更容易获得多态功能。
3.接口性:多态是超类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。
4.灵活性:它在应用中体现了灵活多样的操作,提高了使用效率。
5.简化性:多态简化了对应用软件的代码编写和修改过程。
多态存在的三个必要条件
1. 要有继承;
2. 要有重写;
3. 父类引用指向子类对象。
[可见度] interface 接口名称 [extends 其他的接口名] {
// 声明变量
// 抽象方法
}
接口是隐式抽象的,当声明一个接口的时候,不必使用abstract关键字。
接口中每一个方法也是隐式抽象的,声明时同样不需要abstract关键字。
接口中的方法都是公有的。
是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。
接口可以被编写的多个程序重复调用,可以节省电脑的存储空间,并且使用接口可以减少电脑代码运行时出现的错误,在运行多个程序时,也能更有效率的进行。
1. 抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行。
2. 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的。
3. 接口中不能含有静态代码块以及静态方法(用 static 修饰的方法),而抽象类是可以有静态代码块和静态方法。
4. 一个类只能继承一个抽象类,而一个类却可以实现多个接口。
异常发生的原因有很多,通常包含以下几大类:
用户输入了非法数据。
要打开的文件不存在。
网络通信时连接中断,或者JVM内存溢出。
异常有三种
检查性异常:最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。(编码时的错误)
运行时异常: 运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。(运行完代码之后的错误)
错误: 错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的。
使用 try 和 catch 关键字可以捕获异常。try/catch 代码块放在异常可能发生的地方。
try/catch代码块中的代码称为保护代码
Catch 语句包含要捕获异常类型的声明。当保护代码块中发生一个异常时,try 后面的 catch 块就会被检查。
如果发生的异常包含在 catch 块中,异常会被传递到该 catch 块,这和传递一个参数到方法是一样。
1.NullPointerException: 空指针异常。
2.ClassCastException: 类型强制转换异常。
3.ArrayIndexOutOfBoundsException: 数组下标越界异常。
4.ArithmeticException:算术运算异常。
5.NumberFormatException: 数字格式异常。
6.ClassNotFoundException:不能加载所需的类
7.iIlegalArgumentException:方法接收非法参数
8.数组负下标异常:NegativeArrayException
9.违背安全原则异常:SecturityException
10.文件已结束异常:EOFException
11.文件未找到异常:FileNotFoundException
12.操作数据库异常:SQLException
13.输入输出异常:IOException
14.方法未找到异常:NoSuchMethodException
15.下标越界异常:IndexOutOfBoundsExecption
16.系统异常:SystemException
17.创建一个大小为负数的数组错误异常:NegativeArraySizeException
18.安全异常:SecurityException
19.不支持的操作异常:UnsupportedOperationException
第一步:在项目中加入log4j所使用的jar文件
首先在项目中创建一个lib文件夹,把该文件复制该文件中。然后对已经复制过来的jar包鼠标点击右键,选中BuildPath --------》Add to Build Path 然后你会在项目中看到多了一个引入外包的项目:Library
第二步:创建log4j.properties文件
选择要使用的log4j项目,点击src,依次选择New————》File---------New File--------》输入文件名,单击Finish按钮,结束创建。‘
第三步:编写log4j.properties文件,配置日志信息。
ArraysList
Boolean add (Object o)
Void add (int index, Object o)
Int size()
Object get(int index)
Boolean contains(Object o)
Boolean remove(Object o)
Object remove(int index)
LinkedList
void addFirst(Object o)
void addLast(Object o)
Object getFirst()
Object getLast()
Object removeFirst()
Object removeLast()
list:
1.可以允许重复的对象。
2.可以插入多个null元素。
3.是一个有序容器,保持了每个元素的插入顺序,输出的顺序就是插入的顺序。
4.常用的实现类有 ArrayList、LinkedList 和 Vector。ArrayList 最为流行,
它提供了使用索引的随意访问,而 LinkedList 则对于经常需要从 List 中添加或删除元素的场合更为合适。
set:
1.不允许重复对象
2. 无序容器,你无法保证每个元素的存储顺序,
TreeSet通过 Comparator 或者 Comparable 维护了一个排序顺序。
3. 只允许一个 null 元素
4.Set 接口最流行的几个实现类是 HashSet、LinkedHashSet 以及 TreeSet。
最流行的是基于 HashMap 实现的 HashSet;TreeSet 还实现了 SortedSet 接口,
因此 TreeSet 是一个根据其 compare() 和 compareTo() 的定义进行排序的有序容器。
map:
1.Map不是collection的子接口或者实现类。Map是一个接口。
2.Map 的 每个 Entry 都持有两个对象,也就是一个键一个值,Map 可能会持有相同的值对象但键对象必须是唯一的。
3. TreeMap 也通过 Comparator 或者 Comparable 维护了一个排序顺序。
4. Map 里你可以拥有随意个 null 值但最多只能有一个 null 键。
5.Map 接口最流行的几个实现类是 HashMap、LinkedHashMap、Hashtable 和 TreeMap。(HashMap、TreeMap最常用)foreach有的也叫增强for循环,foreach其实是for循环的一个特殊简化版
foreach适用于循环次数未知,或者计算循环次数比较麻烦情况下使用效率更高,但是更为复杂的一些循环还是需要用到for循环效率更高。
foreach适用于只是进行集合或数组遍历,for则在较复杂的循环中效率更高。
foreach不能对数组或集合进行修改(添加删除操作),如果想要修改就要用for循环。
线程:是进程的一个执行单元,是进程内科调度实体
进程:是并发执行的程序在执行过程中分配和管理资源的基本单位,是一个动态概念
1.一个线程只属于一个进程,但一个进程可以有多个线程
2.同一个进程的所有线程共享该进程的所有资源
十九。实现线程有哪几种方法
1.实现Runnable接口,并实现该接口的run()方法。
a 自定义类并实现Runnable接口,实现run()方法
b 创建Thread对象,用实现Runnable接口的对象作为参数实例化该Thread对象。
c 调用Thread的start()方法
2.继承Thread类,重写run方法
a继承Thread,重写run()方法
b创建一个MyThread实例
c执行start()方法
3.实现Callable接口,重写call()方法
Callable对象实际是属于Executor框架中的功能类,Callable接口与Runnable接口类似,但是提供了比Runnable更强大的功能,主要表现为以下三点:
a .Callable可以在任务结束后提供一个返回值,Runnable无法提供这个功能。
b.Callable中的call()方法可以抛出异常,而Runnable的run()方法不能抛出异常。
c.运行Callable可以拿到一个Future对象,Future对象表示异步计算的结果。它提供了检查计算是否完成的方法。
由于线程属于异步计算模型,所以无法从其他线程中得到方法的返回值,在这种情况下,就可以使用Futrue来监视目标线程调用call()方法的情况,
当调用Futrue的get()方法以获取结果时,当前线程就会阻塞,直到call()方法结束返回结果。
使用Callable接口实现线程的步骤如下:
(1)自定义类实现Callable接口,并实现该接口的call()方法;
(2)创建实现Callable接口的自定义类对象;
(3)创建执行服务;
(4)提交执行;
(5)获取结果;
(6)关闭服务。线程的生命周期包含5个阶段,包括:新建、就绪、运行、阻塞、销毁。
新建(new):就是刚使用new方法,new出来的线程;
就绪(runnable):就是调用的线程的start()方法后,这时候线程处于等待CPU分配资源阶段,谁先抢的CPU资源,谁开始执行;
运行(running):当就绪的线程被调度并获得CPU资源时,便进入运行状态,run方法定义了线程的操作和功能;
阻塞(blocked):在运行状态的时候,可能因为某些原因导致运行状态的线程变成了阻塞状态,比如sleep()、wait()之后线程就处于了阻塞状态,
这个时候需要其他机制将处于阻塞状态的线程唤醒,比如调用notify或者notifyAll()方法。唤醒的线程不会立刻执行run方法,它们要再次等待CPU分配资源进入运行状态;
死亡(dead):如果线程正常执行完毕后或线程被提前强制性的终止或出现异常导致结束,那么线程就要被销毁,释放资源;线程休眠(sleep):使一个线程暂时不需要处理,休眠到一定时间就会醒并继续执行,(我先睡一会儿,醒了再做事)定义方法如下:
1.休眠方法一:public static void sleep(long millis) throws InterruptedException;
2.休眠方法二:public static void sleep(long millis,int nanos) throws InterruptedException;
线程强制执行(join):当满足于某些条件之后,某一个线程对象可以一直独占资源,一直到该线程的程序执行结束(就是说某线程是vip通道,可以插队运行)
线程的礼让(yield):先将资源让出去让别的线程先执行,但每次礼让执行的时候只礼让一次。(你是老大你先走)
以线程A和线程B为例,在执行线程A的时候,
若使用了jon(),那么线程A就停止让线程B先执行,一直到线程B的所有程序执行完毕后才能继续执行线程;
若使用了yield(),那么线程A就停止让线程B执行,但是只会让线程B执行一次,然后继续执行线程A的程序。
流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。它的特性是进行数据传输;
1) 根据数据的流向来分:
输出流:是用来写数据的,是由程序(内存)--->外界设备。
输入流:是用来读数据的,是由外界设备--->程序(内存)。
2) 根据流数据的格式来分:
字节流:处理声音或者图片等二进制的数据的流,比如 InputStream;
字符流:处理文本数据(如txt文件)的流,比如 InputStreamReader ;
java几种常见的类型的流。
对于字节流而言:主要继承的抽象类为 InputStream和OutputStream
对于字符流而言:主要继承的抽象类为 InputStreamReader和OutputStreamWriter
字节流与字符流之间的区别:
1.读写单位不同:字节流式以字节(8位2进制)为单位,字符流是以字符为单位,根据码表映射字符,一次可能读多个字节。
2.处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。
3.一次读入或读出是8位二进制。
4.字符流:一次读入或读出是16位二进制。
使用流注意事项 :涉及创建IO流,记得关流,否则数据更改无效。
脏读:
所谓的脏读,其实就是读到了别的事务回滚前的脏数据。比如第一人买了一张票修改了票数,在未提交前,第二人去买了票,而第一人放弃了买票,这样第二人就形成了脏读。
不可重复读:
事务A首先读取了一条数据,然后执行逻辑的时候,事务B将这条数据改变了,然后事务A再次读取的时候,发现数据不匹配了,就是所谓的不可重复读了。
比如:只剩最后一张票了,A正在购买,但B的速度比A快,事先完成操作,所以A没买成票了。这就是不可重复读,
虚读(幻读):
所谓幻读是指同一个事务内多次查询返回的结果集不一样
比如同一个事务A内第一次查询时候有n条记录,但是第二次同等条件下查询却又n+1条记录,这就好像产生了幻觉,为啥两次结果不一样那。
其实和不可重复读一样,发生幻读的原因也是另外一个事务新增或者删除或者修改了第一个事务结果集里面的数据。不同在于不可重复读是同一个记录的数据内容被修改了,幻读是数据行记录变多了或者少了: