Java是什么
java是一门高级编程语言,以C++为基础建立,但不仅吸收了C++语言的各种优点,还在此基础上有很多改进,抛弃了C++中难以理解的多继承和指针等要素,还加入了GC机制,解决了程序员每次都需要手动释放内存的问题。
java功能强大且简单易用,一次编写,到处运行。
Java的特点
面向对象(简述特点)
- 封装: 把描述一个对象的属性和行为的代码封装在一个模块中,也就是一个类中,属性用变量定
义,行为用方法进行定义,方法可以直接访问同一个对象中的属性。 - 抽象: 把现实生活中的对象抽象为类。分为过程抽象和数据抽象
数据抽象 -->鸟有翅膀,羽毛等(类的属性)
过程抽象 -->鸟会飞,会叫(类的方法) - 继承:子类继承父类的特征和行为。子类可以有父类的方法,属性(非private)。子类也可以对父
类进行扩展,也可以重写父类的方法。缺点就是提高代码之间的耦合性。 - 多态: 多态是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程
时并不确定,而是在程序运行期间才确定(比如:向上转型,只有运行才能确定其对象属性)。方法
覆盖和重载体现了多态性。具体体现在父类引用变量可以指向子类变量。
平台无关性
java借助其虚拟机的优越性,java编译后的文件可以在各个平台和操作系统的虚拟机上运行,java屏蔽了平台的相关特性,只需要生成对应平台的代码,就能在虚拟机上运行。
可编译,可解释执行
java在执行时,会根据使用频率将部分热点代码切换成编译执行,而大部分代码仍然是解释执行,以此就可以将两种执行方式的优势结合,达到更高的运行效率。
多线程
java支持通过Thread类和它的多个子类进行多线程运行,执行方法写在run()方法内。
安全性
java支持应用在多种Internet场景中,java提供了很多安全机制,无指针运算,异常抛出,自动GC等,java也支持从网络上下载其他的类来帮助做安全的支持。
JDK,JRE,JVM
JDK包含JRE的所有组件以及development kit,development kit提供java的运行环境。
JRE包含JVM和java的核心类库。
而JVM是java的虚拟机,是java实现跨平台的核心,只要在不同平台上实现了相同的虚拟机,同样的代码编译为字节码文件后,跑在虚拟机上就能实现相同的运行结果。
自动装箱与自动拆箱
java中对基本数据类型实现了包装类,并且为我们实现了自动装箱和自动拆箱
public class Main {
public static void main(String[] args) {
//自动装箱
Integer total = 99;
//自定拆箱
int totalprim = total;
}
}
不过,这里我们需要了解一下自动装箱和自动拆箱的源码
通过字节码文件能够知道,自动装箱调用了ValueOf方法,而自动拆箱调用了intValue方法
那么针对如下代码
public class Main {
public static void main(String[] args) {
Integer i1 = 100;
Integer i2 = 100;
Integer i3 = 200;
Integer i4 = 200;
System.out.println(i1==i2); //true
System.out.println(i3==i4); //false
}
}
public static Integer valueOf(int i) {
return i >= 128 || i < -128 ? new Integer(i) : SMALL_VALUES[i + 128];
}
ValueOf方法中,逻辑如下,判断装箱的int值是否在-128~127之间,如果在,则直接返回一个系统建立好的数组中对应的Integer对象,SMALL_VALUES其实就是一个Integer[256],里面装着系统建立好的256个Integer对象;如果不在,就直接新建一个Integer对象返回。
也就是说,上述例子,i1和i2的引用指向了同一个对象,也就是系统建好的Integer(100),但i3和i4返回地是各自新建的Integer对象。
同类的类型还有Short,Byte,Long,Character,这个阈值都是-128~127
同理,boolean类型只有两种情况,返回地也是系统创建好的对象。
public class Main {
public static void main(String[] args) {
Double i1 = 100.0;
Double i2 = 100.0;
Double i3 = 200.0;
Double i4 = 200.0;
System.out.println(i1==i2); //false
System.out.println(i3==i4); //false
}
}
但浮点数,由于-128~127中间有无数个浮点数,显然没法像上述做法一样做,所以Double和Float的ValueOf做法很简单,就直接返回一个新建的对象。
为什么要使用包装类
很简单,因为需要让基本数据类型也具备对象的特征,比如我们使用容器,都是装Object的,所以要装基本数据类型就都得装包装类。
a=a+b和a += b有什么区别?
+=操作符会隐式的进行强制类型转换,而正常加法不会,所以类型不一致时会报编译错误。
Java中final和static的用法和区别
final
final可以修饰类,类属性和类方法,基本功能就是修饰的内容不可被修改,final修饰的变量如果是引用类型,引用不可变,引用内容可变,final修饰的类不可被继承,方法不可被重写,final修饰的常量在编译阶段就会存入常量池。
static
static表示静态,可以修饰类,内部类,属性,方法,代码块,静态内容会随着类一起优先加载,修饰代码块可以用于初始化,会被优先加载,还可以用于静态导包。
序列化和序列化接口的作用
Serializable接口,我理解就是一种标注,它是一个mini接口,它并没有任何实现方法,但如果我们要把它转化为字节流或者要在网络中传输或者要持久化,就要实现他才可以做。
内部类
定义在外部类的里面的类
1.成员内部类
2.局部内部类
3.匿名内部类
4.静态内部类
当成员内部类具有与外部类同名的方法和变量时,默认访问成员内部类的。
静态内部类不依赖内部类而实例,不能访问普通成员变量,但是可以访问静态变量和方法。
Java中的异常处理机制
根类为Throwable,下面分为两个子类Error和Exception
异常分为系统异常和普通异常,系统异常主要指软件本身缺陷带来的问题,是程序员考虑不周导致的
普通异常指用户运行环境变化带来的异常,如网络,这时程序不应该崩溃。
error指依靠程序本身无法处理的问题,如内存溢出等
hashCode
散列存储,hashMap和hashSet的核心就是拉链法的散列查找,依靠hash算法给每个存储的值计算出一个哈希值,确定他的存储位置,计算结果相同的值就用拉链法往下接。
Java创建对象有几种方法
new一个
通过反射
通过clone
通过序列化
迭代器中删除元素
public class Test {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(2);
Iterator<Integer> iterator = list.iterator();
while(iterator.hasNext()){
Integer integer = iterator.next();
if(integer==2)
list.remove(integer);
}
}
}
上述代码是有问题的,因为在迭代器中删除元素不能用list.remove()方法,会引发ConCurrentModificationException异常,因为list删除后会使得list中数量出现不一致的问题,抛出异常,删除要用iterator.remove()方法。
HashMap,HashTable,ConcurrentHashMap
相同点:
HashMap和HashTable都实现了Map接口
都存储key-value数据
不同点:
HashMap线程不安全,效率高,HashTable线程安全,效率低
HashMap的迭代器优先抛出异常而非程序执行,HashTable不是这种策略。
ConcurrentHashMap是HashTable的替代品,将整个Map分为N个segment,可以提供相同的线程安全但效率提升N倍。
HashMap底层:
插入时采用的是拉链法的散列存储
添加元素时:
判断目标地址是否为空,如果为空,直接添加
如果不为空,判断地址上的值的hash值和添加元素的hash值是否相同,如果不同,直接添加(往下拉链)
如果相同,则新值替换原值
loadFactor 负载因子 默认0.75
假如时,如果占用长度比例超过负载因子,就会扩容,16,32,64,当链表长度达到64以上时,就会直接改为红黑树存储。
BIO,NIO与AIO
BIO:指Block IO,也称作同步阻塞式IO,就是传统的IO模式,特点是简单使用方便,但并发处理能力很低。
NIO:Non IO,也称作同步非阻塞IO,是BIO的升级,客户端和服务端通过Channel通信,期间先是采用轮询的方式,减少线程抛出,但这样仍会造成用户态和内核态的频繁切换,所以又加入了多路复用,一次打包很多个请求,减少fd的频繁复制。
AIO:Asychronous IO,是NIO的升级,也成为NIO2,实现了异步非阻塞IO,主要基于事件和回调机制。
Files的常用方法
Files. exists():检测文件路径是否存在。
Files. createFile():创建文件。
Files. createDirectory():创建文件夹。
Files. delete():删除一个文件或目录。
Files. copy():复制文件。
Files. move():移动文件。
Files. size():查看文件个数。
Files. read():读取文件。
Files. write():写入文件。
反射
首先要获取Class对象
1.Class.forName()
2.类名.class
3.对象名.getClass()
4.包装类.Type
之后可以使用这个clazz来进行属性、方法的调用,对任意个对象都能任意调用它的任意一个方法
优点:
运行时动态获取类的实例,灵活性强
缺点:
需要解析字节码文件,效率低
相对不安全,能访问私有属性和方法