J2SE-Java基础

注释

1.单行注释 //
2.多行注释 /* /
3.文档注释 /
* */

数据类型

– Java是强类型的语言 –
数据类型分为两种:

	第一种:基本类型
		整型
		  byte(1字节)、short(2字节)、int(4字节)、long(8字节)
		浮点型
			float(4字节)、double(8字节)
		字符型
			char(2字节)
		boolean型
			boolean(1位)
	第二种:引用类型

类型转换
byte,short,char - int - long - float - double 由低到高
高转低 强制类型转换
低转高 自动类型转换

什么是字节?
在这里插入图片描述
拓展(面试常问)

1.整数 进制 二进制0b 十进制 八进制0 十进制0x

2.浮点数 是大约,接近并不准确的数

	-- 最好完全避免使用浮点数进行比较 --

所以银行业务怎么表示?*BigDecimal

3.字符的本质还是数字
可以互相转换

4.转义字符
\t - tab键
\n - 换行
crtl + D 复制到下一行

5.位运算符
<< 左移运算符 代表乘2
(>>) 右移运算符 代表除2

Scanner

从键盘接收再做处理
两个常用的方法 :
Scanner scanner = new Scanner(System.in);
scanner.next();//例:Hello Word 输出Hello
scanner.nextLine();//例:Hello Word 输出Hello Word

break & continue

break是强制退出循环体,结束循环,kill
continue是结束本层循环,回到循环开始

可变参数

int… i 也是可变数组
i[0] i[1]

面向对象编程(OOP)

以类的方式组织代码,以对象封装数据
封装 属性私有,get/set
继承
1.方法重载 & 方法重写
重载:
方法名称相同,参数列表不同
重写:
方法名称,参数列表相同,方法体不同
必须基于继承,子类继承父类才能重写父类的方法
修饰符只能扩大范围,不能缩小
抛出异常只能缩小,不能扩大

2.super
super VS this:
this调用本类的方法或对象(没有继承也可以用)
super调用父类的(必须有继承,才能在子类中使用)
在这里插入图片描述

注意:
super调用父类的构造方法默认第一个,只能是第一个
super和this不能同时调用构造方法
new对象时,如果有继承,是先调用父类的构造方法
如果父类只有有参构造,没有无参构造,子类是无法写无参构造的,

多态
1.存在条件:基于继承,要有重写方法,父类引用指向子类对象(Father s1 = new Son();)

2.子类重写父类的方法,父类对象去调用该方法,是会执行子类重写之后的方法。

3.instanceof关键字与引用类型的类型转换
子类转化为父类,低转高,自动类型转换,可能会丢失一些方法。
父类转换子类,高转低,强制类型转换
这个类型转换需要是子父类的关系,二者需要有关系
instanceof关键字就是判断是否有关系(father instanceof son —— true)

类型转换的作用:就是简化操作,不用再去new对象,而是通过升级降级去做。

static关键字

非静态方法可以调用静态方法,但是静态方法不能调用非静态方法。因为静态方法随着类的创建而创建,非静态方法需要类的实例化之后创建,所以已经存在的方法去调用不存在的方法就会报错。

–静态代码块&匿名代码块&构造方法–
静态代码块先执行且执行一次,次之匿名代码块执行,最后构造方法执行。

构造器

构造器与类名相同,不能有返回值。
本质:new对象的时候去调用这个构造函数,实例化初始值。

abstract抽象

1.抽象类(单继承)里可以有非抽象方法,抽象方法(没有方法实现)必须在抽象类里。
2.不能new对象,只能通过子类去继承父类去写方法实现
Java中的类是单继承的,但是接口是多继承的

interface接口

JDK7之前:只能定义抽象方法和全局变量
JDK8:还可以定义静态方法和默认方法

异常

在这里插入图片描述
try , catch , finally , throw , throws

Object类

答:首先它是所有类的父类。
所拥有的的方法:equals(),toString(),getClass(),clone(),finalize(),wait(),notify(),notifyAll()。

clone(): 就是克隆对象
finalize(): 垃圾回收之前调用这个方法,垃圾回收器通知对象去调用
toString(): 当输出一个对象的引用时,实际是在调用对象的toString方法,在Object类中。toString是一串地址值,但是String、Date、File重写了toString方法。

包装类与String之间的转换

包装类与基本数据类型之间存在自动装箱/拆箱,所以可以看成整体。其他类型转换成String类型String.ValueOf()这个方法,String转换其他类型,要调用包装类的parseXXX(parseInt)方法。

线程

主要围绕:创建线程有四种方式,解决线程安全有三种方法
程序:是一段静态代码块
进程:程序的一次执行过程,是执行着的应用程序,动态的,系统运行时会为每一个进程分配不同的内存空间
线程:一个进程内部可以有多个线程,每个线程有自己独立的栈和程序计数器。一个进程中的多个线程有共享的内存单元。但多个进程共享的资源可能会存在安全隐患

创建线程的方法

一:继承Thread类
实现步骤:
1、子类继承父类
2、重写run方法(需要实现的功能写在run方法里面)
3、创建子类对象
4、调用start方法(start方法作用1:启动当前线程。start方法作用2:调用run方法)

存在两个问题:
1.子类对象不能直接调用run方法,需要通过start方法去启动线程并调用run方法,如果直接调用run方法就与普通的对象之间的调用一样,体现不出多线程
2.要同时启动两个线程,就创建多个子类对象。如果两个线程run方法实现不一样,就创建两个子类

Thread类中的方法
在这里插入图片描述
线程的优先级
在这里插入图片描述

二、实现Runnable接口
实现步骤:
1、创建一个类实现Runnable接口
2、实现接口中的run方法
3、创建该类的对象
4、将类对象作为参数传递到Thread类的构造函数中,创建Thread类对象
5、通过Thread类对象调用start方法

两种方法的区别:

优先选用Runnable接口
1、Java中类是单继承的,接口是多继承的,接口实现就不会有单继承类的局限性
2、实现的方法更适合多线程共享数据的情况

三、实现Callable接口
实现步骤:
1、创建实现Callable接口的实现类
2、重写接口中的call()方法,该方法可以抛异常,可以有返回值
3、创建接口实现类对象
4、将此对象作为参数传递给FutrueTask的构造函数,并创建FutrueTask对象
5、将FutrueTask对象作为参数传递给Thread类的构造函数,并创建Thread类对象,调用start方法
6、FutrueTask对象的get方法可以接受call方法的返回值

Callable接口相当于Runnable接口更强大
1、call方法有返回值
2、call方法可以抛异常
3、接口支持泛型

四、创建线程池
在这里插入图片描述
一般开发中使用线程池,因为
1、减少创建新线程的时间,提高响应速度
2、重复利用线程池中的线程,不需要每次创建,节约资源
3、便于线程管理

线程的生命周期

(1)创建:创建新的线程对象
(2)就绪:线程对象创建之后,调用了该对象的start方法,该状态的线程位于可运行的线程池中,等待运行。
(3)运行:可运行状态的线程获得CPU时间片,调用run方法,执行程序代码。
(4)阻塞:线程因某种原因放弃CPU的使用权,暂停运行
(5)死亡:线程结束生命周期,死亡的线程不在复生。

线程的同步

线程安全问题出现的原因:当一个线程操作车票的时候,还未完成,另一个线程也进来参与车票,就会发生线程的安全问题。

---- 在Java中,我们通过同步机制来解决线程安全问题。----

第一种方法:同步代码块

格式:
synchronized(同步监视器){
同步代码块
}

说明:1.操作共享数据的代码即为同步代码块
2.共享数据就是多个线程共同操作的数据
3.同步监视器,即锁。任何一个类的对象都可以作为锁,但是多个线程只能共用一个锁

—继承Thread类与实现Runnable接口分别是如何看待多个线程只能共用一个锁的?–
实现Runnable接口是只new一个对象,进行数据共享,就是多个线程共用一把锁,但是继承Thread类是new了多个线程对象,未做到多个线程共用一把锁,解决的办法1是将锁变成静态的。解决方法2,用this关键字,指向当前run方法对象

第二种方法:同步方法
同步方法同样涉及同步监视器,只是不需要显示声明
1.非静态同步方法,同步监视器是this
2.静态同步方法,同步监视器当前类本身

死锁
两个线程同时占用对方所需要的资源不放手,都等着对方先释放,就会造成死锁。尽量避免死锁的方法是,能不用同步就不用,一嵌套就容易死锁,而且效率低。

第三种方法:Lock锁(JDK5.0以后加的)
面试题:synchronized与Lock的异同?
相同:都可以解决线程安全问题
不同:synchronized机制是执行完同步代码块之后自动释放同步监视器,Lock锁是先加锁lock(),之后手动释放锁unlock()。这样就是随时释放锁。

------ 推荐使用顺序:Lock锁 – 同步代码块 – 同步方法 --------

线程通信

例子:使用俩个线程交替打印1-100之间的数

线程通信涉及三个方法:
wait():一旦使用这个方法,线程就会变成阻塞状态并释放锁
notify():唤醒被wait的一个线程,如果有多个线程wait,就唤醒优先级高的那个
notifyAll():唤醒所有被wait的线程

注意:这三个线程必须使用在同步代码块或者同步方法里面,调用这三个方法的必须是同步监视器,而且这三个方法都是Object类里面的(因为任何对象都可以作为锁,所有任何对象都应该能调用上面三个方法)

面试题:sleep()与wait()有什么异同?
相同:都可以让线程阻塞
不同:1)两个方法存在的类不同,sleep方法存在Thread类中,wait方法存在Object类中。2)使用地方不同,sleep方法可以使用在任何场景下,wait方法要使用在同步方法或同步代码块中。3)sleep方法调用时不会释放锁,wait方法调用释放锁

Java中常用的类

String

在这里插入图片描述

String的字符串拼接

在这里插入图片描述

String中常用的方法

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

------String转换为字符数组 tocharArray(),反之调用String构造函数 -------

– String 转换成byte数组 getbytes(),反之亦然 -------

String、StringBuffer、StringBuilder

String 不可变序列
StringBuffer 可变序列,线程安全的
StringBuilder 可变序列,线程不安全的,效率高。JDK5.0 以后出现的

相同点:三者的底层实现都是char[] 数组

源码分析:
当我们new一个String对象,它的底层默认是创建一个char[0],长度为0
当我们new一个StringBuffer对象,StringBuffer默认是char[16], 长度为16
如果要添加的数据底层数组放不下了,就需要扩容,StringBuffer默认扩容到原来的两倍+2,再把原来的数组复制过去。StringBuilder与StringBuffer一样

建议:在开发中,尽量直接就定义好长度,避免扩容,影响效率

StringBuffer常用的方法
在这里插入图片描述

Java中时间表达

------时间戳

在这里插入图片描述
------两个Date
在这里插入图片描述
两个Date如何转换,它们有一个共同的getTime()方法,可以先获取毫秒数,再转换。

SimpleDateFormat

在这里插入图片描述

–JDK8.0以后,LocalDate(年月日),LocalTime(时分秒),LocalDateTime(年月日时分秒)---------

每个类里面都有很多方法,LocalDateTime最常用

Java比较器

Java的对象正常情况下,只能进行比较== 或者 !=,但是在实际开发场景中,很多对象需要排序,所以需要两个接口Comparable、Comparator中的一个
Comparable(自然排序)
像String、包装类等实现了Comparable接口,重写了compareTo方法,对象之间就可以进行比较了。例如:Arrays.sort(str),排序字符串

自定义类操作步骤:
1.实现Comparable接口
2.重写CompareTo方法,定义排序方式

Comparator (定制排序)
自定义类操作步骤:
1.实现Comparator接口
2.重写compara方法,定义排序方式

二者区别: 实现Comparable接口的方式可以重复利用,而实现Comparator接口的方式只能在当前类中用,比较临时。

Java集合框架&容器

Java中的数组和集合都是存储多数据的结构,区别:
数组: 优点:有序,可重复,适合查询操作。缺点:一旦确定,长度不可变,不适合插入、删除、添加操作。
集合: 支持动态扩容,长度可变,适合插入、删除、添加操作,但不适合查询,是一种无序的数据结构

集合框架结构大概图:
在这里插入图片描述

1、Collection

在这里插入图片描述

在这里插入图片描述
迭代器iterator :为容器而生,专门用于容易遍历数据的,有两个常用方法hasNext()、next()方法,执行原理如图:在这里插入图片描述

1-2、List (JDK1.2)

面试题:ArrayList、LinkedList、Vector区别?
ArrayList (JDK1.2): List集合主要实现类,线程不安全的,效率高,底层是使用Object[]数组存储
LinkedList(JDK1.2): 底层是使用双向链表存储的,对于频繁的插入、删除操作效率比ArrayList高
Vector(JDK1.0): List集合古老实现类,线程安全,效率低,底层是使用Object[]数组存储

相同点:它们三个都实现了List接口,存储方式跟List一样,有序,可重复。

ArrayList源码分析:

**JDK 7情况下:**创建一个无参构造器 ArrayList list = new ArrayList(); 就相当于创建了一个长度为10的Object[]数组,如何所要放的数据超出数组长度,就需要动态扩容,这个过程是ArrayList底层源码自动封装帮我们做好的,默认扩容为原来的1.5倍,再将原数组的数据搬到新数组中。
结论:建议开发中使用带参构造器,直接定义长度,避免扩容,数据搬移,影响效率。

JDK 8情况下: 创建一个无参构造器 ArrayList list = new ArrayList(); 就相当于创建了一个长度为0的Object[]数组,当第一次添加的时候再创建长度为10的Object[]数组,后续操作与JDK 7一样。
结论:相比于JDK 7的区别,延迟数组创建,节省内存。

LinkedList源码分析:
JDK 7 和 JDK 8 一样。ArrayList list = new ArrayList(); 内部声明了Node类型的first和last属性,默认为null,当添加数据时,将数据封装到node节点里,创建node对象。

Vector源码分析:
JDK 7 和 JDK8 都是底层直接创建一个长度为10的数组,不同的是在扩容方面,它是扩容为原来的2倍。

List里常用方法

List集合肯定可以用Collection的方法,由于List是有序的,所以有了很多关于索引的方法。这是相对于父接口的区别,因为父接口还有兼容Set无序接口。

在这里插入图片描述

1-3 Set

Set集合没有额外的方法,只沿用Collection集合的方法。

Set集合无序,不可重复。以HashSet为例,无序是指元素添加的时候不是按照Set底层数组的索引添加的,而是根据元素的哈希值,无序不代表随机。

HashSet: 作为Set接口主要实现类,线程不安全,可以存储null值
LinkedHashSet: 它是HashSet的子类,遍历内部数据的时候,可以按照添加时的顺序
TreeSet: 可以按照添加对象的指定属性进行排序

HashSet添加元素源码分析:

我们向HashSet中添加元素a,先调用a的HashCode方法,计算a的哈希值,确定a应该放在HashSet底层数组中的哪个位置,如果这个位置是空的,添加成功1
如果这个位置有元素b(或者以链表形式存在很多元素),我们就计算a与b的哈希值是否一样,如果不一样,就添加成功2。如果一样,就调用a的equals方法,如果equals方法返回true,添加失败,返回false,添加成功3

说明: 对于添加成功2、3来说,原来数组上有元素,a在这里跟其他元素以链式存储。
对于JDK 7,a放到数组中,指向原来元素。
对于JDK 8,原来元素在数组中,指向a。

HashSet的底层是数组+链表的,HashSet的底层是HashMap

注: 向Set中添加元素必须要重写HashCode()方法和equals()方法,重写的这两个方法尽可能保持一致,可以自动生成。

LinkedHashSet添加元素源码分析:

它对于链表多维护了两个引用,记录了谁先来的谁后来的,对于频繁的遍历操作,LinkedHashSet比HashSet效率高。

TreeSet分析

向TreeSet里添加元素,必须是同一个类的对象,输出默认是按照从小到大的,可以自然排序,也可以定制排序

Map

在这里插入图片描述
Map结构图
在这里插入图片描述

HashMap底层原理

在这里插入图片描述
在这里插入图片描述

TreeMap

向TreeMap里添加K-V时,必须是同一个类的对象,按照Key进行排序,可以自然排序,也可以定制排序

Map中的常用方法

在这里插入图片描述

Collections工具类(操作Collection和Map的工具类)

面试题:Collection与Collections的区别?

Collections工具类里提供很多同步方法,它是线程安全的。里面也存在很多方法
在这里插入图片描述

I/O

一、流的分类

按照数据单位分:字节流(8 bit),字符流(16bit)
按照数据流向分:输入流,输出流
按流的角色分:节点流,处理流
在这里插入图片描述
重点要说的流:
在这里插入图片描述

1、抽象基类

InputStream(字节流)、OutputStream(字节流)、Reader(字符流)、Writer(字符流)

2、节点流

FileInputStream(字节流)、FileOutputStream(字节流)、FileReader(字符流)、FileWriter(字符流)

3、缓冲流(处理流)

BufferedInputStream(字节流)、BufferedOutputStream(字节流)、BufferedReader(字符流)、BufferedWriter(字符流)
缓冲流的作用就是提高读写速度,内部有一个缓冲区

4、转换流

InputStreamReader(字符流)、OutputStreamWriter(字符流)
提供字节流与字符流之间的转换

网络编程

在这里插入图片描述

一、IP与端口

IP地址是标识唯一一台计算机,IP地址分为IPV4(4个字节)和IPV6(16个字节)

二、TCP与UDP

在这里插入图片描述

反射

反射被视为动态语言,反射机制允许程序在执行期借助反射的API获取任何类的内部信息,并能直接操作任意对象的属性和方法。Java本身是静态语言,就因为它提供了反射机制,所以Java被称为“准动态语言”。

反射的作用: 反射之前,对于一个类,在类的外部是不能调用它的私有属性和方法的。反射之后,是可以调用的。

反射用途: 例如:用户的注册登录,是要服务器启动的时候才去完成的,是要客户端发出指令之后,是注册还是登录,服务端才根据客户端的需求去造你需要的对象,拿到对象所在类的方法属性等信息。

Class类 是反射的源头。一个类被javac文件编译后生成.class字节码文件,接着对这个字节码文件进行解释运行,加载到内存,这是类的加载。这个加载到内存中的类就是运行时类,此运行时类就作为Class类的一个实例。换句话说,Class类的实例是一个运行时类

获取Class类实例的三种方式
在这里插入图片描述
有了Class实例,
1、我们能做的第一件事,就是通过Class的API中的newInstance方法创建对象,默认是调用这个类的空参构造器
2、通过classPath方法来创建指定类的对象

如何操作运行时类的属性

在这里插入图片描述
如何操作运行时类的方法
在这里插入图片描述
如何操作运行时类的静态方法
在这里插入图片描述

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值