Java基础复习,整理知识点 java基础知识重点总结
yuyutoo 2024-10-12 01:23 3 浏览 0 评论
1.Java关键字总结梳理
首先这里总结一下在编写类时常常会碰到的一些关键字:
private,public,protected,default
关键字同一个包中的其他类不同包中的其他类子类自身privateNoNoNoYesprotectedYesNoYesYespublicYesYesYesYes无修饰(default)YesNoNoYes
注意:以上几个修饰词是和包有关的
static
static关键字修饰内容的几个特点:
1. static修饰的变量和类文件一同被加载到内存中
2. 被修饰的方法可以直接通过类名加点来引用,也就是说static修饰部分的引用是不需要将对象实例化的。
有关static一些注意事项:
- static方法只能访问static变量
- static方法中不能使用this,super这样的关键字,因为static优先于对象被加载到内存之中,static执行时对象可能还未被实例化。
- 内部类包含static修饰的属性或方法时,内部类必须也被static修饰,其实理解起来也很简答,应为static会优先被加载,如果内部类不被static修饰,那么内部变量是不会被提前加载的,这时static关键字修饰就不起作用了。
final
- final是一个修饰词,可修饰类,变量,函数
- final修饰的类不可被继承
- final修饰的函数无法被复写
- final修饰的变量只能赋值一次
abstract
- abstract同样是一个修饰词,能够修饰方法和类
- abstract修饰的类无法被实例化,只能够通过子类的继承并实现内部所有的抽象函数才能被实例化。
- abstract修饰的函数只需要申明方法名,参数,不需要写函数体。
- 抽象类中同样可以定义非抽象的方法,同时抽象类也有构造函数,这个构造函数提供给子类实例化时使用。
- 抽象类中也可以没有抽象的方法。
- abstract不可以和static,private,final公用,简单理解一下,static修饰说明优先加载,而abstract未被实现,所以无法被优先加载。final修饰表名为最终状态无法修改,而abstract修饰的需要子类去实现,必须可以修改。private表示私有化,自由自身能够访问到,而abstract需要子类访问并实现函数体。
instanceof
用于判断类是否实现了指定接口或实现了指定的类,举个简单的例子:
public class Test {
public static void main(String[] args) {
NullPointerException e = new NullPointerException();
System.out.println(e instanceof Exception);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
输出结果为true
2.面向对象
面向对象最为主要的两个内容
- 过程,其实也就是函数
- 对象,则是对一些函数和属性进行了封装
所以,其实在面向对象的编程过程中,编写类,也就是完成对函数和成员变量的封装(当然,在编写前需要对类进行设计)。
接口和接口的实现
- 接口有interface关键字定义,内部函数默认为抽象的,所以接口无法实例化.
- 一个类在实现了接口中所有的方法时才能被实例化,否则这个类还是一个抽象类,无法被实例化,实现某个接口使用关键字implements
- 一个类可以实现多个接口,而且接口之间也可以相互继承,并且接口可以多继承,一个简单的例子:
public class Test {
interface interface1 {
void function1();
}
interface interface2 {
void function2();
}
interface interface3 extends interface1, interface2 {
}
class MyClass implements interface3 {
@Override
public void function1() {
// TODO Auto-generated method stub
}
@Override
public void function2() {
// TODO Auto-generated method stub
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
可以看到,当MyClass实现了interface3,并且interface3继承了interface1和interface2时,MyClass需要实现interface1和interface2中的所有方法。
继承
继承当中子类与父类之间的一些关系:
- 成员变量:当子类中出现与父类相同的成员变量时,在子类中调用优先调用子类的该变量,如果想要调用父类中的该成员,则需要使用super关键字。
- 成员函数:当子类中出现与父类之中相同的方法时,子类的方法会将父类中的方法覆盖。在外部调用时,会调用子类的方法。
- 构造函数:子类的构造函数中会默认调用super()意味着在构造子类之前需要先对其父类进行构造。
多态
举一个简单的多态例子:
父类定义
class Father
{
void sayHi()
{
System.out.println("father hello");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
子类定义:
class Son extends Father
{
void sayHi()
{
System.out.println("son hello");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
测试代码:
public static void main(String[] args) {
Father f = new Son();
f.sayHi();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
输出结果为“son hello”
可以看出,可以通过父类访问到子类的方法,这样为我们操作大量对象提供了方便,当我们需要操作大量不同对象时,我们只需要通过访问他们的父类来操作他们共性的一部分即可。
当然以上只是简单的多态的例子,动态在Java中有很多体现,接口的实现,继承,复写都体现着多态。
3.那些我们常常遇到的类
Exception
异常是程序运行期间发生的不正常的行为,Java中将异常进行了封装,并能够使用try catch语句对异常捕获和处理。所有异常的父类都是Exception,这些异常类的共有特点就是能够被抛出。
这里对比一下throws和throw的区别:
throws抛出的是异常的类名,出现在方法头部,throws只是存在抛出异常的可能并且自身无法处理,需要交给调用者来处理。
private void main() {
try {
function();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void function() throws IOException {
Socket s = new Socket("", 11);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
可以看到,我们通过throws将异常抛出,并且在function被其他函数调用时,调用者任然需要对异常进行捕获和处理,当然调用者也可以继续讲异常抛出,等待其他的调用者对异常进行处理。
throw抛出的是异常的对象,出现在函数体内部,throw一定会抛出异常。看例子
public static void main(String[] args) {
String real_pass_word = "123456768";
String input_pass_word = "123456";
try {
if (!real_pass_word.equals(input_pass_word)) {
throw new IOException();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
可以看到需要对当密码不相等时,我们使用throw抛出了异常IOException,并且在外层通过try catch对异常进行了捕获。
Thread
首选明确一下线程和进程的区别:
进程是程序在执行当中分配资源和管理资源的最小单位。进程之间通常不会共享资源,每个进程独有系统分配的资源,进程中可以包含多个线程。
线程是进程中的一个程序执行控制单元,同时也是一条执行路径,属于同一个进程的线程之间共享进程内的数据,并且可以相互之间进行通讯。
创建一个新的线程有两种办法:
- 通过Thread或继承至Thread的类创建线程对象
- 通过实现Runable接口,并将实现Runable接口的对象作为参数传入Thread()构造方法中(这里解释一下Runable接口出现的原因,由于,应为Java中类是单继承的,所以当一个类既想作为一个线程也有其他必须要继承的类时,就可以通过实现Runable接口来将需要作为线程执行的部分放入run方法之中)
这里有一个常见的面试题
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("哈哈哈");
}
}) {
public void run() {
System.out.println("呵呵呵");
};
}.start();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
上面的代码运行结果输出的“呵呵呵”,简单的解释一下,上述代码首先创建了一个Thread对象,此时run中输出“哈哈哈”,然后我们通过Thread实现了一个匿名的内部类,这个类的run方法输出“呵呵呵”,最后运行输出的结果就是“呵呵呵”了。
多线程的好处当然是能够更好的利用cpu,但是多线程同样也带来了一些问题,由于同一个进程内的多个线程共享着进程内的资源,当多个线程同时运行时就容易出现共享资源的抢夺,一个常见的情况是多个线程在共同访问一个数据时,A线程正在操作数据,这个时候B线程进入并修改数据,这样会导致产生错误的结果,为了解决线程访问共享资源的问题,Java提供了关键字synchronized,以下提供一个synchronized关键的使用例子:
public class Test {
public static void main(String[] args) {
Example example = new Example();
Thread t1 = new Thread1(example);
Thread t2 = new Thread1(example);
t1.start();
t2.start();
}
}
class Example {
public synchronized void execute() {
for (int i = 0; i < 10; ++i) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Hello: " + i);
}
}
}
class Thread1 extends Thread {
private Example example;
public Thread1(Example example) {
this.example = example;
}
@Override
public void run() {
example.execute();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
上面的代码对于excute方法使用了synchronized修饰,执行结果为先打印一次0-9再打印一次0-9,而去除synchronized关键字后,会同步打印,输出结果为001122…..99。证明synchronized保证了函数被调用后执行完才能被其他调用者再次调用。
当然,处理synchronized方法以外,我们同样可以使用synchronized块来对小部分的代码进行同步,再来一个例子:
public class Test {
private static Test instance;
private Test() {
}
public static Test getInstance() {
if (instance == null) {
//锁是类的字节码文件,由于是静态方法
synchronized (Test.class) {
if (instance == null) {
instance = new Test();
}
}
}
return instance;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
上面的代码是一个典型的使用延迟加载的单例模式类,这种时候当多线程同事调用getInstance方法时,可能出现创建多个实体的情况,这样显然不符合单例模式的思想,所以我们需要在创建实体时加上代码同步。为了避免由于判断加锁和解锁的过程带来的低效,可以再同步部分再次添加判断,避免没有必要的同步。从Java 5 开始,推出了新的同步解决办法Lock。
这部分的内容这里有一个不错的博文,推荐给大家,传送门点这里。
String
String类,作为Java中使用最为频发的几个类之一,有必要好好熟悉一下,String类其实很简单,就是对字符串的封装,以及提供了很多方法方便我们操作字符串。这里整理了一些很好用的,但是可能被大家忽略的方法:
方法作用charAt获取指定位置的字符indexOf顺序获取字符或字符串的位置,没有返回-1lastIndexOf倒序获取字符或字符串的位置,没有返回-1subString获取指定位置的子串contain判断字符串是否包含指定字符串startWith判断字符串是否以指定字符串开头endWith判断字符串是否以指定字符串结尾equalsIgnoreCase判断字符串是否相等,忽略大小写toLowerCase所有字母转换为小写toUpperCase所有字母转换为大写replace替换trim去除字符串首位空格
总结完String的一些方法,这里再简单的提一下StringBuilder和StringBuffer两个类。String是赋值后无法修改的(我们可以看到所有的关于String的操作返回结果都是一个新的String对象而不是原对象),而StringBuilder和StringBuffer是可修改的,这两个类作用类似都用于构建字符串,不同在于:StringBuffer对于多线程是安全的,而StringBuilder对于多线程是不安全的。所以推荐的使用情况如下:
- 单线程操作时推荐使用StringBuilder,效率更高。
- 多线程时操作推荐使用StringBuffer,更加安全。
集合
Java中提供了功能强大的集合类,这里我们对Java中的集合类进行整理:
- Iterator (访问集合的迭代器接口)
- Collection(单列)
- List(有序,可存储重复元素,元素有索引)
- Set(无序,不可存储重复元素,元素都是唯一的)
- Map(双列)
- Hashtable
- TreeMap
List接口下我们经常用到主要为以下几个类:
- ArrayList: 底层数组实现,查询速度很快,线程不同步
- LinkedList:底层链表实现,增删熟读很快,线程不同步
- Vector:底层数组实现,查询增删速度都很慢,线程同步
在通过Iterator对List接口对象进行迭代时,如果想要对集合对象进行操作,会出现ConcurrentModificationException的异常,错误原因是迭代过程中Iterator已经在操作集合对象了,这时我们再去操作集合对象会导致访问冲突。解决办法是使用iterator的子接口ListIterator,这个接口提供了对List集合对象的操作。
注意:由于在List集合中,判断元素是否存在或是删除元素都是通过元素的equals方法,所以在日常的开发过程中,通常需要自己重写集合元素对象的equals方法,这样能够提高List集合的操作效率。
Set接口下我们经常用到主要为以下几个类:
- HashSet:底层数据结构为Hash表,效率高,线程不同步
- LinkedHashSet:HashSet的子类,有序
- TreeSet:底层数据结构为二叉树,可以对之中的数据进行指定顺序的排序,线程不同步
简单介绍一下Hash表是什么:
1.对元素中特有数据进行Hash算法,并得到元素的Hash值
2.Hash值就是这个元素在表中的位置
3.在存储过程中,如果Hash值发生冲突,则需要进行冲突解决,最简单的一个Hash冲突解决办法为再次判断元素是否相同,如果相同则不存储,如果不同则存储,在原元素的Hash值的基础上加1。
(提供一个Hash冲突解决的博文链接)
4.存储Hash值的结构称之为Hash表
5.为了提高效率,应该尽量保证元素关键字的唯一性,这样能够提高Hash表的效率。
TreeSet中的元素需要是可比较的,为了保证元素可比较,需要元素实现Comparable接口,TreeSet中为保证元素的唯一,是通过Comparable接口的toCompare方法来实现的,当toCompare方法返回0时,表示两个元素相同。
Map
Map接口与Collection有很大的区别,Map一次存储一个键值对,并且需要保证Map中所有的健是唯一的。
迭代Map的方法:
- 通过Map.keySet()获取健的Set,然后再遍历时通过getKey方法迭代
- 通过Map.entrySet()方法获取到键值对set,直接遍历。
这里总结一下集合的使用规律:
当需要存储的是单个数据时考虑使用Collection,当需要存储的内容是键值对形式的数据使用Map
- 需要保证内部元素唯一用Set,不要需要使用List
- 看到Array说明底层数据结构是数组,证明查询速度快
- 看到Linked说明底层数据结构是链表,增加删除的速度开
- 看到Hash说明底层数据结构是Hash表,需要尽量保证内部元素的Hash值唯一,并且需要复写元素的hasCode方法和equals方法。
- 看到Tree就说明底层的数据结构是二叉树,需要相当排序,内部元素需要Comparable
泛型
泛型只是针对编译时期,在运行时期并不存在泛型的概念,泛型只是为了将一些类型强制转换的异常转化为编译错误。使用泛型时必须保证等式两边声明的泛型是一样的。
泛型的上限与下限:
- ?extends E 泛型指 接受E和E的所有子类
- ? super E 泛型指接受E和E的所有父类
IO Stream
- 首先明确一下字符流和字节流的区别(这个问题今天早上把我一个电话面阿里的同学给难住了,有必要好好记一下)
- 字节流:字节流可以处理几乎计算机当中的所有数据(凡是以InputStream和OutputStream结尾的都为字节流)
- 字符流:字符流的出现是应为,各个国家的语言不通,字符也不通,所以当将各总编码表和流封装在一起,为了方便字符的操作,所以设计到字符操作的时候优先考虑字符流(凡是以Reader和Writer结尾的都是字符流)
开发的时候如何明确该使用什么样的流呢:
- 如果需要读入数据使用InputStream和Reader,写入数据使用OutputStream和Writer
- 如果需要处理纯文本对象 使用Reader和Writer,否者使用InputStream和OutputStream
- 明确使用那个具体的流,通过明确具体操作的数据设备:(磁盘)File,(内存)CharArray。。。
- 是否需要利用缓存提高效率,如果需要可以使用Buffer对流进再一次的封装。
Java部分到这里基本整理完毕了,4天的时间,也算是查漏补缺,感觉的确再看一遍书又有了一些提高。这里整理的是我不太熟悉的一些知识点,并不一定全面
相关推荐
- 建筑福利-pdf转dwg格式转换器,再也不用描图-极客青年
-
作为一名经常熬夜画图的建筑狗或者cad用户,你体验过pdf图纸描图到cad吗?前几天一个老同学找我,说他的毕业设计需要我帮忙,发给我一份pdf图纸文件,问我怎么把pdf图纸转换成dwg格式。机智的我灵...
- 想学 HTML,不知从何入手?看完这篇文章你就知道了
-
很多人都说HTML是一门很简单的语言,看看书,看看视频就能读懂。但是,如果你完全没有接触过,就想通过看一遍教程,背背标签,想要完全了解HTML,真的有点太天真了。HTML中文...
- 「前端」HTML之结构
-
今天继续为大家分享前端的知识,如果对前端比较感兴趣的小伙伴,可以关注我,我会更大家继续分享更多与前端相关的内容,当然如果内容中又不当的或者文字错误的,欢迎大家在评论区留言,我会及时修改纠正。1.初识H...
- 手把手教你使用Python网络爬虫下载一本小说(附源码)
-
大家好,我是Python进阶者。前言前几天【磐奚鸟】大佬在群里分享了一个抓取小说的代码,感觉还是蛮不错的,这里分享给大家学习。...
- 用于处理pdf文件格式的转换器
-
在上传过程中如果单个文件太大则容易中断,而且文件太大的话对与存储也有些弊端。那么我们应该想到将文件进行压缩(注意这里压缩指的是不改变文件格式的压缩,而不是用变成压缩文件。这里就将以下用专门的软件压缩P...
- 乐书:在线 Kindle 电子书制作和转换工具
-
之前Kindle伴侣曾推荐过可以在Windows和Mac系统平台上运行的kindle电子书制作软件Sigil(教程),用它可以制作出高质量的的ePub格式电子书,当然最后还需要通...
- 付费文档怎么下载?教你5种方法,任意下载全网资源
-
网上查资料的时候,经常遇到需要注册登录或者付费的才能复制或者是下载,遇到这种情况大多数人都会选择重新查。...
- 捡来的知识!3种方法随便复制网页内容,白嫖真香呀
-
网上的资源真的多,所以许多人常常会从网上找资料。我们看到感兴趣的内容,第一时间可能会想要收入囊中。比如说截个图啊,或者挑选有意思的句子复制粘贴,记录下来。可是,有些时候,却会遇到这样的情况:1、内容不...
- AI的使用,生成HTML网页。
-
利用deepseek,豆包,kimi以及通义千问,写入相同的需求。【写一个网页,实现抽奖功能,点击“开始”,按键显示“停止”,姓名开始显示在屏幕上,人员包括:“张三”,“里斯”,“Bool”,“流水废...
- pdf转换成jpg转换器 4.1 官方正式版
-
pdf转换成jpg工具软件简介pdf转换成jpg转换器是一款界面简洁,操作方便的pdf转换成jpg转换器。pdf转换成jpg转换器可以将PDF文档转换为JPG,BMP,GIF,PNG,TIF图片文件。...
- 办公必备的office转换成pdf转换器怎么用?
-
2016-02-2415:53:37南方报道网评论(我要点评)字体刚从校园走出社会,对于快节奏的办公环境,难免会觉得有些吃力。在起步阶段力求将手头上的事情按时完工不出错,但是渐渐的你会发现,别人只...
- 为什么PDF转Word大多要收费?
-
PDF转Word大多都要收费?并非主要是因为技术上的难度,而是基于多方面的商业和版权考虑的,下面给大家浅分析下原因:...
- 如何用python生成简单的html report报告
-
前提:用python写了一个简单的log分析,主要也就是查询一些key,value出来,后面也可以根据需求增加。查询出来后,为了好看,搞个html表格来显示。需要的组件:jinja2flask...
- 学用系列|如何搞定word批量替换修改和格式转换?这里一站搞定
-
想必不少朋友都会碰到批量修改word文档内容、压缩文档图片、文件格式转换等重复性文档处理工作的需要,今天胖胖老师就推荐给大家一个免费工具XCLWinKits,一站搞定你所有的需要。什么是XCLWinK...
- 这款PDF文档转换神器,能帮你解决PDF使用中的许多难点
-
不管是平时的学习还是工作,相信许多朋友都经常接触PDF文件。可以说,PDF文件在我们的日常办公学习过程中的重要性和Word文档一样重要。在之前的更新中,小编介绍了几款非常不错的PDF文档格式转换软件,...
你 发表评论:
欢迎- 一周热门
-
-
前端面试:iframe 的优缺点? iframe有那些缺点
-
带斜线的表头制作好了,如何填充内容?这几种方法你更喜欢哪个?
-
漫学笔记之PHP.ini常用的配置信息
-
其实模版网站在开发工作中很重要,推荐几个参考站给大家
-
推荐7个模板代码和其他游戏源码下载的网址
-
[干货] JAVA - JVM - 2 内存两分 [干货]+java+-+jvm+-+2+内存两分吗
-
正在学习使用python搭建自动化测试框架?这个系统包你可能会用到
-
织梦(Dedecms)建站教程 织梦建站详细步骤
-
【开源分享】2024PHP在线客服系统源码(搭建教程+终身使用)
-
2024PHP在线客服系统源码+完全开源 带详细搭建教程
-
- 最近发表
- 标签列表
-
- mybatis plus (70)
- scheduledtask (71)
- css滚动条 (60)
- java学生成绩管理系统 (59)
- 结构体数组 (69)
- databasemetadata (64)
- javastatic (68)
- jsp实用教程 (53)
- fontawesome (57)
- widget开发 (57)
- vb net教程 (62)
- hibernate 教程 (63)
- case语句 (57)
- svn连接 (74)
- directoryindex (69)
- session timeout (58)
- textbox换行 (67)
- extension_dir (64)
- linearlayout (58)
- vba高级教程 (75)
- iframe用法 (58)
- sqlparameter (59)
- trim函数 (59)
- flex布局 (63)
- contextloaderlistener (56)