【java】初阶总结(干货)--持续更新

Java总结(持续更新)

一、方法重载(overload)总结

  • 应用:在同一个类中,多个功能一样的方法可考虑将他们方法名一致
  • 优点:代码美观,减少代码重复量,提高代码效率
  • 重载条件:同时满足3个条件
    1.位于同一个类中
    2.方法名相同
    3.参数列表不同(参数个数/参数类型/参数顺序)

    注意:
    只有返回值不同----->不算是重载,算是重复,因为JVM无法区别,因为返回值可以不再main函数里面接受。
    只有修饰符不同----->不算是重载,算是重复修饰符(public、static…)。
  • 返回值要求
    主数据类型:必须一致
    引用数据类型:可以变成子类

二、构造函数总结

1.构造方法可以在给对象初始化的时候给对象属性赋值,完成对象的初始化
2.使用new运算符时调用构造函数
3.为防止缺省构造器丢失,需手动写出缺省构造方法
4.实例变量的初始化不是类加载时完成,而是在产生对象进行

三、JVM内存结构总结

JVM中主要的三块内存空间:
1.栈内存:局部变量+方法空间
2.堆内存:存放对象
3.方法区内存:字节码文件(classloader将字节码文件装载到JVM中)
【java】初阶总结(干货)--持续更新_第1张图片【java】初阶总结(干货)--持续更新_第2张图片

四、封装总结

  • 面向对象的三大特征:有了封装才有继承,有了继承才有多态:封装->继承-> 多态
  • 封装定义:通过访问权限控制外部对其内部的访问控制,以保证内部的安全性,内部的复杂不对外部显露,外部只能通过预留的接口对内部进行操作。
  • 封装作用:
    1.保证内部结构的安全。
    2.屏蔽复杂(内部结构),暴露简单(接口)
    对于代码调用者来说,无需care代码如何实现,只需要找到代码接口,便可调用这个代码,实现其功能。
  • 封装步骤:
    1.属性私有化(private私有权限:出了本类,无法被访问)
    2.留下公有接口
    接口:留给外部访问私有属性的间接方法,在此方法中可以检测出外部访问者的操作是否合法。

五、static总结

  • 修饰变量->静态变量
  • 修饰方法->静态方法
  • 修饰类->静态方法
  • 可通过但不依赖对象调用静态变量和静态方法
  • 类中的静态成员变量在内存中只有一份,无论实例化多少个对象,全部共享这一份静态成员变量
  • static方法能调用static方法,能通过对象调用非static方法
    static方法中不能有非static变量
  • 在类被加载时运行且只运行一次
  • static关键字不能修饰方法中的局部变量
    静态变量类加载时初始化,静态变量的内存位于方法区
  • 变量:局部变量+成员变量(实例变量+静态变量)
  • 实例的:对象相关的,只能采用“引用.”去访问,需要先new对象,可能会出现空指针异常,例:实例方法、实例变量
  • 静态的:类相关的,建议采用“类名.”去访问,不需要new对象,不会出现空指针异常,例:静态方法、静态变量
  • 空指针异常:只有在“空引用”访问“实例”相关的,都会出现NullPointerException
  • 静态代码块:
    1.格式:static{Java语句; java语句;}
    2.一个类中可以有多个代码块
    3.静态代码块在类加载时执行,并且只执行一次,在main方法之前执行
    4.作用:可以记录类加载的日志记录----->写在静态代码块中
    5.静态代码块和静态变量都在类加载时执行,时间相同,根据代码先后判断执行顺序
    6.静态变量的内存图解:方法的代码块位于方法区中,但是方法执行就会压栈,静态方法也是如此
    【java】初阶总结(干货)--持续更新_第3张图片

六、this总结:

this指针就是一个指向本对象的指针
this.属性 访问的是自己的属性、
this() 调用自己的无参构造方法
1.this是一个关键字,是一个引用,保存内存地址并指向自身。
2.this可以使用在实例方法中,也可以使用在构造方法中。
3.this出现在实力方法中代表的是当前对象。
4.this不能出现在静态方法中。
5.this. 大部分可以省略,但是用来区分局部变量和实例变量时不能省略
6.this()这种语法只能出现在构造方法第一行,在无参构造方法中可以用this(参数)来调用有参构造函数,这样节省了重复代码。this()---->作用:代码复用
7.this内存图解:
【java】初阶总结(干货)--持续更新_第4张图片【java】初阶总结(干货)--持续更新_第5张图片

七、extends总结

  • 作用:
    1.子类继承父类,代码得到复用
    2.因为继承关系,才有方法覆盖和多态机制
  • 相关特性:
    1.B类继承A类,
    则称A类为超类(superclass)、父类、基类
    则称B类为子类(subclass)、派生类、扩展类
    2.java只支持单继承,不支持多继承(多重继承),但是可以多层继承
    3.子类继承父类,除了构造方法不能继承之外,剩下都可以继承,但是私有属性无法在子类中直接访问。
    4.java中所有的类都继承Object类,Object类是根类
    5.继承缺点是增加类间耦合性,父类改变影响子类
    6.子类拥有父类的非private的属性和方法,同时可以覆盖(方法),或扩展(新增成员)

八、方法覆盖总结

1.方法覆盖:方法重写(Overrider、Overwrite)
2.子类对父类继承过来的方法进行方法覆盖之后,子类对象调用该方法时,一定执行覆盖之后的方法
3.形成方法覆盖条件
(1)两个类有继承关系
(2)重写方法必须与之前方法具有相同的(返回值类型、方法名、形参列表)
(3)访问权限不能更低,可以更高
(4)重写之后的方法不可以抛出更多的异常,可以更少
4.注意事项:
(1)方法覆盖针对方法,和属性无关
(2)私有方法无法覆盖
(3)构造方法无法被继承,所以无从谈起方法覆盖
(4)方法覆盖只针对“实例方法”,“静态方法覆盖”不存在(静态方法执行与对象无关,子类“覆盖”之后还是会执行父类的静态方法)
5.Object类中toString()方法覆盖
(1)toString作用:将“java对象”转换成“字符串形式”
(2)toString原默认方法体:

 public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }

(3)toString方法覆盖(重写一定要复制粘贴)

  public String toString() {
        return year + "年" + month + "月" + day + "日";
    }

6.方法重载和方法覆盖的异同
(1)方法重载发生在同一个类中;方法覆盖发生在两个有继承关系的类中
(2)方法重载是方法名相同,参数列表不同;方法覆盖是方法名相同,参数列表相同

九、多态总结

一、基础语法
1.两个重要概念
向上转型(upcasting):子—>父 (自动类型转换) 向下转型(downcasting):父—>子 (强制类型转换)
无论是向上转型还是向下转型,两个类型之间必须有继承关系
2.允许父类型引用指向子类型对象
Animal animal = new Cat();
3.多态解释:编译时一种形态,运行时一种形态
java程序分为编译阶段和运行阶段
编译阶段:对于编译器来说只知道animal的类型是Animal,所以编译器在检查语法时会去Animal.class文件里寻找方法,字节码文件中若找到方法,便会绑定方法,编译通过,静态绑定成功。(编译阶段属于静态绑定)
运行阶段:堆内存中创建的对象时Cat对象,所以执行方法时,真正参与方法执行的是子类对象,所以运行阶段会动态执行子类对象的方法,这个过程属于运行阶段绑定。(运行阶段绑定属于动态绑定)
若执行的方法是子类特有的方法则无法通过编译阶段(在父类的class文件中找不到该方法—>语法不合法)
向下转型(强转)就可访问子类特有的方法
Cat cat = (Cat)animal;

4.运行时异常:java.lang.ClassCastException---->类转换异常(向下转型的风险)
二、开发中的作用
1.降低程序耦合度,提高程序扩展力:面向父类型编程、面向抽象编程
软件开发原则:对扩展开放,对修改关闭—>目的是降低耦合度提高扩展力

十、instanceof运算符总结

1.避免运行时异常:类转换异常
2.运行阶段动态判断:引用指向的对象的类型
3.返回值为Boolean(true/false)
4.animal instanceof Animal ----> true
5.用法:对类型向下转型时,使用instanceof运算符进行判断,可以避免ClassCastException

十一、super和this总结

super与this关键字的比较

  • this关键字
    1.指向自己的引用
    2.this()调用本类中构造方法时,放在程序首行
    3.this能出现在实例方法和构造方法中,不能出现在静态方法中
    4.this的语法有:“this.”、“this()”
    5.this大部分情况下可以省略,但是在区分局部变量和实例变量时不能省略
    public void setName(String name){
    this.name = name;
    }
  • super关键字
    1.用来引用当前对象的直接父类。
    2.super()调用父类中构造方法时,放在程序首行,先初始化父类特征(有子先有父)
    3.super能出现在实例方法和构造方法中,不能出现在静态方法中
    4.super的语法:“super.”、“super()”
    5.super大部分情况下可以省略,但是父类和子类中有同名的属性或方法,想要在子类中访问父类的同名属性或方法,需要"super."
    6.super在构造函数中默认存在
    7.使用方法:
    super(实参列表)—>调用父类有参构造函数---->由于父类属性为private,无法在子类直接赋值构造
    super.属性名—>访问父类的方法
    super.方法名(实参)—>调用父类方法

十二、final总结

1.final是关键字,代表"最终的,不可变的"
2.修饰变量—>只能赋值一次
修饰方法—>无法被方法覆盖or方法重写
修饰类—>该类无法被继承
修饰对象引用—>其指向不可修改,但是对象内部数据可以修改
3.final修饰的实例变量一般添加static修饰并且访问权限都是public—>public static final联合修饰称为"常量"
4.常量和静态变量一样都是存储在方法区,都是在类加载时初始化,区别在于常量不可变,静态变量可变

十三、抽象类总结

1.概念:类与类之间具有共同特征,将这些共同特征提取出来,形成的就是抽象类,抽象类本身并不存在,所以无法创建对象进行实例化
2.抽象类属于引用数据类型
3.语法:
[修饰符列表] abstract class 类名{
类体;
}
4.final与abstract是对立的,无法同时使用
5.抽象类必须被继承,其子类也可以是抽象类,也可以是非抽象类
6.抽象类可以有构造方法供给子类使用
7.抽象方法:没有方法体的方法
例:public abstract void doSome();
8.抽象类中不一定有抽象方法,但是抽象方法必须位于抽象类中
9.抽象类的子类必须对抽象类中的抽象方法进行覆盖/重写/实现
面试题:java语言中凡是没有方法体的方法都是抽象方法?
答:错误的,native关键字修饰的方法就是底层调用C++写的动态链接库程序
例如:public native int hashCode();
10.抽象类并不完全抽象

十四、接口总结

1.接口是一种"引用数据类型"
2.接口是完全抽象的
3.接口定义语法:
[修饰符列表] interface 接口名{…}
4.接口可以继承,并且支持多继承,弥补了java中的类只支持单继承的缺陷
5.接口中只有:常量、抽象方法(不能有方法体)
6.接口中的所有元素都是public修饰
7.常量的public static final可以省略
抽象方法的public abstract可以省略
8.类与类之间称作继承(extends),类与接口之间称作实现(implements)
非抽象类实现接口时,必须将接口中的所有方法实现
9.一个类可以实现多个接口
10.extends和implements可以共存,extends在前
11.使用多态:接口类型引用指向子类型对象
12.接口A和接口B之间无继承关系,但是可以强制转换,编译可通过,但是运行可能会出现ClassCastException
13.接口在开发中的作用:
java中要求:面向抽象编程—>面向接口编程
接口使实现者与调用者解耦合

十五、抽象类与接口的区别总结

1.抽象类是半抽象的,接口是完全抽象的
2.抽象类中可有构造方法,接口中不可有构造方法
3.抽象类只能单继承,接口可以多继承
4.一个类只能继承一个抽象类,一个类可以实现多个接口

十六、类中的接口:

1.私有属性的set和get方法
set方法:在set中设立关卡可以防止用户的非法输入

public void set 属性名首字母大写(1个参数){
   XXX = 参数;
}
get方法:
public int get 属性名首字母大写(){
    return XXX;
}

2.接口都有调用者和实现者:面向接口调用、面向接口写实现类,这都属于面向接口编程
为什么要面向接口编程?
解耦合:降低程序耦合度,提高程序可扩展性
多态机制就是非常典型的面向抽象编程(不要面向具体编程)

 建议:
Animal a = new Cat();
Animal b = new Dog();
//喂养方法
public void feed(Animal a){//面向父类型编程
}

不建议:
Dog d = new Dog();
Cat c = new Cat();

十七、is-a、has-a、like-a关系

is-a: 继承关系(继承)----->Cat is a animal ---->A extends B
has-a: 属性关系(属性)—>I has a pen ---->A{B b;}
like-a: 实现关系(接口)—>Cooker like a FoodMenu ----> A implements B

十八、package和import总结

  • package:
    1.package是java中的包机制,作用是为了方便程序的管理,不同功能的类分别放在不同包下
    2.用法:package+包名
    出现在程序第一行
    3.命名规范:采用公司域名倒叙(公司域名具有全球唯一性)
    公司域名倒叙 + 项目名 + 模块名 + 功能名
    4.带有package的程序运行与编译
    运行:javac -d . HelloWorld.java
    -d带包编译
    .编译之后的东西放入当前目录
    编译:java com.bjpowernode.javase.chapter17.HelloWord
  • import
    1.将程序中需要且不存在于当前目录下的类导入,可以正常使用
    2.import语句位于package与class之间

十九、访问控制权限总结

public--------->表示公开的,在任何位置都可以访问
protected----->表示受保护,只能在本类、同包、子类中访问
default-------->表示默认的,只能在本类、同包中访问
private-------->表示私有的,只能在本类中访问

二十、内部类总结

1.内部类:在类的内部又定义一个新的类,被称为内部类
2.分类:
静态内部类:类似于静态变量
实例内部类:类似于实例变量
局部内部类:类似与局部变量
3.内部类编写的代码可读性很差

二十一、数组总结

1.数组是一种引用数据类型,父类是Object
2.数组中可以存储基本数据类型(内容),也可以存储引用数据类型(对象地址)
3.数组对象处于堆当中
4.数组一旦创建,在Java中规定:数组长度不可变
5.数组自带length属性,可以求数组长度
6.数组的优点、缺点、注意:
优点:检索效率高
缺点:随机增删效率较低,数据无法存储大数据量。
注意:数组最后一个元素的增删效率不受影响

7.数组是什么?(面试这样回答)
第一、空间存储上,内存地址是连续的
第二、每个元素占用的空间大小相同
第三、知道首元素的内存地址
第四、通过下标可以计算出偏移量
通过数组下标和数据类型可以计算出某一个元素的内存地址,效率很高

8.一、二维数组的静态初始化、动态初始化
静态初始化:
一维

int[] arr = {1, 2, 3};
Object[] objs = { new Object(), new Object(), new Object() };

二维

int[][] arr = {
    {1, 2, 3},
    {1, 2, 2, 5},
    {2, 5, 9, 6, 3}
};
Object[][] objs = {
    {new Object(), new Object(), new Object() },
    {new Object(), new Object()},
    {new Object()}
};

动态初始化:
一维

int[] arr = new int[4];    //4个长度,每个元素默认为0
Object[] objs = new Object[4];    //4个长度,每个元素默认值为null

二维

int[][] arr =new int[3][4];
Object[][] arr = new Object[4][4];
Animal[][] animal = new Animal[3][4];    
//既可以存储Animal对象,也可以存储Animal的子类对象

9.一维数组的遍历:
一维:

for( int i = 0; i < arr.length; i++){
    System.out.println( arr[i] );
	}

二维:

for(int i = 0; i < arr.length; i++){
	for(int j = 0; j < arr[i].length; j++){
		System.out.print(arr[i][j]);
	}
	System.out.println();
}

10.main方法上"String[] args"参数:运行程序之前需要输入的字符串,可以用来判断是否具有使用该程序的权限
11.数组的拷贝:String.arraycopy()方法的使用
数组有一个特点:长度一旦确定,不可变
所以数组长度不够时,需要扩容,扩容的机制是:新建一个大数据,将小数组中的数据拷贝到大数组,然后小数组对象被垃圾回收
12.数组内存结构:
【java】初阶总结(干货)--持续更新_第6张图片

二十二、String字符串总结

1.字符串的动态创建、静态创建
动态创建:String str = new String(" abc "); ----->垃圾回收器会回收
静态创建:String str = " abc "; ----->垃圾回收器不会回收
2.字符串的存储位置
动态创建:字符串引用位于栈中(存储字符串对象的地址),字符串对象位于堆中(存储字符串内容的地址),字符串内容位于方法区中的字符串常量池中
静态创建:字符串引用位于栈中(存储字符串对象的地址),字符串内容位于方法区中的字符串常量池中
3.静动态创建相同字符串的异同
静态创建:str1和str2中存储的地址一模一样,都是位于字符串常量池中"abc"的地址。

String str1 = "abc";
String str2 = "abc";

动态创建:str1和str2中存储的地址不一样,分别是位于堆上的不同字符串对象

String str1 = new("abc");
String str2 = new("abc");

4.字符串内容比较使用:equals()方法
例如:

str1.equals(str2);
"hello".equals(str1);   --->可以避免空指针异常

5.面试题:

String str1 = new("abc");
String str2 = new("abc");

一共产生了3个对象:字符串常量池中一个,堆上两个String对象

二十三、常用的String构造方法

第一个: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数组,起始下标,长度);

二十四、String类中常用方法

1、(掌握)char charAt( int index )
作用:获取指定位置字符

char c = "中国人".charAt(1);
System.out.println(c);//国

2、(了解)int compareTo(String anotherString)
作用:比较字符串的大小
字符串之间比较大小不能直接使用 “<”">",需要使用compareTo方法。

int result = "abc".compareTo("abc");
System.out.println(result); 
//0(等于0) 前后一致  10 - 10 = 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、(掌握)boolean contains(CharSequence s)
作用:判断前面的字符串中是否包含后面的子字符串。

System.out.println("HelloWorld.java".contains(".java")); // true
System.out.println("http://www.baidu.com".contains("https://")); // false

4、(掌握) boolean endsWith(String suffix)
作用:判断当前字符串是否以某个子字符串结尾。

System.out.println("test.txt".endsWith(".java")); // false
System.out.println("test.txt".endsWith(".txt")); // true
System.out.println("fdsajklfhdkjlsahfjkdsahjklfdss".endsWith("ss")); // true

5、(掌握)boolean equals(Object anObject)
作用:比较两个字符串必须使用equals方法,不能使用“==”
equals只能看出相等不相等,
compareTo方法可以看出是否相等,并且同时还可以看出谁大谁小。

System.out.println("abc".equals("abc")); // true

6、(掌握)boolean equalsIgnoreCase(String anotherString)
作用:判断两个字符串是否相等,并且同时忽略大小写。

System.out.println("ABc".equalsIgnoreCase("abC")); // true

7、(掌握)byte[] getBytes()
作用:将字符串变成字节数组,数组中存放的是对应字符串中字符的数值,例如,a----97; b----98

byte[] bytes = "abcdef".getBytes();
        for(int i = 0; i < bytes.length; i++){
            System.out.println(bytes[i]);
        }
//bytes[] = {97,98,99,100,101,102}

8、(掌握).int indexOf(String str)
作用:判断某个子字符串在当前字符串中第一次出现处的索引(下标)。

System.out.println("oraclejavac++.netc#phppythonjavaoraclec++".indexOf("java")); // 6

9、(掌握)boolean isEmpty()
作用:判断某个字符串是否为“空字符串”。底层源代码调用的应该是字符串的length()方法。

String s1 = "";
String s2 = "a";
System.out.println(s1.isEmpty());//true
System.out.println(s2.isEmpty());//false

10、(掌握) int length()
面试题:判断数组长度和判断字符串长度不一样
判断数组长度是length属性,判断字符串长度是length()方法。

System.out.println("abc".length()); // 3
System.out.println("".length()); // 0

11、(掌握)int lastIndexOf(String str)
作用:判断某个子字符串在当前字符串中最后一次出现的索引(下标)

System.out.println("oraclejavac++javac#phpjavapython".lastIndexOf("java")); //22

12、(掌握). String replace(CharSequence target, CharSequence replacement)
作用:将某段子字符串替换成另一个字符串替换
String的父接口就是:CharSequence

String newString = "http://www.baidu.com".replace("http://", "https://");
System.out.println(newString); //https://www.baidu.com
//把以下字符串中的“=”替换成“:”
String newString2 = "name=zhangsan&password=123&age=20".replace("=", ":");
System.out.println(newString2);     //name:zhangsan&password:123&age:20

13、(掌握).String[] split(String regex)
作用:按照某个字符拆分字符串

String[] ymd = "1980-10-11".split("-"); //"1980-10-11"以"-"分隔符进行拆分。
for(int i = 0; i < ymd.length; i++){
    System.out.println(ymd[i]);
}
String param = "name=zhangsan&password=123&age=20";
String[] params = param.split("&");
for(int i = 0; i <params.length; i++){
      System.out.println(params[i]);    // 可以继续向下拆分,可以通过“=”拆分。
}

14、(掌握)、boolean startsWith(String prefix)
作用:判断某个字符串是否以某个子字符串开始。

System.out.println("http://www.baidu.com".startsWith("http")); // true
System.out.println("http://www.baidu.com".startsWith("https")); // false

==15、(掌握)String substring(int beginIndex) ==
参数是起始下标
作用:从某一个位置开始截取后面字符串

System.out.println("http://www.baidu.com".substring(7)); //www.baidu.com

16、(掌握)String substring(int beginIndex, int endIndex)
作用:将某一段子字符串变变成新字符串
beginIndex起始位置(包括)
endIndex结束位置(不包括)

System.out.println("http://www.baidu.com".substring(7, 10));  //www

17、(掌握)char[] toCharArray()
作用:将字符串转换成char数组

char[] chars = "我是中国人".toCharArray();
for(int i = 0; i < chars.length; i++){
    System.out.println(chars[i]);
}
//chars[] = {'我','是','中','国','人'}

18、(掌握)String toLowerCase()
作用:将字符串全部变成小写

System.out.println("ABCDefKXyz".toLowerCase());
//abcdefkxyz

19、(掌握)String toUpperCase();
作用:将字符串全部变成大写

System.out.println("ABCDefKXyz".toUpperCase());
//ABCDEFKXYZ

20、(掌握)String trim();
去除字符串前后空白

System.out.println("           hello      world             ".trim());    //hello      world

21、(掌握) String中只有一个方法是静态的,不需要new对象
这个方法叫做valueOf,作用:将“非字符串”转换成“字符串”

String s1 = String.valueOf(true);
String s1 = String.valueOf(100);
String s1 = String.valueOf(3.14);·

你可能感兴趣的:(JavaSE,字符串,多态,编程语言,java,面试)