JDK1.5之后的3大版本
1.java SE(J2SE,Java 2 Platform Standard Edition,标准版)
2.Java EE(J2EE,Java 2 Platform Enterprise Edition,企业版)
3.Java ME(J2ME,Java 2 Platform Micro Edition,微型版)
Java数据类型
两大类:基本数据类型/引用数据类型
基本数据类型(8个):int(4), long(8), byte(1), sort(2), double(8), float(4), char(2), boolean(4)
引用数据类型(3个):数组,类,接口,枚举
int 是基本数据类型,Integer 是引用数据类型,包装类
int :必须赋值,默认为0,不赋值会编译错误
Integer :可以不赋值,默认为null
String 是一种引用数据类型,被 final 关键字修饰,不可以被继承
Java数据类型转换关系
1.向上转型:自动转型(小范围到大范围)
当小范围的数据类型赋值给一个大范围时,Java会自动进行隐式转化
byte>sort>int>long>float>double
char>int
2.向下转型:强制转型(大范围到小范围)
大范围数据类型赋值给小范围数据类型时,需要进项显式转化,会导致精度丢失
Java运算中 i++和++i区别
i++先赋值后运算,数据使用后进行自增
先将值赋值给result后再进行自增
int i = 5;
int result = i++;
System.out.println(i); // 输出:6
System.out.println(result); // 输出:5
++i先运算后赋值,数据使用前进行自增
先再进行自增后将值赋值给result
int i = 5;
int result = ++i;
System.out.println(i); // 输出:6
System.out.println(result); // 输出:6
Java运算中位运算 2的3次方
使用左操作符 << 将 2先左移动3位,相当于2的3次方
2<<3 相当于 2的3次方
2<<4相当于 2的4次方
4<<5 相当于 4的5次方
Java循环,跳出嵌套循环
关键字 break
单层循环:直接在结尾加break
多层循环:如果是多层循环语句,想跳出在那一层循环语句,则在那一层做个标记,例如标记为 ok; 然后使用关键字 break ok;
JVM内存回收机制
JVM即Java虚拟机(Java Virtual Machine),目前Java的JDK默认虚拟机是HotSpot
GC(Garbage Collection) ,系统的内存是有限的,一旦超过内存限制,就无法向其中添加对象,于是JVM提供了一种垃圾回收机制,分代回收算法,回收无用的系内存空间,提高系统的运行性能
GC通过分代回收算法来判断对象是否存活来决定是否进行回收:判断对象是否存活主要有两种算法,引用计数器算法,可达性分析算法
引用计数器算法:原理是向对象中添加一个计数器,每次被引用一次这则计数器加一,引用失效后则减一,当计数器为0时,表示对象没被引用,可以被回收。虽然简单高效,但是对象存在循环引用的问题,导致无法被GC回收,需要花大量的时间去解决这个问题
可达性分析算法:原理是通过遍历搜索所有从根引用出发的可达对象,在遍历的同时标记可达对象和不可达对象形成一个引用链,不可达对象表示没有任何引用指向该对象,可以被回收,该算法不受循环的问题影响,可以准确的判断出对象的存活状态。
Java几种常见的排序算法
冒泡排序、选择排序、插入排序、快速排序、归并排序、计数排序,桶排序、希尔排序
冒泡排序:通过重复比较相邻的两个元素,将较大(小)的元素向后移动,直到有序
选择排序:每一次从未排序的部分选取最大(小)的元素放到已排序部分的末尾
面向对象的基本特征
封装,继承,多态,抽象
封装:私有化属性,对外提供 接口进行交互,隐藏内部结构细节
继承:Object是基类,子类可以继承父类,重写父类的方法
多态:一个方法名在不同的类中有不同的行为,提高了代码的灵活性
抽象:通过定义一个抽象类或者接口,强调特性和行为,不关心具体实现
多态的好处
灵活性和扩展性,新增的子类不会影响不会影响已经存在的类的的多态性、继承性,
可替换性,多态对已存在代码具有可替换性
统一的接口,多态使得不同的对象可以共享同一套接口,从而降低了代码的耦合度。
代码简洁性:通过多态,可以使用更简洁、更通用的代码来处理多种不同的对象。
Java关键字 exends和implement
Java中只支持单继承,但是接口可以多继承,接口与接口不能实现
extends:继承类,子类只能继承一个父类的方法和属性,并且可以在继承的基础上添加新的方法 和属性,还可以重用(overrider)和重载(overload)父类的方法;
implement:实现接口,接口是抽象的类型,可以实现多接口,但是必须实现接口中的方法,
Java关键字 重载(overload)和重写(override)
overload:子类与父类中,方法名相同、参数列表不同、返回值无关、异常无关、访问修饰符无关
override:方法名相同、参数列表相同、返回值类型相同、访问修饰符不能比父类小,抛出的异常 不能比父类大
Java关键字 super()和this()
super()方法必须写在子类构造方法的第一行,否则编译不通过,调用的是父类的构造方法
this()方法必须在当前构造方法的第一行,调用本类的其他构造方法,以避免重复代两者都是指 对象,不能在static环境中使用,不能同时出现在一个构造方法中
Java关键字 final
final关键字修饰类、属性、方法
final修饰的类不能被继承
final修饰的变量称为常量,值不可变,,一般结合static使用,称为静态常量,不会被回收
final修饰的方法不能被重写
Java关键字 static
static关键字可以修饰变量,方法,代码块,类
修饰变量:修饰后的变量称为静态变量,静态变量共享一片内存,可以直接用类名调用,用new关 键字每次创建新的对象都会分配新的内存空间,但是static修饰后,不会再分配新的内 存空间,与之前的对象共享一片内存空间
修饰方法:修饰后的方法称为静态方法,可以通过类名直接调用,静态方法只能用静态变量,不 能使用super、this关键字,不能被重写
修饰代码块:静态语句块,最早被执行且只执行一次
修饰类:静态内部类,静态内部类定义做类体中,直接可以用主类调用
String 和 StringBuffer 的 区 别 ?
- 可变性:
String是不可变的类,一旦创建了String类它的值就无法修改,对String进行的一系列操作都会创建 一个新的String对象,导致内存消耗较大
StringBuffer是可变的类,可以对其进行修改,不会创建新的对象,在需要频繁修改字符串的情况 下,StringBuffer是一个更好的选择
- 线程安全性:
String线程是安全的,多个线程共享一个String对象
StringBuffer线程是也是安全的,它的方法都有同步锁(synchronized)修饰,保证了多个线程操作同一个对象的线程安全
- 性能
String需要频繁的创建对象,所以内存开销比较大和垃圾回收压力增大
StringBuffer不需要频繁创建对象,在原有的对象上进行修改,速度较快
StringBuffer 和 StringBuilder 区别?
StringBuffer:线程安全,方法有同步锁,适合多线程
StringBuilder:线程不安全,适合单线程,在单线程下效率高
异常类型
异常基类主要分为两种异常:Error和 Exception
Error:程序不能正常运行,程序本身无法解决,例:内存不够,磁盘空间不足
Exception:可以正常运行,可以捕获的异常,自身可以解决
CheckedException:检查异常,程序编写的异常,必须捕获
RunTimeException:运行时异常,运行时发送的异常,可以不捕获
空指针异常(NullPointerException)
数组下标越界异常(ArrayListIndexOutBoundException)
类找不到异常(ClassNotFoundException)
类型转化异常(ClassCastException)
数字转化异常(NumberFormatException)
运算异常(ArithmeticException)
数据操作异常(SQLException)
文件找不到异常(FileNotFoundException)
输入输出异常(IOException)
实例化异常(InstantiationException)
异常处理流程
try:放置可能发生异常的代码
catch:捕获并处理特定的异常类型,可以设置多个catch来处理不同的异常。没一个catch处理一 种特定的异常,并提供相对应的逻辑
finally:无论有没有异常finally块都要执行的代码,总是会被执行
throw:用于手动抛出一个实际的异常,可以作为一个单独的语句,抛出一个具体的异常对象
throws:在方法签名中,用于声明该方法可能会抛出的异常
异常中 try {}中有一个 return
当在try
块中遇到return
语句时,紧跟在try
后的finally
块中的代码仍然会被执行。finally
块中的代码在return
语句之前执行。
当在finally
块中存在return
语句时,它会覆盖掉之前的try
块或catch
块中的返回语句。也就是说,finally
块中的return
语句将决定最终的方法返回值。
数组的特点
同一种类型
固定长度
有序排列
静态分配
List 的遍历方法
下标遍历,使用for循环遍历
迭代器遍历,用List的iterator()方法获取迭代器对象
Foreach遍历,增强型for循环遍历
List 和Map
List:有序可重复,单列数据的集合
Map:无序的键值对,key不可重复,value可重复,双列数据的集合
ArrayList和LinkedList
ArrayList:底层是动态数组,
LinkedList:底层是双向链表,
在插入和删除数据时,ArrayList需要移动其他元素保存连续性,比较耗时,LinkedList在插入和修改数据时只需要修改节点之间的引用,所以在列表中间进行插入和删除会比较高效
随机访问性,ArrayList是基于数组实现,可以通过索引来快速访问元素,支持高效的数据访问,而LinkedList访问元素需要经过遍历从节点头或者节点尾开始遍历,比较耗时,效率不高
内存占用,ArrayList基于数组实现,会预留一定的内存空间,当元素数量超过限制后需要进行扩容。而LinkedList需要存储每一个元素的前后引用,会占用更多的内存空间
迭代器性能,LinkedList在使用迭代器进行遍历的性能更高,可以从任意位置开遍历,而ArrayList则需要通过索引来进行访问元素,效率稍低
ArrayList 和 Vector
ArrayList:初始化长度为0,添加元素后长度为10,当超过10后,依次扩容15.20,25,30
Vector:初始化长度为10,添加元素后长度为10,超过10后,依次扩容20,30,40
ArrayList线程不安全任意引发多线程的并发安全问题,
Vector线程更加安全,方法都是同步的,可以在多线程下使用,性能开销较大