哈哈,标题党让在座各位点进来了,别急着走,多学习点知识。这几天闲来无事,看了看java基础,写了点自己总结,发出来供大家一起学习!!!欢迎评论区说出我的不足
java基础
1、环境和环境变量
1、JVM、JRE和JDK的区别:
JVM(Java Virtual Machine):java虚拟机,用于保证java的跨平台的特性。
java语言是跨平台,jvm不是跨平台的。
JRE(Java Runtime Environment):java的运行环境,包括jvm+java的核心类库。
JDK(Java Development Kit):java的开发工具,包括jre+开发工具
2、环境变量path和classpath的作用是什么?
(1)path是配置Windows可执行文件的搜索路径,即扩展名为.exe的程序文件所在的目录,
用于指定DOS窗口命令的路径。
(2)Classpath是配置class文件所在的目录,用于指定类搜索路径,JVM就是通过它来寻找该类的class类文件的。
3、类加载过程
将人能看懂的java文件编译成class文件 ,使用了javac编译器。
-
将class文件加载到内存,生成一个Class对象。
以上是一个静态过程,文件的内容没有变化
4、数据类型
基本数据类型
//整数类型
byte 1个字节
short 2个字节
int 4个字节
long 8个字节
//浮点数类型
float 4个字节
double 8个字节
//布尔类型
boolean 一个字节
//字符类型
char 两个字节
//引用数据类型
类、接口、数组
//精度从高到低
double float long int short(char) byte
自动类型转换:低精度到高精度
强制类型转换:高精度到低精度
5、定义变量
变量的作用
用来存储数据
为什么要定义变量
用来不断的存放同一类型的常量,并可以重复使用
什么时候定义变量?只要是数据不确定的时候,就定义变量
过程
定义 int i;
赋值 i = 5; 定义和赋值可以一起 int i = 5;
使用;
成员变量和局部变量区别
1、作用域
成员变量:针对整个类有效
局部变量:只在某个范围内有效(一般指的方法体,语句体内)
(2)存储位置
成员变量:随着对象的创建消失而存在消失,存储在堆内存
局部变量:在方法被调用,或者语句被执行时存在,存储在栈内存
(3)初始值
成员变量:有默认初始值。0
局部变量:没有默认初始值,使用前必须赋值。null
2、概念:
成员变量:在类中定义,用来描述对象将要有什么
局部变量:在类的方法中定义,在方法中临时保存数据
public class Telephone{
//成员变量
//变量1 类型 变量1;
float cpu;
float sceen;
int var;
public 返回类型 方法1(){
//局部变量
变量2 类型 变量3;
System.out.println(var)
//局部变量
int localVar = 5;
}
}
6、运算符
布尔运算
与 &: 串联
或 | :并联
非 !
&& 双语: 如果是false 直接 结果就是false
|| 双或 : 如果是true 直接 结果就是true
^ 异或: 和或有点不一样。 两边结果一样,就为false。 两边结果不一样,就为true.
算术运算符
+ - * / % ++ -- += -=
i++ 与 ++i
i++ 与 ++i 的主要区别有两个:
1、 i++ 返回原来的值,++i 返回加1后的值。
2、 i++ 不能作为左值,而++i 可以。
1、a = i++; 等校为
a = i;
i = i + 1;
2.a = ++i; 等校为
i = i + 1;
a = i;
例如:int i=2,a;
a = i++; a 为2
a = ++i; a 为3
数组
含义
同一种数据类型的集合。
好处
可以自动给数组中的元素从0开始编号,方便操作这些元素。
定义数组
类型[] 取得名字 = new 类型[长度];
int[] array = new int[10];
定义及初始化
int[] array = new int[]{1,2,3};
int[] array = {1,2,3};
使用
1、打擂台的形式找最大值
2、循环遍历打印数组的每一个值
3、查找数组里存在的值
4、元素的位移
5、选择排序法
6、冒泡排序法
7、结构语句
switch:不支持lon
switch(条件){
case 条件1:
break;
..................
default:
break;
}
基础类型不能是long型 可以 byte short int
String(String不是基础类型)
for循环
定义条件变量 进入条件 ; 变量改变
自增为了达到退出条件
while和do while
区别
do while无论如何都要先执行一下,然后才去判断
while 满足条件才能进入
while(条件){}
do{
...
}
while(条件)
关键字
break
无论如何都要结束当前的全部循环,程序会继续向下执行。
contiune
跳过本次循环继续下一次循环。
打标签
for循环可已打标签,使用break + 标签名可以 退出 被打标签的循环
8、三目运算符
条件 ? 结果1 : 结果二;
如果为true,执行结果1,否则执行结果2
9、内存结构
栈内存:用于存储局部变量,当数据使用完,所占空间会自动释放。
堆内存:数组和对象,通过new建立的实例都存放在堆内存中。
方法区:静态成员、构造函数、常量池、线程池
本地方法区:window系统占用
寄存器:
栈:先进后出,后进先出
堆
10、命名规范
元素、项目、包(文件夹)、类、接口、抽象类、接口的实现类、变量
面向对象
思想
面向对象是相对于面向过程而言的,面向过程强调的是功能,
面向对象强调的是将功能封装进对象,强调具备功能的对象;
比如我要达到某种结果,我就寻找能帮我达到该结果的功能的对象,如我要洗衣服我就买洗衣机,至于怎么洗我不管。
特征
封装:隐藏对象的属性和实现细节,仅对外提供公共访问方式
继承: 多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义,这些属性和行为,只要继承那个类即可。
多态: 一个对象在程序不同运行时刻代表的多种状态,父类或者接口的引用指向子类对象
1、权限修饰符
public
当前类、同package、其他package可带哦用
protected
当前类、同package可调用
private
当前类可调用
2、类和new对象
类:对现实世界中某类事物的描述,是抽象的,概念上的定义。
对象:事物具体存在的个体。
new对象其实是调用构造方法 ,但我们发现刚写的类里并没有构造方法 ,事实上,如果你的类没有构造 方法系统会送一个空的构造方法。
3、构造方法
名字和类名完全一样,大小写也不能有区别,没有返回类型,没有返回值。
一旦你定义了自己的构造方法,系统就不会赠送空的构造方法
作用
构造函数是用于创建对象,并对其进行初始化赋值,对象一建立就自动调用相对应的构造函数
//使用无参的构造方法
Dog teddy = new Dog();
//使用有参的构造方法,直接给name赋值
Dog golden = new Dog("金毛");
//空的构造方法,方法必须和类名一样,不能有一点区别
public Dog(){
}
//构造方法和其他方法一样可以重载,可以有参数,名字必须和类名一样,不能有一点区别
public Dog(String name)
{
System.out.println("验证构造方法被调用的时机:【" + name + "】被构造!");
.name = name;
}
构造方法和成员方法区别
A:格式区别
构造方法和类名相同,并且没有返回类型,也没有返回值。
普通成员方法可以任意起名,必须有返回类型,可以没有返回值。
B:作用区别
构造方法用于创建对象,并进行初始化值。
普通成员方法是用于完成特定功能的。
C:调用区别
构造方法是在创建对象时被调用的,一个对象建立,只调用一次相应构造函数
普通成员方法是由创建好的对象调用,可以调用多次
4、setter和getter
所有的属性必须私有化:
使用setter和getter,因为方法能控制取值和赋值的过程。
5、封装
集装箱改变了搬运,把零散的东西封装成一个整体
使用简单的基础数据类型(属性),方法封装可以封装成更复杂,更好用的类
参考:超级数组
好处:
将变化隔离;
方便使用;
提高复用性;
提高安全性
6、String
引用类型
注:使用string一定要注意,必须用一个新的String接受。
String substring = name.substring(1, 3);
用法
符串查找
字符串替换
字符串分割
字符串截串
字符串小写转大写
7、类加载器
把clss类,加载到内存里边,然后去运行
专业名称叫classloader
第一次主动使用类,加载的过程是静态的
8、静态过程
static的变量和方法,都在这个过程完成初始化并赋值给类对象
9、引用
放在栈里面,除了基本类型(byte、short、int、long、),但是String、数组、所有自己定义的类都是引用类型,都存在栈里面。存在栈里面的引用都是内存地址,指向内存的一片空间。只要碰到new,一定是从内存里面挖了一片空间去存数据。
栈帧
每个方法只要一执行,就会拉一个方法进来
方法里定义的变量,就是局部变量
10、对象和类对象的区别
对象:就是内存里边一块区域存的数据所表示的东西,是new出来的,在堆空间里面存的一堆数据所表示的
类对象:在类加载的时候把类加载到内存里面,形成了类对象,就像说明书,被static修饰。不能被调用。在内存里面只有一个
11、栈--先进后出
压栈
压入栈顶,一个数据结构
//压栈(压入栈顶)
public void push(int data){
superArray.add(data);
}
弹栈
有返回值,把最顶上面得值弹出来
public int pop(){
return superArray.delete();
}
12、继承
extends 单继承,一个爹可以有多个儿子,一个儿子只能有一个爹。
有个 顶级父类叫Object,所有的对象都有一个父类叫Object,这是规定,记住。
思想:一个对象调用方法的时候,首先去自己的类里边找,找不到的话就去父类找,父类找也不到,就 去父类的父类找,直到Object,找到为止!
new一个子类,一定会先new一个父类,子类的构造方法中第一句默认就是super(),意思就是构造子类一定会先构造一个父类
13、多态
存在的前提
1、要有继承
2、要有重写
3、要有父类引用指向子类对象
//父类引用指向子类,子类能完成父类的一切工作
Animal dog = new Dog("小狗");
dog.eat();
存在的好处
灵活
14、抽象类
1、有些类天然就是为了让子类继承,而不是为了在父类中调用,这类方法存在的目的就是规定了子类,必须要有这些方法,比如动物类就规定,你实现了我这个类,就必须有eat方法,而且你必须重写
2、抽象方法必须使用abstract修饰
3、抽象方法是对子类的约束,不管是猫是狗,他必须是能吃东西
4、子类必须实现的定义成抽象类
public abstract void eat();
注意:
1、不能new,因为某些方法没有方法体。这些方法就是用来重写的,就是定义了子类必须有这些方法
2、他必须被继承才能用,必须实现所有的抽象方法
3、如果一个类继承了抽象类,要么,把自己声明成一个抽象类;要么,实现抽象类的所有方法;要么,实现抽象类的所有方法
15、接口
概念
当一个类里全是抽象方法,我们称这类方法叫接口,省略abstract,class改为interface。
注意:
1、接口里省略权限修饰符,默认为public,一个原因是因为他是给子类去实现(即成立叫重写)的
2、接口要被实现,关键字implements,必须实现里边所有的方法
3、java是单继承,但是是多实现,一个类可以实现多个接口,但只能继承一个父类
4、实现接口,必须实现接口里全部方法
5、接口里只能有静态常量、抽象方法
6、静态常量可以在任何的类、抽象类、接口中定义,他和继承、封装、多态以及new不new没有关系
public static final int num = 1;
16、对象转型
强制转换
从父类的类型强制转换为子类,如果传入的真的是该类型,则强转没有问题;如果不是就会报错
合适的方法是使用instanceof,首先进行判断,确定类型后再处理
17、数组和链表区别
数组:调料盒,必须是连续存储,顺序存储,所有元素一次存储,插入时需要扩容,不便新增和删除
链表:不连续,可以分散的存储,链式存储,通过指针,插入删除不需要移动,长度容易扩充,查找比较难(需要从头开始,一个一个查找,费时)
链式存储:一个一个查找
集合和数组的区别
1:数组是固定长度的;
集合可变长度的。
2:数组可以存储基本数据类型,也可以存储引用数据类型;
集合只能存储引用数据类型。
3:数组存储的元素必须是同一个数据类型;
集合存储的对象可以是不同数据类型。
18、List集合
也叫容器,装东西
List<> 名称 = new List<>();
概念
1、集合存放的都是对象引用,而非对象本身,出于表达上的便利,我们称集合中的对象就是指集合中对象的引用(reference)
2、集合就是能存东西的类,有的是只存值比如list、set,有的是存键值对,一个键一个值比如map,有的是数组实现,有的是列表实现的,有的是红黑树实现的,把一堆数据集合在一起就是集合
类型
有序的:set(集)、---------- HashSet、TreeSet
无序的:list(列表)、---------- ArrayList、LinkedList
map(映射) ---------- HashMap、TreeMap
集合接口分类
Collection和Map、list、set
注意:集合是一个动态的数组,数组的长度是不可变的、集合长度是可变的
collection:所有集合的父类
Collection接口
表示一组对象,这些对象也称为collection的元素。一些collection允许有重复的元素(例如List),但是另一些不允许有重复元素,例如(set)
List集合
元素有序,每一个元素都存在一个索引,元素可以重复
Set集合
元素无序,元素是通过链表进行存储的,元素不可以重复
Map集合
元素无序,通过键值对的方式进行存储,键不可以重复,值可以重复
ArrayList集合
参考SuperArray超级数组
注意
1、集合只能存储引用类型
2、ArrayList是顺序存储
3、特点:查询快、增删慢、线程不安全、效率高
4、容量会自动增加
5、初始化为10,有一个父类是List
//构造方法
List<String> strings = new ArrayList<>();
add方法
直接add,add(int index,String element),指定下标插入一个新的元素
clear方法
删除所有的元素
contains方法
如果此类表包含指定元素,则返回true
indexof方法索引
找元素,看元素在第几个位置,找不到就是-1
isEmpty
看看元素是否为空
迭代器
iterator():以正确的顺序返回该列表中的元素迭代器
remove(int index)
按照下标删除 names.remove(2);
remove(Object o)
从列表中删除指定元素的第一个出现(如果存在)
removeRange(int fromIndex,int toIndex)
删除列表fromIndex(包含)和toIndex之间的元素
set(int index,E element)
用指定的元素替换此列表中指定位置的元素
size()
int类型,返回此列表中的元素数
subList(int fromIndex,int toIndex)
返回此列表中指定的fromIndex(包括)和toIndex之间的独占视图
例如(1,4):1、2、3会出来
toArray()
以正确的顺序(从第一个到最后一个元素)返回一个包含此列表中所有元素的数组
简而言之,将他们变成数组
Object[] objects = strings.toArray();
LinkList集合
底层数据结构是链表
特点:查询慢,增删快,线程不安全,效率高
Map
1、通过名字获取
Map是父类,父类引用指向子类
2、有两个泛型
public static void main(String[] args) {
//通过名字获取
Map<String,User> map = new HashMap<>();
//map存数据
map.put("武三水",new User("武三水",18,2));
//map取数据
User wss = map.get("武三水");
System.out.println(wss.getName());
}
------------------------------------
结果:武三水
HashMap--entryset
1、存的是一个键值对,叫做entryset,里面封装了内部类
2、通过键,找到值
3、首先会在内存生成数组,初始大小为16,用node存数据(里面有key、value、nextnode)。首先拿key算哈希值,得到一个数字,除以8,两个同样的形成一个链表,至少能挂8个,之后会树化,变成红黑树
4、HashMap不能根据key来排序
5、TreeMap可以排序,整体都是一棵树
6、V是泛型
7、HashMap的key不能重复,会直接覆盖
getOrDefault(Object key,V defaultValue)
1、返回到指定键的值,或defaultValue
2、M安排有两个泛型,一个是key的,一个是value的
isEmpty
看看元素是否为空
keySet()
返回此地图中包含的键的set视图,就是拿到所有的key
通过哈希值一算,就会散列,分散成列
//返回所有的key
Set<String> strings = map.keySet();
Remove
删除
replace(K key,V value)
将某一个key替换为别的值
keyset拿到所有的key,拿key去找值
拿到所有的键值对遍历
map的便利
//map的便利,map不能排序
//map存的都是entry这种键值对,使用增强for循环拿到一个个键值对遍历
for (Map.Entry<String,User> entry : map.entrySet()){
System.out.println(entry.getKey());
System.out.println(entry.getValue());
}
TreeMap--有序
有序的,在你添加时自动排序
HashCode
1、任何都能通HashCode它生成一个数字
1、每一个字符串都能生成一个Hash,所有的字符串生成的数字都不一样
3、运用了哈希、数组、链表
HashSet-自动排序
1、不能重复,重复会被直接覆盖
TreeSet-自动排序
不能重复,而List可以,可以自动排序
first()
返回当前第一个元素
利用set去重
19、重写override
概念
1、在不同类中(子父类中),方法声明相同(返回类型,方法名,参数列表均相同)。
2、从字面上看,重写就是 重新写一遍的意思。其实就是在子类中把父类本身有的方法重新写一遍。子类继承了父类原有的方法,但有时子类并不想原封不动的继承父类中的某个方法,所以在方法名,参数列表,返回类型(除过子类中方法的返回值是父类中方法返回值的子类时)都相同的情况下, 对方法体进行修改或重写,这就是重写。但要注意子类函数的访问修饰权限不能少于父类的。
注意:
1.发生在父类与子类之间
2.方法名,参数列表,返回类型(除过子类中方法的返回类型是父类中返回类型的子类)必须相同
3.访问修饰符的限制一定要大于被重写方法的访问修饰符(public>protected>default>private)
4.重写方法一定不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查型异常
5、子类方法的访问权限要大于等于父类方法的访问权限
6、静态只能在重写静态。但是这种情况一般不会出现
public class Father {
public static void main(String[] args) {
// TODO Auto-generated method stub
Son s = new Son();
s.sayHello();
}
public void sayHello() {
System.out.println("Hello");
}
}
class Son extends Father{
@Override
public void sayHello() {
// TODO Auto-generated method stub
System.out.println("hello by ");
}
}
20、重载overload
概念
1、在同一个类中,允许存在一个以上的同名函数,只要它们的参数个数或者参数类型不同即可。
2、在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同甚至是参数顺序不同)则视为重载。同时,重载对返回类型没有要求,可以相同也可以不同,但不能通过返回类型是否相同来判断重载。
特点
1.重载Overload是一个类中多态性的一种表现
2.重载要求同名方法的参数列表不同(参数类型,参数个数甚至是参数顺序)
3.重载的时候,返回值类型可以相同也可以不相同。无法以返回型别作为重载函数的区分标准
4、与返回值类型无关,只看参数列表(参数类型以及参数个数)
好处
方便阅读,优化了程序设计
public class Father {
public static void main(String[] args) {
// TODO Auto-generated method stub
Father s = new Father();
s.sayHello();
s.sayHello("wintershii");
}
public void sayHello() {
System.out.println("Hello");
}
public void sayHello(String name) {
System.out.println("Hello" + " " + name);
}
}
重载与重写区别
重载在一个类中,且除了方法名、返回值、参数类型都可以不一样;
重写在子类中重写,重写是方法名,返回类型,参数必须完全一样,切必须要有继承
面试时,问:重载(Overload)和重写(Override)的区别?
答:方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同或者二者都不同)则视为重载;重写发生在子类与父类之间,重写要求子类被重写方法与父类被重写方法有相同的参数列表,有兼容的返回类型,比父类被重写方法更好访问,不能比父类被重写方法声明更多的异常(里氏代换原则)。重载对返回类型没有特殊的要求,不能根据返回类型进行区分。
21、date
SimpleDateFormat(String pattern)
使用给定模式SimpleDateFormat并使用默认的FORMAT语言环境的默认日期格式符号
HH:24小时制
hh:12小时制
时间戳
1、英国伦敦1970年1月1日 0:0:0 到现在的毫秒数
2、在任何地域都一样
22、Calander日历类
//设置了一个月历,适用于零点抢购
calendar.set(2020,Calendar.JANUARY,12,12,12,12);
23、Math静态方法
数学操作类:该类没有构造函数,方法均为静态的
//向上取整
System.out.println(Math.ceil(3.3));
//向下取整
System.out.println(Math.floor(3.3));
//取一个最大值
System.out.println(Math.max(2,4));
//取一个最小值
ystem.out.println(Math.min(2,4));
//取一个随机数
System.out.println(Math.random());
24、Random随机数
掌握内容
A:构造方法
**Random() 创建一个新的随机数生成器。 **
Random(long seed) 使用单个 long 种子创建一个新的随机数生成器。
B:成员方法
**int nextInt() 返回下一个伪随机数,它是此随机数生成器的序列中均匀分布的 int 值。
**int nextInt(int n) 返回一个伪随机数,它是取自此随机数生成器序列的、
在 0(包括)和指定值(不包括)之间均匀分布的 int 值。
//最常用
System.out.println(random.nextInt(100));
System.out.println(random.nextInt());
System.out.println(random.nextFloat());
System.out.println(random.nextDouble());
25、单例模式
(1)设计模式:
解决某类问题行之有效的方法,是一种思想,是规律的总结
(2)用来保证某个类在内存中只有一个对象
(3)保证唯一性的思想及步骤
为了避免其他程序建立该类对象,先禁止其他程序建立该类对象,即将构造函数私有化
为了其他程序访问到该类对象,须在本类中创建一个该类私有对象
为了方便其他程序访问到该类对象,可对外提供一个公共访问方式
比如API中的Runtime类就是单例设计模式。
(4)单例设计模式的两种方式
A:饿汉式 当类加载的时候,就创建对象。
B:懒汉式 当使用的使用,才去创建对象。
饿汉式和懒汉式的区别:
**
饿汉式是类一加载进内存就创建好了对象;
懒汉式则是类才加载进内存的时候,对象还没有存在,只有调用了getInstance()方法时,
对象才开始创建。
**
懒汉式是延迟加载,如果多个线程同时操作懒汉式时就有可能出现线程安全问题,解决线程安全问题
可以加同步来解决。但是加了同步之后,每一次都要比较锁,效率就变慢了,
所以可以加双重判断来提高程序效率。
注:开发常用饿汉式,因为饿汉式简单安全。懒汉式多线程的时候容易发生问题
26、File
1、文件和目录路径名的抽象表示
2、方便操作文件
3、常用构造方法
File(String pathname):通过给定的路径名字转换为抽象路径名来创建新的File实例
//返回的是Boolean值
file.canExecute(); //可执行
file.canRead(); //可读
file.canWrite(); //可写
file.createNewFile(); //创建新的文件夹
file.exists(); //是否存在
file.delete(); //删除
file.getAbsolutePath(); //拿到绝对的路径,就是他所在的位置
file.getName(); //拿到文档的名字
file.getParent(); //所在的父级文件夹
file.setReadOnly(); //设置文档可读
file.setWritable(); //设置文档可读
file.isFile(); //是否为文件
file.isDirectory(); //是否为目录
file.isHidden(); //是否文隐藏文件
file.length(); //文件有多少字节,有多大
file.list(); //调出里面的文件
27、IO流
概念
1、java的io是实现输入和输出的基础,可以方便的实现数据的输入和输出操作。在java中把不同的输入/输出源(键盘、文件、网络连接等)抽象表为“流”(stream)
2、可以操作文件以及文件里面的内容
分类一
字节流:读文件一个字节一个字节,一个字节8个比特
字符流:处理文件一个字符一个字符,不会乱码,两个字
节点流:根据数据类型不同而定义不同类型的流,堆在不同的节点之上
处理流:有某些场景可能有某些更复杂功能
分类二
根据流的流向-----输入流和输出流
· 输入流:只能从中读取数据,而不能向其写入数据
· 输出流:只能向其写入数据,而不能向其读取数据。此处的输入,输出设计一个方向的问题。数据从内存到硬盘,通常输出为输出流--也就是说,这里的输入,输出都是从程序运行所在的内存角度来划分的
根据单位-----字节流和字符流
字节流和字符流的用法几乎完成全一样,区别在于字节流和字符流所操作的数据单元不同,字节流操作 的单元是数据单元是8位的字节,字符流操作的是数据单元为16位的字符。
字节流主要是由InputStream和outPutStream作为基类,而字符流则主要有Reader和Writer作为 基类。
按照流的角色-----节点流和处理流
可以从/向一个特定的IO设备(如磁盘,网络)读/写数据的流,称为节点流。节点流也被称为低级流。
java输入/输出流体系中常用的流的分类表
分类 | 字节输入流 | 字节输出流 | 字符输入流 | 字符输出流 |
---|---|---|---|---|
抽象基类 | InputStream | OutputStream | Reader | Writer |
访问 文件 | FileInputStream | FileOutputStream | FileReader | FileWriter |
访问数组 | ByteArrayInputStream | ByteArrayOutputStream | CharArrayReader | CharArrayWriter |
访问字符串 | StringReader | StringWriter | ||
缓冲流 | BufferedInputStream | BufferedOutputStream | BufferedReader | BufferedWriter |
转换流 | InputStreamReader | OutputStreamWriter | ||
对象流 | ObjectInputStream | ObjectOutputStream |
转换流能都将字符流转成字节流
文件的复制
//已知子类
AudioInputStream; //音频
PopedInputStream; //管道上
FileInputStream; //文件上
从一个文件夹复制到另一个文件夹,要用节点流,往文件上怼
FileInputStream:抽象类
read(byte[] b);
从输入流入去一些字节数,可以理解为一摞一摞的搬砖,效率会高,返回值int,读到-1说明已经读完了
FileOutputStream
可以传名字可以传文件
字节流读文件
字符流读文件
Buffered缓冲处理流
向文件里面写内容
StringReader
对象流(序列化)
1、该对象必须实现Serializable接口,这样才能被序列化。 对象在内存就是一堆0和1,任何文件在内存都是0和1,都能转化成字节数组,进行保存或者网络传输。
对象序列化也是一样的,就是把内存的对象以字节数组的形式上保存,我们能保存在磁盘,或者在网络 中传输。
2、序列化目的:把他通过网络传给别的程序,或者保存在自己的程序上
3、通过序列化可以传输对象,叫工程的交互
ObjectOutoutStream
把对象输出到文件里面
垃圾回收机制
1、GC只作用于堆
2、引用计数法,根可达计数法
GVM
1、伊甸园内存不足就会出现GC
2、老年代是标记清除算法
3、当幸存区的到达15岁后,就会进行清理
28、异常
概念
Java异常是一种错误情况,是程序不希望出现的现象,但是程序本身的设计逻辑和运行的环境等因素,出现异常的情况不可避免,Java虚拟机 针对不同的异常情况定义了很多异常类,当jvm运行程序发现对应的异常时,将会向外面抛出异常
类型
1、检查型异常
最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。
如要打开一个不存在文件时,一个异常就发生了
2、运行时异常RuntimeException
编译时书写类异常可能被程序员避免的异常,与检查型异常相反,运行时异常可以在编译时被忽略
能被规避,能用try / catch来解决
运行时异常,可以自己规避
例如 1/0;
3、错误异常Error
错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。
4、自定义异常
用法
需要在类名后面加extends RuntimeException,去继承
定义类继承Exception或者RuntimeException
1,为了让该自定义类具备可抛性。
2,让该类具备操作异常的共性方法。
class MyExcepiton extends Exception
class MyException extends RuntimeException
Exception和RuntimeException的区别
A:Exception:一般性的错误,是需要我们编写代码进行处理的。
B:RuntimeException:运行时异常,这个我们也不需要处理。
其实就是为了让他在运行时出问题,然后我们回来修改代码。
在用throws抛出一个的时候,如果这个异常是属于RuntimeException的体系的时候,我们在调用的地方可以不用处理。(RuntimeException和RuntimeException的子类)
在用throws抛出一个的时候,如果这个异常是属于Exception的体系的时候,
我们在调用的地方必须进行处理或者继续抛出。
throws和throw的区别
A:有throws的时候可以没有throw。
有throw的时候,如果throw抛的异常是Exception体系,那么必须有throws在方法上声明。
B:throws用于方法的声明上,其后跟的是异常类名,后面可以跟多个异常类,之间用逗号隔开
throw用于方法体中,其后跟的是一个异常对象名
常见的内置异常类
1、下标越界
2、类型转换异常,猫不能转换成狗
3、没有被初始化,内存里面没有该对象
4、检查性异常
5、空指针异常
异常类型 | 说明 |
---|---|
Exception | 异常层析结构的父类 |
ArithmeticException | 算数错误情形,如以0做除数 |
ArrayIndexOutOfBoundsException | 数组下标越界 |
NullPointerException | 尝试访问null对象成员 |
ClassNotFoundException | 不能加载所需的类 |
IllegalArgumentException | 方法接收到非法参数 |
ClassCastException | 对象强制转换出错 |
NumberFormatExcept | 数字格式转换异常,如把“abc”转换成123 |
Throwable类的学习
getMessage():获取异常信息,返回字符串。
toString():获取异常类名和异常信息,返回字符串。
printStackTrace():获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。
异常的处理·
A:try...catch...finally
基本格式:
try
{
可能出现异常的代码
}
catch(异常对象)
{
异常处理代码
}
finally
{
释放资源
}
面试题
***:final,finally,finalize区别。
final是最终的意思。它可以用于修饰类,成员变量,成员方法。
它修饰的类不能被继承,它修饰的变量时常量,它修饰的方法不能被重写。
finally:是异常处理里面的关键字。
它其中的代码永远被执行。特殊情况:在执行它之前jvm退出。System.exit(0);
finalize:是Object类中的一个方法。
它是于垃圾回收器调用的方式。
***:假如catch中有return语句, finally里中的代码会执行吗?
是在return前,还是在return后呢?
会,在return前执行finally里面的代码。
29、工具类
数组Arrays
Arrays.asList(); //变成列表
//变成列表
List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5, 6);
二分查找
复制
排序,双轴快排
集合Collection
添加元素
打乱shuffle
30、integer
Integer 的自动拆箱和装箱
①、自动装箱
一般我们创建一个类的时候是通过new关键字,比如:
Object obj = new Object();
但是对于 Integer 类,我们却可以这样:
Integer a = 128;
为什么可以这样,通过反编译工具,我们可以看到,生成的class文件是:
Integer a = Integer.valueOf(128);
这就是基本数据类型的自动装箱,128是基本数据类型,然后被解析成Integer类。
②、自动拆箱
我们将 Integer 类表示的数据赋值给基本数据类型int,就执行了自动拆箱。
Integer a = new Integer(128);
int m = a;
反编译生成的class文件:
Integer a = new Integer(128);
int m = a.intValue();
简单来讲:自动装箱就是Integer.valueOf(int i);自动拆箱就是 i.intValue();
31、扩展
8、js和java分别怎么生成一个10到20的随机数?
答:js:let random = Math.floor(Math.random()*10)+10
java:int i = (int)(10 + Math.random()*(20 - 10 +1))