标签:封装 调度 面向对象编程 包装类 时间 结构 也有 注意 需要
前言在之前Java基础知识回顾中,我们回顾了基础数据类型、修饰符和String、三大特性、集合、多线程和IO。本篇文章则对之前学过的知识进行总结。除了简单的复习之外,还会增加一些相应的理解。
基本数据类型主要有:
byte、short、int、long、float、double、char、boolean
它们可以分为三类:
其中byte是8位,short是16位, int是32位以及 long是64的整数;而float 32位,double 64 位的浮点数。
数值类型的级别从低到高分别为:
byte,char,short(这三个平级)——>int——>float——>long——>double
其中由低级别转到高级别,是属于自动类型转换,这点是由系统自动转换的。在进行计算的时候,如果级别小于int,最终的数据类型会自动转换为int,如果高于int,最终数据结果会取其中最高的一个。
又高级别转到低级别是强制类型转换。强制类型转换需要注意取值范围和数据的精确度。
char是字符类型,可以储存任何字符。
boolean是布尔类型,只有false或true。
基础数据类型更详细的说明:http://www.panchengming.com/2018/03/18/pancm76/
一般我们在用基础数据类型的时候,也会用到包装类型。
这里顺便说下包装类型,也来弥补之前的文章讲述不足。
什么是包装类型?包装类型和基础数据类型的关系。
包装类就是基本类型数据转换为对象的一种类型。
每个基本类型在java.lang包中都有一个相应的包装类。
基础数据类型:
boolean, char, byte,short,int, long, float,double
分别对应的包装数据类型:
Boolean,Character,Byte,Short,Integer,Long,Float,Double
包装类型有什么用?
利于实现基本类型之间的转换;
因为我们了解到基本数据类型之间的相互转换分为自动类型转换和强制类型转换,自动类型转换还好,但是强制类型转换容易出现问题。所以出现了包装类型,它可以很方便的帮助转换。
例如: String类型的转int类型可以通过 Integer.parseInt()转换成int,或使用Integer.valueOf()转换成Integer类型。
Map<String,Integer> map=new HashMap<String,Integer>();
注意:在使用包装数据类型进行值比较的时候,用equals进行比较,不要用==。例如:
Integer a=127;
Integer b=127;
Integer c=128;
Integer d=128;
System.out.println(a == b);
System.out.println(a.equals(b));
System.out.println(c == d);
System.out.println(c.equals(d));
输出结果:
true
true
false
true
Java修饰符主要分为两类:
其中访问修饰符主要包括 private、default、protected、public。
非访问修饰符主要包括 static、final、abstract、synchronized。
访问修饰符的访问权限: |
修饰符 | 当前类 | 同一包内 | 子类 | 其它包 |
---|---|---|---|---|---|
public | Y | Y | Y | Y | |
protected | Y | Y | Y | N | |
default | Y | Y | N | N | |
private | Y | N | N | N |
static: 用来修饰类变量和类方法。
修饰变量
static在修饰类变量的时候,无论该类被实例化了多少次,它的静态变量只有一份拷贝。静态变量也被称为类变量。局部变量是不能被声明为static变量的。
修饰方法
static在修饰类方法的时候,静态方法是不能使用类的非静态变量。静态方法可以直接通过类名调用,因此静态方法中是不能用this和super关键字的。
final :用来修饰类、方法和变量。
final 修饰的类不能够被继承,修饰的方法不能被继承类重新定义,修饰的变量为常量,是不可修改的。
abstract :用来创建抽象类和抽象方法。
修饰类
会使这个类成为一个抽象类,这个类将不能生成对象实例,但可以做为对象变量声明的类型(见后面实例),也就是编译时类型。抽象类就相当于一类的半成品,需要子类继承并覆盖其中的抽象方法。
修饰方法
会使这个方法变成抽象方法,也就是只有声明而没有实现,需要子类继承实现。
synchronized: 修饰的方法同一时间只能被一个线程访问。
transient:被 transient 修饰的实例变量时,java 虚拟机(JVM)跳过该特定的变量。
native: 被native修饰的方法实际是由另一种语言进行实现的本地方法
修饰符更详细的说明:http://www.panchengming.com/2018/03/24/pancm77/
封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。要访问该类的代码和数据,必须通过严格的接口控制。
使用封装的好处
良好的封装能够减少耦合。
类内部的结构可以自由修改。
可以对成员变量进行更精确的控制。
继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
优缺点
虽然继承大大提升了代码的复用性,但是也提高了类之间的耦合性!
多态是指事物在运行过程中存在不同的状态。
多态的优点
三大特性更详细的说明:http://www.panchengming.com/2018/03/24/pancm78/
List 接口是继承于 Collection接口并定义 一个允许重复项的有序集合。该接口不但能够对列表的一部分进行处理,还添加了面向位置的操作。
推荐单线程使用ArrayList进行查询和遍历,LinkedList进行插入和删除。
多线程使用Collections.synchronizedList方法对List上锁,效率比Vector高。
Map 接口并不是 Collection 接口的继承。Map提供key到value的映射。一个Map中不能包含相同的key,每个key只能映射一个value。Map接口提供3种集合的视图,Map的内容可以被当作一组key集合,一组value集合,或者一组key-value映射。
推荐单线程随机查询用HashMap,自然顺序或自定义顺序用TreeMap,插入和删除用LinkedHashMap。
多线程推荐使用ConcurrentHashMap。
Set是一种不包含重复的元素的Collection,即任意的两个元素e1和e2都有e1.equals(e2)=false,Set最多有一个null元素。因为Set是一个抽象的接口,所以是不能直接实例化一个set对象。
Set s = new Set()
这种写法是错误的。
推荐单线程随机查询用HashSet,自然顺序或自定义顺序用TreeSet,插入和删除用LinkedHashSet。
集合更详细的说明:http://www.panchengming.com/2018/04/19/pancm80/
多线程是指在同一程序中有多个顺序流在执行。 简单的说就是在一个程序中有多个任务运行。
创建(new)状态: 准备好了一个多线程的对象
就绪(runnable)状态: 调用了start()方法, 等待CPU进行调度
运行(running)状态: 执行run()方法
阻塞(blocked)状态: 暂时停止执行, 可能将资源交给其它线程使用
终止(dead)状态: 线程销毁
注:线程启动的方法是start而不是run。
推荐创建单线程的时候使用继承 Thread 类方式创建,多线线程的时候使用Runnable、Callable 接口的方式来创建创建线程。
多线程更详细的说明:http://www.panchengming.com/2018/05/28/pancm84/
多线程中经常会使用这几个关键字synchronized、lock和volatile。
synchronized: synchronized是JVM级别的,也就是在运行期由JVM解释的。它是阻塞锁(也就是在同一时间只会有一个线程持有);也是非公平锁(也就是不遵循先来后到的原则,当一个线程A持有锁,而线程B、C处于阻塞状态时,若线程A释放锁,JVM将从线程B、C随机选择一个线程持有锁并使其获得执行权)。可以保证原子性、可见性以及有序性。
lock: lock是通过编码实现的。它是非阻塞锁;也是公平锁。可以保证原子性、可见性以及有序性。相比synchronized,更加灵活和强大。
volatile:轻量级的锁。主要用户保证共享变量对所有线程的可见性,以及禁止指令重排序)。因为无法保证原子性,所以并不能保证线程安全。
线程安全与共享资源
1.局部变量中的基本数据类型(8种)永远是线程安全的。
2.局部变量中的对象类型只要不会被其他线程访问到,也是线程安全的。
3.一个对象实例被多个线程同时访问时,他的成员变量就可能是线程不安全的。
IO的名称又来是Input与Output的缩写,也就是输入流和输出流。输入流用于从源读取数据,输出流用于向目标写数据。
字符流有两个抽象类:Writer和Reader类。
其对应子类FileWriter和FileReader可实现文件的读写操作。
BufferedWriter和BufferedReader能够提供缓冲区功能,用以提高效率。
字节流也有两个抽象类:InputStream和OutputStream类。
其对应子类有FileInputStream和FileOutputStream实现文件读写操作。
BufferedInputStream和BufferedOutputStream提供缓冲区功能
推荐读取文本用字符流,读取图片、视频和图片等二进制文件用字节流。
IO流更详细的说明:http://www.panchengming.com/2018/06/16/pancm85/
说起IO流,顺便谈下它的几个孪生兄弟,NIO、BIO和AIO。
IO:
阻塞的,从硬盘读取数据时,程序一直等待,数据读完在继续操作 。
操作时一次一个字节的读取数据,一个输出流一次输出一个字节数据,一个输出流一次消耗一个字节数据,数据的读取和写入效率不好。
I/O属于底层操作,性能依赖与系统环境。
NIO:
同步非阻塞I/O,在读取数据时程序可以继续执行,读取玩数据以后,通知当前程序(即硬件的中断,软件中的回调),然后程序立即或执行完后处理数据。选择器(selector)、缓冲(buffer)、管道(channel) 面向块(缓冲区)。采取“预读方式”。操作中一步产生或消费一个数据块,按块处理数据,同时数据读取到一个稍后可能会处理的缓冲区,需要时也可在缓冲区前后移动。
方式适用于连接数目多且连接比较短(轻操作)的架构。例如聊天工具。毕竟好用的框架Netty和Mina。
BIO:
同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。
方式适用于连接数目比较小且固定的架构
AIO:
异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理.。
方式使用于连接数目多且连接比较长(重操作)的架构。
简单的介绍了下这些知识。详细的可以查看这篇文章:https://blog.csdn.net/huangwenyi1010/article/details/75577091?ref=myread
Java基础知识的总结篇就介绍到这里了,以后的博文主要编写的方向是Java的进阶知识了,主要内容为设计模式,源码解析和并发编程这块吧!至于后面的这些博文没有信心能够写好,毕竟这些相对于来说还是比较难以理解的。所以以后的这些相关博文我会按照自己的理解写的,如果写的不好,还请多多指点!
原创不易,如果感觉不错,希望给个推荐!您的支持是我写作的最大动力!
版权声明:
作者:虚无境
博客园出处:http://www.cnblogs.com/xuwujing
CSDN出处:http://blog.csdn.net/qazwsxpcm
个人博客出处:http://www.panchengming.com
标签:封装 调度 面向对象编程 包装类 时间 结构 也有 注意 需要
原文地址:http://blog.51cto.com/12965378/2322916