超详细java进阶知识点笔记

java进阶

  • 一、final关键字
    • 1.对final的基本认识
    • 2.被final修饰后的特点
  • 二、常量
    • 1.final和static结合
    • 2.存储
  • 三、抽象类
    • 1.类与对象
    • 2.抽象类
    • 3.抽象方法
    • 4.抽象的意义
  • 四、接口
    • 1.接口的初步认识
    • 2.接口的实现
    • 3.接口的常见异常(ClassCastException)
    • 4.接口的意义
    • 5.类和类之间的关系
    • 6.抽象类和接口的语法上区别:
  • 五、包机制
    • 1.使用的原因:
    • 2.使用方法:
    • 3.命名规范
    • 4.import机制
  • 六、访问控制权限
    • 1.访问控制权限
    • 2.权限的大小比较
    • 3.访问控制权限修饰符可以修饰什么
  • 七、object类
    • 1.初步认识
    • 2.API
    • 3.object中的方法
  • 八、内部类
    • 1.普通内部类
  • 九、数组
    • 1.初步认识
    • 2.数组的优缺点
    • 3.数组的声明
    • 4.数组的初始化
    • 5.每个类型的默认值
    • 6.一维数组动态初始化的内存图
    • 7.方法参数是数组
    • 8.数组的扩容
    • 9.二维数组
    • 十、Arrays工具类
    • 1.sort()
    • 2.binarySearch()
  • 十一、String字符串
    • 1.String字符串的存储原理
    • 2.String的面试题
    • 3.常用的构造方法
    • 4.String的常用方法
    • 2.读入数据

一、final关键字

1.对final的基本认识

  1. final是java中的一个关键字
  2. final表示最终的,不可变的
  3. final可以修饰变量以及方法,还有类

2.被final修饰后的特点

  1. final修饰的类不能被继承
  2. final修饰的方法不能被覆盖,重写
  3. final修饰的变量: final修饰的局部变量一旦赋值就 不能重新赋值,final修饰的变量只能赋一次值
  4. final修饰引用只能指向一个对象,并且不能再改变
    注意:
    final修饰的引用:
    该引用只能指向1个对象,并且它只能永远指向该对象,无法再指向其它对象。并且在该方法执行过程中,该引用指向对象之后,该对象不会被垃圾回收器回收。直到当前方法结束,才会释放空间。
    虽然final的引用指向对象A后,不能再重新指向对象B。但是对象A内部的数据可以被修改。
  5. final修饰的实例变量,系统不管赋默认值,要求程序员必须手动赋值,实例变量是在默认构造方法里赋值

二、常量

1.final和static结合

static final联合修饰的变量称为“常量”,
常量名建议全部大写,每个单词之间采用下划线衔接。

代码如下(示例):

//定义常量π的值
public static final double PI = 3.1415926;

2.存储

常量存储在方法区,在类加载时初始化,不能再改变,常量一般是公开的。

三、抽象类

1.类与对象

类在现实世界中不存在的,是抽象总结的结果;对象是现实世界中存在的。
类是对象的抽象,对象是类的实例化。
而抽象类可以被看做类的抽象

2.抽象类

  1. 什么是抽象类: 类和类之间具有共同特征,将这些共同特征提取出来,形成的就是抽象类。类本身是不存在的,所以抽象类无法创建对象“无法实例化”。
  2. 抽象类属于什么数据类型: 抽象类也属于引用数据类型
  3. 抽象类的基础语法: [修饰符]abstract class 类名{类体}
  4. final和abstract不可以同时使用,两者是对立的
  5. 抽象类的子类也可以是抽象类
  6. 抽象类没有实例化的,但是有构造方法,构造方法给子类使用

3.抽象方法

  1. 什么是抽象方法: 抽象方法表示没有实现的方法;没有方法体的方法。
  2. 语法定义:
    [修饰符] abstract 返回类型 方法名;
  3. 特点:
    1.没有方法体,以分号结尾。
    2.需要用abstract关键字修饰
  4. 抽象类中不一定有抽象方法,抽象方法必须出现在抽象类中
  5. 非抽象类继承抽象类,一定要将抽象的方法实现
  6. 没有方法体不一定是抽象方法,例如:object中native修饰的,调用C++程序 调用JVM本地程序

4.抽象的意义

  1. 面向抽象编程,不要面向具体编码,降低程序的耦合度,提高程序的扩展力
  2. 抽象类专门用来继承: 只有方法名没有方法体节省空间

四、接口

1.接口的初步认识

  1. 接口是一种”引用数据类型"。编译之后也是一个class字节码文件。
  2. 接口是完全抽象的。
  3. 接口怎么定义,语法是什么:
    [修饰符列表] interface 接口名 {}
  4. 接口支持多继承。
  5. 接口中只有常量+抽象方法。
  6. 接口中所有的元索素都是public修饰的
  7. 接口中抽象方法的public abstract可以省略。
  8. 接口中的方法都是抽象方法,所以接口中的方法不能有方法体。
  9. 接口中常量的public static final可以省略。
  10. 类实现接口必须实现所有的抽象方法。

2.接口的实现

  1. 类和类之间叫做继承,类和接口之间叫做实现:
    继承:extends 实现:implement
  2. 一个类可以同时实现多个接口
  3. 继承和实现都存在的话,代码应该怎么写?
    extends关键字在前.
    implements关键字在后。

3.接口的常见异常(ClassCastException)

接口A和接口B虽然没有继承关系,但是写代码的时候,可以互转。编译器没意见。但是运行时可能出现: classCastException,类型转换异常
所以:
向下转型养成好习惯。转型之前先if+instanceof进行判断。

4.接口的意义

  1. 弥补了类之间的单继承,可以多个实现
  2. 接口是完全面向抽象编程
  3. 面向接口编程,降低耦合度,提升拓展力,要和多态一起用
  4. 主要三部分定义接口,接口的实现,接口的调用

5.类和类之间的关系

类型和类型之间的关系:
is ahas alike a
is a:
凡是能够满足is a的表示"继承关系"
has a:
凡是能够满足has a关系的表示"关联关系"关联关系通常以"属性”的形式存在。
like a :
凡是能够满足like a关系的表示”实现关系"
实现关系通常是:类实现接口

6.抽象类和接口的语法上区别:

  1. 抽象类是半抽象的,接口是全抽象的
  2. 抽象类中有构造方法,接口中没有构造方法
  3. 接口和接口之间支持多继承
  4. 类和类之间只能单继承
  5. 一个类可以同时实现多个接口,一个类只能继承一个抽象类
  6. 接口中只允许出现常量和抽象方法

五、包机制

1.使用的原因:

package是java中的包机制。包机制的作用是方便程序的管理;不同的功能放在不同的包下(按照功能划分的,不同的软件包具有不同的功能)

2.使用方法:

package是一个关键字,后面加包名,只出现在java员代码的第一行。
语法:package+包名

3.命名规范

一般都采用公司域名倒序的方式
包名命名规范:
公司域名倒序+项目名+模块名+功能名

4.import机制

A中使用B类,而B和A不在一个包内时使用
lang包下不需要导入
一般编程工具能自动导入包

六、访问控制权限

1.访问控制权限

private 私有
protected受保护的
public 公开的
默认的

2.权限的大小比较

“默认”表示只能在本类和同包下访问
protected在本类和同包以及子类中访问
public表示公开,任何位置可以访问
private 只能在本类中
超详细java进阶知识点笔记_第1张图片

3.访问控制权限修饰符可以修饰什么

属性(4个都能用)
方法(4个都能用)
类public和默认能用,其它不行。
接口(public和默认能用,其它不行。

七、object类

1.初步认识

object是jdk类库中的根类,任何一个类都默认继承Object,就算没有直接继承,最终也会间接继承

2.API

应用程序编程接口(Application Program Interface)整个JDK的类库就是一个javase的API。
每一个API都会配置一套API帮助文档

3.object中的方法

toString方法:
1.源码:


public string toString ()
 {
 return this.getclass().getName() + "@" + Integer.toHexString(hashcode());}
 

源代码上toString()方法的默认实现是:
类名@对象的内存地址转换为十六进制的形式
2.设计目的:
通过调用这个方法可以将一个java对象转换成字符串表示,通过子类的重写实现
直接输出对象的话,会调用这个方法

equals方法:
1.源码:

public boolean equals (object obj){
return (tnis == obj) ;}

2.设计目的:
以后编程的过程当中,都要通过equals方法来判断两个对象是否相等。ecuals方法是判断两个对象是否相等的。
3.默认的equals方法是不够用的:
在object类中的equals方法当中,默认采用的是"==",判断的是两个java对象的内存地址,我们应该判断两个java对象的内容是否相等。所以object 的equals方法不够用,需要子类重写equals。

String类已经重写了equals方法,所以字符串比较用equals方法,可以比较出数值相等,String也重写了toString方法。
所以:
java中基本数据类型比较是否相等,使用“==”。
java中所有的引用数据类型统一使用equals方法来判断是否相等。

finalize()方法
1、在object类中的源代码:

protected void finalize()throws Throwable
 { }

2、finalize()方法只有一个方法体,里面没有代码,而且这个方法是protected修饰的
3、这个方法不需要程序员手动调用,JVM的垃圾回收器负责调用这个方法。
4、finalize方法的执行时机:
当一个java对象即将被垃圾回收器回收的时候,垃圾回收器负贲调用finalize()方法。
5、finalize()方法实际上是SUN公司为java程序员准备的一个时机,垃圾销毁时机。如果希望在对象销毁时机执行一段代码的话,这段代码要写到finalize()方法当中。
6、静态代码块的作用是什么?
static {
}
静态代码块在类加载时刻执行,并且只执行一次。这是一个SUN准备的类加载时机,finalize()方法同样也是SUN为程序员准备的一个时机。这个时机是拉圾回收时机。
7.可以实现:记录对象释放的时间
8.java中的垃圾回收器不是轻易使用的,没满和没到时间可能使用也可能不使用,可以通过

System.gc();//建议启动立即回收器,
//只是建议也不一定能启动

hashCode()方法

1.在object中的hashcode方法:

public native int hashCode () ;

这个方法不是抽象方法,带有native关键字,底层调用c++程序。
2.hashCode0方法返回的是哈希码:
实际上就是一个java对象的内存地址,经过哈希算法,得出的一个值。所以hashcode()方法的执行结果可以等同看做一个java对象的内存地址。

八、内部类

1.普通内部类

class Test01{
//该类在类的内部,所以称为内部类
//由于前面有static,所以称为"静态内部类"
static class Inner1{
}
//没有static叫做"实例内部类"。
class Inner2 {
}
public void dosome (){
//局部变量
int i=100;
//该类在类的内部,所以称为内部类
//局部内部类。
class Inner3 {}
)

2.匿名内部类:
直接在参数位置就new出对象,不需要名字;一般用在对接口的实现上。
但一般不建议使用,可读性太差

 play(new Compute () {
pubiic int sum(int a , int b){
return a +b;
}
}, 200,300) ;

九、数组

1.初步认识

1.java语言中的数组是一种引用数据类型,不属于基本数据类型,数组的父类是object
2.数组实际上是一个容器,可以同时容纳多个元素(数组是一个数据的集合)
3.数组当中可以存储基本数据类型的数据,也可以存储引用数据类型的数据
4.数组因为是引用类型,所以数组对象存储在堆内存中
5.数组当中如果存储“java对象”的话,实际上存储的对象的“引用”,不能直接存储java对象
6.数组一旦创建,在java中规定,长度不变
7.数组的分类:一维二维……
8.所有数组都有对象都有length属性(java自带),用来获取数组中元素的个数
9.java中的数组要求数组中的元素的类型统一
10.数组在内存中存储的时候,数组的元素内存地址是连续的
11.所有的数组都是拿第一个小方框的内存地址作为整个数组的内存地址(数组中的首元素的内存地址作为整个数组对象的内存地址)
12.数组每一个元素都是有下标的(下表非常重要,“存取”需要下标)

2.数组的优缺点

优点:
查询/查找/检索某个下标上的元素时效率极高。可以说是查询效率最高的一个数据结构。
原因:
第一:每一个元素的内存地址在空间存储上是连续的。
第二:每一个元素类型相同,所以占用空间大小一样。
第三:知道第一个元素内存地址,知道每一个元素占用空间的大小,又知道下标,所以通过一个数学表达式就可以计算出某个下标上元素的内存地址。查接通过内存地址定位元素,所以数组的检索效率是最高的。
数组中存储100个元素,或者存储100万个元素,在元素查询/检索方面,效率是相同的,因为数组中元素查找的时候不会一个一个找,是通过数学表达式计算出来的。(算出一个内存地址,直接定位的。)

缺点:
第一:由于为了保证数组中每个元素的内存地址连续,所以在数组上随机删除或者增加元素的时候,效率较低,因为随机增删元素会涉及到后面元素统一向前或者向后位移的操作。
第二:数组不能存储大数据量,
因为很难在内存空间上找到一块特别大的连续的内存空间。

3.数组的声明

语法格式:
数据类型[ ]数组名

4.数组的初始化

包括两种方式:静态初始化一维数组,动态初始化一维数组。
静态初始化语法格式:
int[ ] array = {100,2100,300,55};
动态初始化语法格式:
int[ ] array = new int[5];//这里的5表示数组的元素个数。
//初始化一个5个长度的int类型数组,每个元素默认值0
String[] names = new String[6];/初始化6个长度的String类型数组,每个元素默认值null。

5.每个类型的默认值

超详细java进阶知识点笔记_第2张图片

6.一维数组动态初始化的内存图

超详细java进阶知识点笔记_第3张图片
什么时候采用静态初始化方式,什么时候使用动态初始化方式呢?
当你创建数组的时候,确定数组中存储哪些具体的元素时,采用静态初始化方式。
当你创建数组的时候,不确定将来数组中存储哪些数据,你可以采用动态初始化的方式,预先分配内存空间。

7.方法参数是数组

1.传数组名
2.直接new一个数组

8.数组的扩容

在java开发中,数组长度一旦确定是不可变,
java中对数组的扩容是:
先新建一个大容量的数组,然后将小容量数组中的数据一个一个拷贝到大数组当中。

具体扩容方法:

//示例
 int []a={1,2,3};
        int []b=new int[9];
        System.arraycopy(a,0,b,0,3);
        for(int i=0;i<b.length;i++){
            System.out.print(b[i]);}
//结果为123000000

语法格式:
System.arraycopy(src,srcPos, dest,destPos,length);

src:要扩容的数组名
srcPos:从哪个元素开始copy,索引下标
dest:容量更大的数组名
destPost:从哪个位置开始插入
length:要复制的长度

内存图:
超详细java进阶知识点笔记_第4张图片

9.二维数组

1.二维数组其实是一个特殊的一维数组,每个元素是一维数组
2.静态初始化
3.经常使用一维数组,很少使用二维数组
4.二维数组的length:
int [][]a={{100,200,300},{30,20,40,50,60}{6,7,9,1},{0}}

a.length=4;//行数,也可以理解为含有的一维数组个数
a[0].length=3//表示这行的列数,表示一维数组的元素个数

遍历二维数组:

//遍历二维数组
for(int i = 0; i < array.length; i++){ //外层循环3次。(负责纵向。)
String[]一维数组=array[i];
//负责逼历一维数组
for(int j= e; i<一维数组.1ength; j++){
system.out.println(一维数组[i]+"");
}
//输出换行符
System.out.println();
}

十、Arrays工具类

1.sort()

Arrays.sort(数组名),从小到大排序

2.binarySearch()

Arrays.binarySearch(数组名,要查找的值),返回下标

十一、String字符串

1.String字符串的存储原理

字符串常量池在方法区,一旦创建不可变。

String s1 = “abcdef” ;
String s2 = “abcdef” +“xy” ;
内存地址表示:
超详细java进阶知识点笔记_第5张图片

String s3=new String(“xy”);
内存地址表示:
超详细java进阶知识点笔记_第6张图片

2.String的面试题

1.经典判断题:
String s1 = “hello”;
String s2 = “hello”;
System.out.println(s1 ==s2);

//分析结果是true还是false ?

结果为true,“hello”在字符串常量池中,不会再新建了,地址是一样的

String x = new String( “xyz”);
String y = new String( “xyz”);
System.out.println(x == y);
//分析结果是true还是false

结果为false,在堆中新建了x,y对象,他们之间的地址是不同的
2.代码:
String x = new String( “xyz”);
String y = new String( “xyz”);
请问创建了几个对象?
答:一共三个;方法区中字符串常量池中有一个“hello”,堆中还有两个对象

3.常用的构造方法

第一个 : String s = new String(" “);
第二个: String s =” ";//最常用
第三个: String s = new String(char数组);
第四个: String s = new String(char数组,起始下标,长度);
第五个: String s = new String(byte数组);
第六个: String s = new String(byte数组,起始下标,长度)

4.String的常用方法

1.charAt
返回一个字符

char c ="中国人".charAt(1);//索引从零开始
 System.out.println(c);//国

2.compareTo
int compareTo(String anotherString)

int result = "abe".compareTo("abe");
System.out.println(result);
 //0(等于0)前后一致
int result2 = "abcd".compareTo("abce");
System.out.println(result2);
//-1 (小于0)前小后大8 - 9 = -1
int result3 = "abce".compareTo("abcd");
System.out.println(result3); 
// 1 (大于0 )前大后小9- 8 =1

//拿着字符串第一个字母和后面字符串的第一个字母比较。能分胜负就不再比较了。
System.out.println("xyz".compareTo("yxz"));// -1

3.contains
booLean contains( CharSequence s)

//判断前面的字符串中是否包含后面的子字符串。
System.out.println("Helloword.java".contains(".java")); // true
System.out.println("http://www.baidu.com".contains("https://")); //false

4.endsWith
booLean endswith(String suffix)

//判断当前字符串是否以某个字符串结尾。
System.out.println("a.txt".endswith(".java"));//false
System.out.println("test.txt".endswith(".txt")); // true

5.getByte
byte[] getBytes()

//将字符串对象转换成字节数组
byte[]bytes = "ab".getBytes();
for(int i = 0; i < bytes.length; i++){
System.out.println(bytes[i]);}

6.indexof
int indexof(String str)

//判断某个子字符串在当前字符串中第一次出现处的索引(下标)。
System.out.println("javac++java".indexof("java"));
//结果为0

7.isEmpty
boolean isEmpty()

//判断某个字符串是否为“空字符串。底层源代码调用的应该是字符串的Length()方法。
String s = "a" ;
System.out.println(s.isEmpty());//false

8.lenght
int length();
数组中length是属性,字符串中是方法
9.replace

String replace(CharSequence target,CharSequence repLacement)

String newString = "http: / /www.baidu.com".replace(target:"http://",replacement:"https://");
System.out.println(newString); //https ://www.baidu.com

10.split
String[ ] split(String regex)

//拆分字符串
String[] ymd = "1980-10-11".split( regex: "-");//"1980-10-11"以"-"分隔符进行拆分。
for( int i = 0; i <ymd.length; i++){
System.out.println(ymd[i]);}
//1980
//10
//11

2.读入数据

代码如下(示例):

data = pd.read_csv(
    'https://labfile.oss.aliyuncs.com/courses/1283/adult.data.csv')
print(data.head())

你可能感兴趣的:(java基础学习,java,开发语言,后端)