• 【Java SE】SE“细节”知识大总结


    目录

    1.初识JAVA

            1.1环境配置时JDK、JRE、JVM之间是什么关系?

            1.2Java代码运行过程

            1.3一个简单Java程序的解释

             1.4什么叫“一次编译,到处运行”?

            1.5注释常见错误

            1.6标识符

            1.7关键字

    2.数据类型

            2.1基本数据类型

            2.2.引用型数据类型

            2.3.不同数据类型解析

                    要注意以下这些不同点:

                    整形(int):

                    长整形(long):

                    短整型(short):

                    字节型(byte):(可以为类比char)

                    问答:

                    单精度浮点型(float):

                     双精度浮点型(double):

                    字符型(char):

            布尔类型(boolean):

            2.4类型转换

                     自动类型转换(隐式):

                    强制类型转换(显式):

                     字符串类型(String):

    3.运算符常见易错点

            3.1 + - * /

            3.2 x=x+1与x+=1

     ​                        编辑

            3.3 > < >= <= == !=

            3.4 && 和 ||

            3.5 无符号右移

            3.6条件运算符(三目运算符)经典面试题

    4.逻辑控制(猜数字游戏)

    5.方法重载

            5.1形参与实参的关系,如何开辟空间?

    6.数组

            6.1数组的三种访问方式

            6.2数组名作为参数传参,以及内存布局

            6.3 对于数组,Java带来的一些便捷(import java.util.Arrays;)

                    6.3.1 数组拷贝(Arrays.copyOf)

                    6.3.2字符串形式返回数组(Arrays.toString)

                    6.3.3数组排序(Arrays.sort)

                    6.3.4指定范围的数组拷贝(Arrays.copyOfRange)

                    6.3.5数组比较(Arrays.equals)

            6.4二维数组

                    有以下三种定义方式:(未定义默认初始化为0,引用类型为:NULL)

                    三种不同的遍历方式:

                    对二维数组遍历的解释:

                    不规则二维数组:

     7.类和对象(一个例子轻松理解~)

             7.1this

            7.2构造

                    7.2.1 构造重载

    8.static修饰的静态变量

            8.1类变量和类方法

            8.2代码块

    9.内部类

            9.1实例内部类

            9.2静态内部类

            9.3局部内部类

    10.封装、继承、多态

    11.抽象类(abstract)

    12.接口

            12.1制作一个简单的比较器

    13.浅拷贝和深拷贝

    14.Object类

    15.String类

            15.1字符串常量池 

            15.2面试题:请解释String类中三种实例化对象的区别

                    15.3.1 字符串比较是否相同(equals())

                    15.3.2字符串比较大小(compareTo())

                    15.3.3忽略大小写比较是否相同(equalsIgnoreCase())

                    15.3.4KMP算法查找字符或字符串(indexOf())

                    15.3.5将其他类型相互转化(其他类型.valueOf())

                    15.3.6小写转大写(toUpperCase())

                    15.3.7大写转小写(toLowerCase())

                    15.3.8字符串转字符数组(toCharArray())

                    15.3.9字符串切割(split())

                     15.3.10字符串替代(replaceFirst())

                    15.3.11拿到字符串中的每一个字符(charAt())

    16.异常处理

            16.1try-catch-finally(捕获并处理)

            ​​​​​​​16.2自定义异常




    高老爷子保佑!!!

    36475b3902aa45f6bdfb51e414948e38.png



    1.初识JAVA

    1.1环境配置时JDK、JRE、JVM之间是什么关系?

    e130f0c1a3824d1da4badf75ace0da65.png

    62a8070ad6284798ae920b57c2033d31.png


    1.2Java代码运行过程

    在之前的文章有写过~下面给出链接

    http://t.csdn.cn/lkZ5J

    427d1eba691c4f2eaef893facaae0632.png


    1.3一个简单Java程序的解释

    ab29daa19cef4f269ecfc244b179d5c0.png


     1.4什么叫“一次编译,到处运行”?

            一次编译后产生的xxx.class字节码文件,无论你发给谁,只要他的电脑上装有JDK,在他的JDK上就能跑,Java命令就能执行!

                                            苹果电脑 没问题 可以跑

                                            你是linux也可以

                                            windows也可以

                                                                                                                                    51d1af9e3a814dc796d25f01fbdf0ba1.gif


    1.5注释常见错误

    注释中出现中文就会出现以下错误(分情况)

    444ae4d7505e4e7799ad64038992fdb2.png


    1.6标识符

    在程序中由用户给类名、方法名或者变量所取的名字。

    【硬性规则】

            标识符中可以包含:字母、数字以及 下划线和 $ 符号等等。注意:标识符不能以数字开头,也不能是关键字,且严格区分大小写。

    【软性建议】

    • 类名:每个单词的首字母大写(大驼峰)
    • 方法名:首字母小写,后面每个单词的首字母大写(小驼峰)
    • 变量名:与方法名规则相同

    1.7关键字

             观察上述程序可以发现,public、class以及static等颜色会发生变化,将这些具有特殊含义的标识符称为关键字。即:关键字是由Java语言提前定义好的,有特殊含义的标识符,或者保留字。

            那么,java中都有那些常见的关键字呢?

    53beb5dcdd4e44d9b662cb58e058836b.png

             慢慢学        不着急        一步一步来~

                                                                            79b430719e2348909f41737a3d7ad4eb.gif



    2.数据类型

            实际上java和C语言类型,有以下这些类型:


    2.1基本数据类型

    553a7ce21bdf4d2f9320bcaf89849d18.png


    2.2.引用型数据类型

            数组        String        类        接口        枚举...(后面章节细讲)


    2.3.不同数据类型解析

            很多地方可以与C语言类比着看,以前写过一篇文章(仅做参考),解释了数据类型,以及内存形式:

    http://t.csdn.cn/QOGH6

    要注意以下这些不同点:

    • 整形(int):

    • 大小4个字节【可移植性强:不管你是32位还是64位,int就是4个字节】;
    • 在Java里,int 没有所谓的无符号整形,故int既能表示正数也能表示负数
    •  包装类类型->Integer

    在Java中,什么是变量(int举例)

    简而言之就是可以改变的量;

    问题来了,如下图

    11763ab8e5db42dea692071b0b3dcf0c.png

     注        意:Java中局部变量必须要初始化,否则会报错,Java中不存在所谓的如C语言中全局变量(后续类和对象中会细讲)

    长整形(long):

    • 不管是64位还是32位都只占8个字节,总共64位,去掉符号位63位
    • 最小值:-2^63,最大值:-2^63-1
    • 同样long也就包装类类型->Long
    • 不存在无符号,只有有符号数
    • long a = 10L;后面的L(或小写l,但不推荐)表示为长整型,没有的话他就是一个整数

    短整型(short):

    • 2个字节 共16位,去掉符号位-> 15位
    • 最小值:-2^15,最大值:2^15-1
    • 不存在无符号,只有有符号数
    • 包装类类型->Short

    字节型(byte):(可以为类比char)

    • 占一个字节
    • 总共8位,去掉符号位-> 7位
    • 大小为-128~127
    • 不存在无符号,只有有符号数
    • 包装类类型->Byte

    注意如果你这样赋值:

    db67e0e608574d7c9cc28c6a8dac48e4.png

             编译器会自动检查,赋值的字面值常量是不是超出了当前数据类型能够表示的数据范围,以此类推其他数据类型也一样,超出便会报错!

    注意:

    4bcda2d6713f415c8cd7d5dae6b5867c.png

     更改办法:

    2ddd413b983b4ce7ae733244a659ac20.png

    问答:

    但是b的值是128,超出了b,怎么办呢? 为什么不报错呢?

    我们来打印看一下它的值:

    b1f0c46c9b224033ad83334f35e1c1ce.png

     -128?为什么呢?不报错吗?

    注意:刚刚说的是超出字面值常量!编译前并不知道a+1中的a是127

    详情请看(和C语言中的char一样):

    http://t.csdn.cn/Wecgu

    小的总结:不能直接赋值一个超过这个数据类型的值,编译器会报错!

    单精度浮点型(float):

    • float 类型在 Java 中占四个字节, 同样遵守 IEEE 754 标准.

    • 由于表示的数据精度范围较小, 一般在工程上用到浮点数都优先考虑 double, 不太推荐使用 flfloat. flfloat的包装类型为Float。
    • float精确到小数点后6位

    注意:f6fb9f351b5b49228dcd19e2bd9d0324.png

             6.5默认是一个double类型的数据(Java规定),而double占用8个字节,所以会报错;

    更改:2b687f80e5ce49259c6188102151f821.png

     双精度浮点型(double):

    •  double在任何系统下都占8个字节
    • 浮点数与整数在内存中的存储方式不同,不能单纯使用的形式来计算
    • double的包装类型为Double4. double 类型的内存布局遵守 IEEE 754 标准(和C语言一样), 尝试使用有限的内存空间表示可能无限的小数, 势必会存在一定的精度误差,因此浮点数是个近似值,并不是精确值。

    字符型(char):

    • char类型占两个字节(与C语言不一样!)
    • Java中使用的不是ASCII字符集,而是Unicode字符集
    • ASCII字符集:只有英文
    • Unicode字符集:包含很多语言:中文,拉丁文...
    • 不能表示负数
    • 取值范围0~65535(2^16)

    布尔类型(boolean):

    aefaacd84cf648d2a2c118583bd1d350.png

    • boolean类型非常特殊,JVM没有所谓的大小
    • 包装类:Boolean

    也不能存在如下写法:

    ee0e9df8e6414c23882f5c673c64ae6b.png


    2.4类型转换

     自动类型转换(隐式):

    • 代码不需要经过任何处理,在代码编译时,编译器会自动进行处理。
    • 特点:数据范围小的转为数据范围大的时会自动进行。
    1. int a = 100;
    2. long b = 10L;
    3. b = a;//a,b都是整形,a的范围更小,b的范围大,赋值时编译器自动将小范围类型转化为大范围类型
    4. a = b;//都是整形,但a的范围比b小,Java语法规定为错误,除非强制类型转化

    强制类型转换(显式):

    • 当进行操作时,代码需要经过一定的格式处理,不能自动完成。
    • 特点:数据范围大的到数据范围小的。
    1. int a = 10;
    2. long b = 100L;
    3. b = a;        // int-->long,数据范围由小到大,隐式转换
    4. a = (int)b;   // long-->int, 数据范围由大到小,需要强转,否则编译失败

     那么问题来了,下面两个代码正确吗?

    1. public class test {
    2. public static void main(String[] args){
    3. //代码1
    4. byte a = 1;
    5. byte b = 2;
    6. byte c = a + b;
    7. System.out.println(c);
    8. //代码2
    9. int i = 10;
    10. float f = 19.9f;
    11. i = f;
    12. }
    13. }

    解释如下:

    1811192c1991409a8f558bd9746d82d0.png         扩展:两个不一样的数据类型进行运算时候,会把较小的数据类型转化为较大的数据类型参与运算(CPU 通常是按照 4 个字节为单位从内存中读写数据. 为了硬件上实现方便, 诸如 byte 和 short这种低于 4 个字节的类型, 会先提升成 int, 再参与计算.

     字符串类型(String):

    【后期会重点讲!本章只做了解!】

    Java中使用String定义字符串:

    1. public class test{
    2. public static void main(String[] args){
    3. String h = "hello ";
    4. String w = "world";
    5. System.out.println(h+w);//h+w表示将字符串h与w拼接起来
    6. }
    7. }

              特点:String类型和其他数据类型进行拼接的时候,会整体变成字符串类型

              一些情况下,字符串与整形需要相互转化(这就设计到包装类,后面章节重点讲,本小节只做了解!)

    1.int转化成String

    1. int num = 10;
    2. // 方法1
    3. String str1 = num + "";  
    4. // 方法2
    5. String str2 = String.valueOf(num);

    2.String转化成int

    1. String str = "100";
    2. int num = Integer.parseInt(str);


    3.运算符常见易错点

    本章主要会探究C与Java的不同点

    3.1 + - * /

    + - * /想必都很了解(类比C语言),有必要的是聊一聊%,看懂下下面例子对%也就没什么问题

    你计算的结果是?

    1. public class operator {
    2. public static void main(String[] args){
    3. System.out.println(10 % 3);
    4. System.out.println(10 % -3);
    5. System.out.println(-10 % 3);
    6. System.out.println(-10 % -3);
    7. }
    8. }

    解析:

    881268ca87d3465dad9d81327c163cb9.png


    3.2 x=x+1与x+=1

    观察以下代码,为什么s1 = s1 + 1;报错了,s1 += 1;却不会报错?

     9bdc4c23d73f40f38b5c6ededb9ca605.png

     解析:

            s1 + 1中,进行了算数运算,1为整形,所以s1会提升为整形,那么(s1+1)也就为整形类型,赋值给s1这个short类型自然会报错,想不让他报错,只需要s1 = (short)(s1 + 1);即可,证明s1+=1;

    中的+=自动帮我进行类型转化;


    3.3 > < >= <= == !=

    值得注意一点是,这些表达式的结果只能是布尔类型,也就是说,表达式的结果只能为ture或者false(要和C语言区分开),看如下例子,结果是什么?

    ee9216485a0947f78ab4ac3cce205acf.png

     解析:

    e9a261dfa06843d7ab430ba85788e529.png


     3.4 && 和 ||

    逻辑与(&&):

    69c3aa23781e4483a8c20217fc4cbc51.png

     逻辑或(||):

    6ec5a3fc230142e8a5c8b6d9ff825b22.png


    3.5 无符号右移

    08a15125e69f4b66ba841d7d6e18eb03.png

     存在无符号位左移吗?

                                            不存在!

                                                            因为右边不是符号位!


    3.6条件运算符(三目运算符)经典面试题

    442736dc33c34df38b10e4c2a4bda12c.png

     解析:

    02cf53132e3543809ec15ec8a230759e.png



    4.逻辑控制(猜数字游戏)

    1. import java.util.Random;
    2. import java.util.Scanner;
    3. //猜数字游戏
    4. public class test{
    5. public static void main(String[] args){
    6. }
    7. public static void main1(String[] args){
    8. //生成随机数
    9. Random ran = new Random();
    10. int randNum = ran.nextInt(101);//[0~101)
    11. //int randNum = ran.nextInt(100)+1;//[1~101)
    12. while(true){
    13. System.out.print("请输入数字:");
    14. Scanner scanner = new Scanner(System.in);
    15. int input = scanner.nextInt();
    16. if(input > randNum){
    17. System.out.println("猜大了!");
    18. }
    19. else if(input < randNum){
    20. System.out.println("猜小了!");
    21. }
    22. else{
    23. System.out.println("恭喜你猜中了!");
    24. break;
    25. }
    26. }
    27. }
    28. }


    5.方法重载

    类比C与语言函数会清楚很多,想象以下榨汁机:

    980b4a08b3dc4d19b375ec528fa629ae.png

     重载  注意以下几点就好了

    • 方法名相同
    • 形参列表不同
    • 返回值不做要求,可以一样,也可以不一样

    5.1形参与实参的关系,如何开辟空间?

    注意一下形参和实参的传递关系即可:

            main方法和你定义的方法会分别在栈区开辟两块不同的空间(栈帧),形参只是实参的一份临时拷贝

    对此,博主之前写过一篇文章,详细的介绍了栈帧的创建与销毁,可以通过下方链接看看

    函数栈帧的创建与销毁

    http://t.csdn.cn/hU5oV



    6.数组

    和C语言中数组就些许不同啦~

    三种定义方式,由于JAVA中数组是动态的,所以会在堆区开辟空间存放数组内容,在栈区为引用变量开辟空间,存放数组内容的地址(未定义默认初始化为0,引用类型为:NULL)

    aee44665f32c42ef934180d8dd294fdf.png

    初始化数组时不能指定数组元素个数,否则报错,相比C语言,此时array1才真的算的上是数组,类型为int[ ]       (doge)

    2d72deaf373346e78e40a17c21c30584.png

    数组名不在仅仅是地址,而是地址的哈希值:也可以理解为地址

    eb50e8edef5f4cf8a23fa050d86885d7.png


    6.1数组的三种访问方式

    第一种

    1. import java.util.Arrays;
    2. public class Test{
    3. //数组访问
    4. public static void main(String[] args){
    5. int[] array = {1,2,3,4,5,6};
    6. //1
    7. int i = 0;
    8. for(i = 0; i < array.length; i++){
    9. System.out.print(array[i] + " ");
    10. }
    11. }

    第二种

    1. import java.util.Arrays;
    2. public class Test{
    3. //数组访问
    4. public static void main(String[] args){
    5. int[] array = {1,2,3,4,5,6};
    6. //2
    7. for(int x : array){
    8. System.out.print(x + " ");
    9. }
    10. System.out.println();
    11. }

    第三种

    1. import java.util.Arrays;
    2. public class Test{
    3. //数组访问
    4. public static void main(String[] args){
    5. int[] array = {1,2,3,4,5};
    6. //3
    7. String ret = Arrays.toString(array);
    8. System.out.println(ret);//以字符串的形式打印
    9. }

    6.2数组名作为参数传参,以及内存布局

    以下代码会打印什么?

    1. public class Test{
    2. public static void fun1(int[] array1){
    3. array1 = new int[]{4,5,6};
    4. }
    5. public static void fun2(int[] array2){
    6. array2[0] = 100;
    7. }
    8. public static void main(String[] args){
    9. int[] array = {1,2,3};
    10. fun1(array);
    11. int i = 0;
    12. for(i = 0; i < array.length; i++){
    13. System.out.print(array[i] + " ");
    14. }
    15. System.out.println();
    16. fun2(array);
    17. for(i = 0; i < array.length; i++){
    18. System.out.print(array[i] + " ");
    19. }
    20. }

    分析:

    1.首先main方法在栈区开辟栈帧,在堆区开辟空间存放 array数组内容,并在栈区存放array地址

    94451372b548498eaa3187eedee93218.png

     2.调用fun1方法,栈区为fun1开辟空间

    2a1b4d5836d84bef86ff415edfd7f89f.png

    a3f65bcd4e174240bef204ad9f564777.png

     3.出函数销毁

    550e45b19a914cf3bac8815a2dcbfec3.png

     4.调用fun2函数,并通过地址修改其值

    3d883bdebb764697aa02603e01c97a29.png

    其实将过程分析清楚,答案自然就出来,画图很重要!!!


    6.3 对于数组,Java带来的一些便捷(import java.util.Arrays;)

    6.3.1 数组拷贝(Arrays.copyOf)

    Arrays.copyOf(待拷贝的数组,拷贝的长度)

    有以下copyOf重载:

    f33152ad48db45e7b42a07cfa5d48766.png

     实例:(拷贝长度大于被拷贝数组时,相当于扩容,扩容部分自动初始化为0

    1. import java.util.Arrays;
    2. public class Test{
    3. //数组拷贝
    4. public static void main(String[] args){
    5. int[] array = {1,2,3,4,5};
    6. int[] copy = Arrays.copyOf(array, array.length);
    7. for(int i = 0; i < copy.length; i++){
    8. System.out.print(copy[i] + " ");
    9. }
    10. }
    11. }

    6.3.2字符串形式返回数组(Arrays.toString)

            Arrays.toString(数组名)

    重载:

    85647ccced5c4008a503bf5650680f54.png

     实例:(打印时会自动加上[ ] ,并且是以字符串形式打印)

    1. import java.util.Arrays;
    2. public class Test{
    3. //字符串打印数组实例
    4. public static void main(String[] args){
    5. int[]array = new int[]{1,2,3,4,5};
    6. System.out.println(Arrays.toString(array));
    7. }

    6.3.3数组排序(Arrays.sort)

            Arrays.sort(待排序的数组名);

            Arrays.sort(待排序的数组名, 起始位置下标, 终止位置下标); //前闭后开  [ x, y )

    重载:

    16e3d9da2fde4e38859b33c6234fa681.png

    实例:(升序排序,可以给出起始终止位置,也可以不给(默认排序整个数组),以下例子只会排序下标1~3的数字,4不会被排序,注意前闭后开

    1. import java.util.Arrays;
    2. public class Test{
    3. //排序实例
    4. public static void main(String[] args){
    5. int[] array = new int[]{5,3,2,6,1,9};
    6. Arrays.sort(array,1, 4);
    7. System.out.println(Arrays.toString(array));
    8. }

    6.3.4指定范围的数组拷贝(Arrays.copyOfRange)

    Arrays.copyOfRange(被拷贝的数组, 起始下标, 终止下标); //前闭后开

    重载:

    86852e2e8a05456b99d49dd889aa0470.png

     实例:(凡是from , to一般都是前闭后开)下例打印[ 1 , 2 , 3 ]

    1. import java.util.Arrays;
    2. public class Test{
    3. //指定拷贝
    4. public static void main(String[] args){
    5. int[] array = new int[]{1,2,3,4,5};
    6. int[] arrayCopy = Arrays.copyOfRange(array, 0,3);
    7. System.out.println(Arrays.toString(arrayCopy));
    8. }

    6.3.5数组比较(Arrays.equals)

            Arrays.equals(数组名1, 数组名2); 返回类型为布尔类型,相等返回true

    f21515cfebcd4a8fb0708c0932f4a6f5.png

    实例:(以下例子打印true)

    1. import java.util.Arrays;
    2. public class Test{
    3. public static void main(String[] args){
    4. int[] array1 = new int[]{1,2,3,4,5};
    5. int[] array2 = new int[]{1,2,3,4,5};
    6. boolean flag = Arrays.equals(array1,array2);
    7. System.out.println(flag);
    8. }

    6.4二维数组

    和C语言中数组就些许不同啦~


    有以下三种定义方式:(未定义默认初始化为0,引用类型为:NULL)

    1. public class Test{
    2. public static void main(String[] args) {
    3. int[][] array1 = {{1,2,3},{1,2,3}};//不可指定[]里的内容,此时行列会根据初始化内容定义,因此也不能{1,2,3,1,2,3}
    4. int[][] array2 = new int[][]{{1,2,3},{4,5,6}};
    5. int[][] array3 = new int[2][3];
    6. }

    三种不同的遍历方式:

    1. import java.util.Arrays;
    2. public class Test{
    3. public static void main(String[] args) {
    4. int[][] array = {{1,2,3},{4,5,6}};
    5. //1
    6. for(int i = 0; i < array.length; i++){
    7. for(int j = 0; j < array[i].length; j++){
    8. System.out.print(array[i][j] + " ");
    9. }
    10. }
    11. System.out.println();
    12. //2
    13. for(int[] tmp : array){
    14. for(int x : tmp){
    15. System.out.print(x + " ");
    16. }
    17. }
    18. System.out.println();
    19. //3
    20. System.out.println(Arrays.deepToString(array));
    21. }

    如何理解呢?


    对二维数组遍历的解释:

    4a948938eb6f4444929dab98aea0fbd4.png


    不规则二维数组:

    与C不同,Java中二维数组可以省略列,不能省略行,以下为图解:

    c087dc1495e243f7900df0195ddddbaf.png



     7.类和对象(一个例子轻松理解~)

    一个例子带你搞懂类和对象:

    一、假设我们要创造一个机器人,首先我们要先绘制机器人图纸(这个图纸相当于“”,没有实际的物理空间)。

    二、根据图纸我们需要建造这么一个机器人(建造出机器人过过程成为——实例化对象),那么这个机器人有那些属性呢?

    三、这个机器人是什么颜色、有多重、多高...这便是这个机器人的属性。那么的功能是那些呢?怎么设计他的芯片让他完成一系列任务?

    四、这个机器人我需要给他设计多个芯片,每个芯片都可以让他完成不同的任务(行为)。

    五、成功造出这个机器人(机器人——对象

    代码如下:

    1. class robot{
    2. //成员属性(字段)
    3. public String colour;
    4. public double height;
    5. public double weight;
    6. //...
    7. //成员方法(行为)
    8. public void fun1(){
    9. System.out.println("与人沟通");
    10. }
    11. public void fun2(){
    12. System.out.println("做饭");
    13. }
    14. public void fun3(){
    15. System.out.println("洗衣服");
    16. }
    17. }
    18. public class Test{
    19. public static void main(String[] args){
    20. robot machine1 = new robot();
    21. machine1.colour = "蓝色";
    22. machine1.height = 1.88;
    23. machine1.weight = 300.25;
    24. machine1.fun1();
    25. }

    图解:

    078ae7c676264a5bbffedb120626cb81.png

     3cb569d6ab5a4b0d97078628986ab875.png


     7.1this

    1.防止形参与成员变量同名,并且约定俗成,在方法里引用成员变量时,最好都加this

    (存在即合理)

    1. class student{
    2. public String name;
    3. public int age;
    4. public void fun(String name, int age){
    5. this.name = name;
    6. this.age = age;
    7. }
    8. public void print(){
    9. System.out.println("name :" + this.name);
    10. System.out.println("age :" + this.age);
    11. }
    12. }
    13. public class Test{
    14. public static void main(String[] args){
    15. student stu = new student();
    16. stu.fun("jay chou",46);
    17. stu.print();
    18. }

    2.在当前的构造方法里面,通过this()可以调用当前对象的构造方法(必须放在当前构造方法的第一行!

    1. class student{
    2. public String name;
    3. public int age;
    4. public student(){
    5. this("jay chou",46);
    6. }
    7. public student(String name, int age){
    8. this.name = name;
    9. this.age = age;
    10. System.out.println("name:" + this.name + "age:" + this.age);
    11. }
    12. public void fun(String name, int age){
    13. this.name = name;
    14. this.age = age;
    15. }
    16. public void print(){
    17. System.out.println("name :" + this.name);
    18. System.out.println("age :" + this.age);
    19. }
    20. }
    21. public class Test{
    22. public static void main(String[] args){
    23. student stu = new student();
    24. }

    7.2构造

            一个没有返回类型的方法,对象一旦生成(new),就会调用一次构造方法(实例化对象其实就是开辟空间同时调用构造方法),同时,构造方法不止一个,可以重载,如果没有提供构造方法,编译器会默认给你提供一种合适的构造方法

    使用如下:

    1. class student{
    2. //成员变量
    3. public String name;
    4. public int age;
    5. //构造方法
    6. public student(String name, int age){//public 可加可不加,后期会讲
    7. this.name = name;
    8. this.age = age;
    9. System.out.println("name:" + this.name + "age:" + this.age);
    10. }
    11. //成员方法
    12. public void fun(String name, int age){
    13. this.name = name;
    14. this.age = age;
    15. }
    16. public void print(){
    17. System.out.println("name :" + this.name);
    18. System.out.println("age :" + this.age);
    19. }
    20. }
    21. public class Test{
    22. public static void main(String[] args){
    23. student stu = new student("jay chou",46);
    24. }

    执行过程如下:

    5ec26eafaa5c4564a7049bd65ec8d0cd.png


    7.2.1 构造重载

    7.1this中的例二就是构造重载,向上翻阅即可

    注意:不可圈式调用(以下为错误调用)

    f1282d42ad654d4ebab6eb28eedc9e3a.png



    8.static修饰的静态变量

            在类里面,static可以修饰成员变量和方法,由于修饰后的意义不同,也被也被称为类变量和类方法;类变量在内存中只有一份,不能定义在普通的方法当中


    8.1类变量和类方法

            类中的成员变量被static修饰后也称类变量,类方法同;(类变量和类方法的访问最好通过类名去访问,尽管通过对象也可以访问,但是不推荐!)

    如下代码:

    1. class Student{
    2. public String name;
    3. public int score;
    4. //类变量
    5. public static String classes = "火箭6班";
    6. //类方法
    7. public static void fun1(){
    8. System.out.println("类方法");
    9. }
    10. }
    11. public class Test {
    12. public static void main(String[] args){
    13. Student stu = new Student();
    14. System.out.println(Student.classes);
    15. Student.fun1();
    16. }
    17. }

    内存布局如下:

    e8566eadf38a4f0da29122848a0e1713.png

     注意:在静态的方法里不要直接去访问非静态的,可以提供对象引用来访问非静态的!(静态方法在没有new这个类的时也是可以访问的,而非静态的在没有new出对象时是不可以直接访问的!)

    如下代码:

    1. class Student{
    2. public String name;
    3. public int score;
    4. //类变量
    5. public static String classes = "火箭6班";
    6. //类方法
    7. public static void fun1(){
    8. name = "jay";//错误
    9. System.out.println("类方法");
    10. }
    11. public void fun2(){
    12. name = "jay";//正确
    13. }
    14. }
    1. class Student{
    2. public String name;
    3. public int score;
    4. //类变量
    5. public static String classes = "火箭6班";
    6. //类方法
    7. public static void fun1(){
    8. Student stu = new Student();
    9. stu.name = "jay"; //正确
    10. System.out.println("类方法");
    11. }
    12. }

    8.2代码块

    博主单另写了一篇,有兴趣可以看看~

    http://t.csdn.cn/NGixv



    9.内部类

            内部类就是将一个类定义在另一个类的内部;内部类有四种,分别为:实例内部类、静态内部类、局部内部类、匿名内部类(匿名后期将接口会细讲)


    9.1实例内部类

    • 外部类中的任何成员都可在实例内部类中直接访问
    • 内外成员同名时,优先访问内部,若想访问外部:外部类名.this.成员名
    • 外部类对象创建后才能创建实例内部类对象
    • 外部类中不能直接访问内部类,须先创建内部类对象

    如下代码:

    1. class OutClass{
    2. //成员变量
    3. public int data1 = 1;
    4. private int data2 = 2;
    5. public static int data3 =3;//类变量
    6. //构造方法
    7. public OutClass(){
    8. System.out.println("外部类的构造方法!");
    9. }
    10. //实例内部类
    11. class InsideClass{
    12. //成员变量
    13. public int data1 = 4;
    14. private int data2 = 5;
    15. public static final int date3 = 6;//必须用 final 修饰为常量,必须初始化
    16. //构造方法
    17. public InsideClass(){
    18. System.out.println("实例内部类的构造方法!");
    19. }
    20. //成员方法
    21. public void fun2(){
    22. System.out.println(OutClass.this.data1);//访问外部
    23. System.out.println(data2);//优先访问内部
    24. System.out.println("实例内部类的成员方法");
    25. }
    26. }
    27. //成员方法
    28. public void fun1(){
    29. OutClass.InsideClass inside = new InsideClass();//外部类中需要先创建对象内部类对象
    30. System.out.println(inside.data1);//在外部类中访问内部类成员
    31. System.out.println(inside.data2);
    32. System.out.println("外部类的成员方法!");
    33. }
    34. }
    35. public class Test{
    36. public static void main(String[] args){
    37. OutClass out = new OutClass();
    38. OutClass.InsideClass inside = out.new InsideClass();//必须建立在外部类对象的前提的下
    39. }
    40. }

    9.2静态内部类

    • 静态内部中只能访问外部类中的静态变量,不能访问非静态变量,非要访问,需要创建外部类对象
    • 创建静态内部类对象,不需要先创建外部类对象
    • 在外部类未引入静态内部变量对象前,只能访问静态变量

    如下代码:

    1. class OutClass{
    2. public int data1 = 1;
    3. private int data2 = 2;
    4. public static int data3 = 3;
    5. public OutClass(){
    6. System.out.println("外部类的构造方法!");
    7. }
    8. static class InsideClass{
    9. public int data3 = 3;
    10. private int data4 = 4;
    11. public static int data5; // 可以不加final修饰,可以不用先初始化
    12. public InsideClass(){
    13. System.out.println(OutClass.data3);//只能访问外部静态的变量
    14. OutClass out = new OutClass();
    15. out.fun1();//访问外部非静态成员
    16. System.out.println("静态内部类构造方法!");
    17. }
    18. public void fun2(){
    19. System.out.println("静态内部类成员方法!");
    20. }
    21. }
    22. public void fun1(){
    23. System.out.println(InsideClass.data5);//没引入内部类对象前只能访问静态变量
    24. OutClass.InsideClass inside = new OutClass.InsideClass();
    25. System.out.println(inside.data3);//访问静态内部类
    26. System.out.println("外部类的成员方法!");
    27. }
    28. }
    29. public class Test{
    30. public static void main(String[] args){
    31. //创建静态内部类对象时不需要先创建外部类对象
    32. OutClass.InsideClass inside = new OutClass.InsideClass();
    33. }
    34. }

    9.3局部内部类

    • 可以直接访问外部类中成员变量
    • 此类极不常用

    如下代码:

    1. class OutClass{
    2. public int data1 = 1;
    3. private int data2 = 2;
    4. public static int data3 = 3;
    5. public OutClass(){
    6. System.out.println("外部类构造方法!");
    7. }
    8. public void fun(){
    9. System.out.println("外部类成员方法!");
    10. //局部内部类
    11. class InsideClass{
    12. public void fun(){
    13. System.out.println("外部类成员变量:" + data1);
    14. }
    15. }
    16. }
    17. }
    18. public class Test{
    19. public static void main(String[] args){
    20. OutClass out = new OutClass();
    21. out.fun();
    22. }
    23. }


    10.封装、继承、多态

    也是经典的一个面试问题:OOP语言的三大特征

    这篇博主已经整理好笔记啦~

    http://t.csdn.cn/KUJrv



    11.抽象类(abstract)

            通俗来讲,就是一个abstract修饰的类,他也具有成员变量,构造方法,成员方法,但这个方法必须是抽象类方法(被abstract修饰并且没有具体实现)。

    注意事项:

    • 抽象类不能进行实例化
    • 可以被继承(extends)
    • 若被一个普通类继承,必须对继承的抽象类(有抽象方法)里抽象方法进行重写,否则编译报错
    • 抽象类A,继承抽象类B,则可以不重写B的抽象方法
    • 抽象方法不能被static、final、private修饰

    例子:音乐生与美术生所能完成的不同任务

    1. abstract class Human{
    2. public abstract void func();
    3. }
    4. class Art extends Human{
    5. @Override
    6. public void func(){
    7. System.out.println("画画~");
    8. }
    9. }
    10. class Music extends Human{
    11. @Override
    12. public void func(){
    13. System.out.println("唱歌~");
    14. }
    15. }
    16. public class Test{
    17. public static void function(Human human){
    18. human.func();
    19. }
    20. public static void main(String[] args){
    21. //Human human = new Human();//抽象类不能实例化对象
    22. Human human1 = new Art();
    23. Human human2 = new Music();
    24. function(human1);
    25. function(human2);
    26. }
    27. }


    12.接口

            是一个用interface修饰的接口,成员变量都是默认被public static final修饰的,成员方法都是默认被public abstract修饰的,并且不能有具体实现(JDK8开始,才可以通过default来写具体实现)。

                   举个例子,就像手机,需要通过usb接口完成交互,通过数据线将接口连接到电脑,可以传输不同类型的数据,如:图片、视频、音乐、软件.....

    注意事项:

    • 可以有静态成员方法,并且都是被public修饰的
    • 不可以实例化
    • 类是通过implements关联接口的
    • 可以引用具体的实现类完成向上转型
    • 不能有静态代码块、实例代码块、构造方法
    • 接口之间可以通过extends继承,并且可以不重写抽象方法

    例子:

    1. abstract class Animal{
    2. public String name;
    3. public int age;
    4. Animal(String name, int age){
    5. this.name = name;
    6. this.age = age;
    7. }
    8. public abstract void eat();
    9. }
    10. interface IRun{
    11. int a = 1;
    12. void run();
    13. }
    14. interface IFly{
    15. void fly();
    16. }
    17. class Brid extends Animal implements IRun, IFly{
    18. Brid(String name, int age){
    19. super(name,age);
    20. }
    21. @Override
    22. public void eat(){
    23. System.out.println(name + "正在吃小虫子~");
    24. }
    25. @Override
    26. public void run(){
    27. System.out.println(name + "正在用两条腿蹦来蹦去~");
    28. }
    29. @Override
    30. public void fly(){
    31. System.out.println(name + "正在飞翔~");
    32. }
    33. }
    34. class Dog extends Animal implements IRun{
    35. Dog(String name, int age){
    36. super(name, age);
    37. }
    38. @Override
    39. public void eat(){
    40. System.out.println(name + "正在啃骨头~");
    41. }
    42. @Override
    43. public void run(){
    44. System.out.println(name + "正在用四条腿跑~");
    45. }
    46. }
    47. public class Test{
    48. public static void func1(Animal animal){
    49. animal.eat();
    50. }
    51. public static void func2(IRun run){
    52. run.run();
    53. }
    54. public static void func3(IFly fly){
    55. fly.fly();
    56. }
    57. public static void main(String[] args){
    58. func1(new Brid("小鸟",1));
    59. func1(new Dog("狗子",2));
    60. func2(new Brid("小鸟",1));
    61. func2(new Dog("狗子",2));
    62. func3(new Brid("小鸟",1));
    63. }
    64. }

    12.1制作一个简单的比较器

    1. import java.util.Arrays;
    2. import java.util.Comparator;
    3. class Student /*implements Comparable*/ {
    4. public String name;
    5. public int age;
    6. public int score;
    7. public Student(String name, int age, int score) {
    8. this.name = name;
    9. this.age = age;
    10. this.score = score;
    11. }
    12. @Override
    13. public String toString() {
    14. return "Student = {" +
    15. name + ", " + age
    16. + ", " + score +
    17. "} ;";
    18. }
    19. }
    20. //比较器
    21. class AgeCompare implements Comparator{
    22. @Override
    23. public int compare(Student o1, Student o2) {
    24. return o1.age - o2.age;
    25. }
    26. }
    27. class ScoreCompare implements Comparator{
    28. @Override
    29. public int compare(Student o1, Student o2){
    30. return o1.score - o2.score;
    31. }
    32. }
    33. class NameCompare implements Comparator{
    34. @Override
    35. public int compare(Student o1, Student o2){
    36. return o1.name.compareTo(o2.name);
    37. }
    38. }
    39. public class Test {
    40. public static void main(String[] args){
    41. Student[] student = new Student[3];
    42. student[0] = new Student("张三",19,90);
    43. student[1] = new Student("李四",17,82);
    44. student[2] = new Student("王五",18,85);
    45. System.out.println("排序前:" + Arrays.toString(student));
    46. Arrays.sort(student,new ScoreCompare());
    47. System.out.println("排序后:" + Arrays.toString(student));
    48. }


    13.浅拷贝和深拷贝

    博主整理出文章了哦,快去看看吧~

    http://t.csdn.cn/bu7wd



    14.Object类

            Java当中,默认Object是所有类的父类,也就意味着Object可以接收所有类的对象

    如下代码:

    1. import java.util.Objects;
    2. class A{
    3. }
    4. class B{
    5. }
    6. public class Test{
    7. public static void main(String[] args){
    8. Object obj1 = new A();
    9. Object obj2 = new B();
    10. System.out.println(obj1);
    11. System.out.println(obj2);
    12. }
    13. }

            同时,Object类中,也有很好的几个方法例如toString,equals, hashcode...(后面数据结构博主会重点讲),以下以equals举例作为了解

    1. import java.util.Objects;
    2. class Human{
    3. public String id;
    4. public Human(String id){
    5. this.id = id;
    6. }
    7. @Override
    8. public boolean equals(Object obj){
    9. if(obj == null){//判断参数是否为空
    10. return false;
    11. }
    12. if(this == obj){//判断地址是否相等
    13. return true;
    14. }
    15. Human tmp = (Human)obj;
    16. return this.id.equals(tmp.id);
    17. }
    18. }
    19. public class Test{
    20. public static void main(String[] args){
    21. Object o1 = new Human("610");
    22. Object o2 = new Human("610");
    23. System.out.println(o1.equals(o2));
    24. }
    25. }


    15.String类

    string的三种定义方法

    1. public class Test {
    2. public static void main(String[] args){
    3. String str1 = "hello";
    4. String str2 = new String("world");
    5. char[] s = {'a','b','c'};
    6. String str3 = new String(s);
    7. }
    8. }

    内存布局:(简易图如下,后面讲面试题有更细致的图)

    4c0b4088436b45fab1504410232d4649.png


    15.1字符串常量池 

    观察如下代码 s1 == s2 ?

    1. public class Test {
    2. public static void main(String[] args){
    3. String str1 = "hello";
    4. String str2 = "hello";
    5. System.out.println(str1 == str2);
    6. }
    7. }

    内存分析:

    b2ecb2290e934c498a4825cc27775167.png


    15.2面试题:请解释String类中三种实例化对象的区别

    博主已经整理好博客啦

    http://t.csdn.cn/n1n5z


    15.3.1 字符串比较是否相同(equals())

    1. public class Test {
    2. public static void main(String[] args){
    3. String str1 = "hello";
    4. String str2 = "hell";
    5. System.out.println(str1.equals(str2));
    6. }
    7. }

    15.3.2字符串比较大小(compareTo())

    1. public class Test {
    2. public static void main(String[] args){
    3. String str1 = "abc";
    4. String str2 = "jcd";
    5. System.out.println(str1.compareTo(str2));//返回ASCII码差值
    6. }
    7. }

    15.3.3忽略大小写比较是否相同(equalsIgnoreCase())

    1. public class Test {
    2. public static void main(String[] args){
    3. String str1 = "abc";
    4. String str2 = "ABC";
    5. System.out.println(str1.equalsIgnoreCase(str2));//返回ASCII码差值
    6. }
    7. }

    15.3.4KMP算法查找字符或字符串(indexOf())

    1. public class Test {
    2. public static void main(String[] args){
    3. String str1 = "abcabcdeabcdef";
    4. /**
    5. * 通过KMP算法
    6. * 从下标3的位置开始查找第一次出现字符'c'的位置,返回下标,
    7. */
    8. int index1 = str1.indexOf('c',3);
    9. System.out.println(index1);
    10. int index2 = str1.indexOf("abcd");
    11. System.out.println(index2);
    12. }
    13. }

    15.3.5将其他类型相互转化(其他类型.valueOf())

    1. public class Test {
    2. public static void main(String[] args){
    3. //double转String
    4. String str1 = String.valueOf(12.5);
    5. System.out.println(str1);
    6. //String转int
    7. int value =Integer.valueOf("64");
    8. System.out.println(value);
    9. }
    10. }

    15.3.6小写转大写(toUpperCase())

    1. public class Test {
    2. public static void main(String[] args){
    3. String str1 = "abc";
    4. String str2 = str1.toUpperCase();
    5. System.out.println(str2);
    6. }
    7. }

    15.3.7大写转小写(toLowerCase())

    1. public class Test {
    2. public static void main(String[] args){
    3. String str1 = "ABC";
    4. String str2 = str1.toLowerCase();
    5. System.out.println(str2);
    6. }
    7. }

    LeetCode   125.验证回文串:给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。

    1. class Solution {
    2. private boolean legal(char ch){
    3. if(((ch >= 'a') && (ch <= 'z')) || ((ch >= '0') && (ch <= '9'))){
    4. return true;
    5. }
    6. return false;
    7. }
    8. public boolean isPalindrome(String s) {
    9. s = s.toLowerCase();
    10. int left = 0;
    11. int right = s.length() - 1;
    12. while(left < right){
    13. while(left < right && !legal(s.charAt(left))){
    14. left++;
    15. }
    16. while(left < right && !legal(s.charAt(right))){
    17. right--;
    18. }
    19. if(s.charAt(left) != s.charAt(right)){
    20. return false;
    21. }
    22. left++;
    23. right--;
    24. }
    25. return true;
    26. }
    27. }


    15.3.8字符串转字符数组(toCharArray())

    1. public class Test {
    2. public static void main(String[] args){
    3. String str1 = "hello";
    4. char[] str2 = str1.toCharArray();
    5. System.out.println(str2);
    6. }
    7. }

    15.3.9字符串切割(split())

    1. public class Test {
    2. public static void main(String[] args){
    3. String str1 = "hello welcome to China";
    4. String[] str2 = str1.split(" ");//(" ", 3);3表示切割3组字符串
    5. for(String x : str2){
    6. System.out.println(x);
    7. }
    8. }
    9. }

    15.3.10字符串替代(replaceFirst())

    剑指Offer:将str1中的空格替代为%20

    1. //将str1中的空格替代为%20
    2. public class Test {
    3. public static void main(String[] args){
    4. String str1 = "hello welcome to China";
    5. for(int i = 0; i < 3; i++){
    6. str1 = str1.replaceFirst(" ","%20");//每次只会替代一个空格
    7. }
    8. System.out.println(str1);
    9. }
    10. }

    15.3.11拿到字符串中的每一个字符(charAt())

    求字符串最后一个单词的长度

    1. public class Test {
    2. public static void main(String[] args){
    3. Scanner scanner = new Scanner(System.in);
    4. String str = scanner.nextLine();
    5. int i = 0;
    6. int count = 0;
    7. for(i = str.length() - 1; i > 0; i--){
    8. if(str.charAt(i) == ' '){
    9. break;
    10. }
    11. count++;
    12. }
    13. System.out.println(count);
    14. }
    15. }

    16.异常处理

    对异常的处理常常有以下两种处理方式:

    1.LBYL:事前防御型

            在操作前就提前做好一切准备,把可能报异常的地方都列举出来;

            一个有趣的例子,你谈了女朋友,想牵她的手,但是不知道会发生什么,所以你问了一句:“我可以牵你手吗?”这便是提前做好准备

    2.EAFP:事后认错型

            不管会发生什么样的问题,先操作,遇到问题,再解决问题;

            你谈了女朋友,想牵她的手,但是不知道会发生什么,然后你也没问,直接牵手,这便是先斩后奏,遇到问题,再说。

    16.1try-catch-finally(捕获并处理)

    如下代码:

    1. public class Test{
    2. public static void main(String[] args){
    3. int[] array = null;
    4. try {
    5. /**
    6. * 可能会发生的异常
    7. */
    8. System.out.println(array.length);
    9. }catch (NullPointerException e){
    10. /**
    11. * 若try中抛出的异常与catch捕获的异常类型一样时,就会进行对异常的处理
    12. * 若try中抛出的异常与catch捕获的异常类型不一样时,就会不断对外抛,直到交给JVM中断程序,抛出异常
    13. */
    14. System.out.println("对异常的处理!");
    15. }finally{
    16. System.out.println("无论try有没有抛异常,程序都会指向这里");
    17. /**
    18. * 无论有没有finally程序都会执行到这里,那finally有什么意义呢?
    19. * 想象一下,如果try里存在return这样的语句,就会结束main方法
    20. * 但这里因为有finally,所以无论try里有没有return都会执行指一条语句
    21. */
    22. }
    23. }
    24. }

    面试题:

            throw 和 throws 的区别?

           throw关键字,事抛出一个指定的异常对象,将错误信息告知给调用者

    throw new XXXException("异常产生的原因");

      throws是异常的声明,在方法名(参数列表)之后如下:

    1. 修饰符  返回值类型   方法名(参数列表) throws 异常类型1,异常类型2...{
    2. //...
    3. }

      是当方法中抛出编译时异常时,用户不想处理异常,就用throws来声明异常即可,以提醒方法的调用者处理该异常

    面试题:

            finally中的语句一定会执行吗?

            一定会执行,就算try里有return语句,照样执行finally;


    16.2自定义异常

            先自定义一个异常类,继承一个具体异常或者Exception(所有异常的父类),再实现一个带有String参数的构造方法(抛出错误原因)。

    如下代码:(消息发送异常,模拟网络异常)

    1. class NetworkException extends Exception{
    2. public NetworkException(String message){
    3. super(message);
    4. }
    5. }
    6. public class Test{
    7. public static void send (String networdState) throws NetworkException{
    8. if(networdState.equals("网络异常")){
    9. throw new NetworkException("网络状况不佳,无法发送消息!");
    10. }
    11. }
    12. public static void main(String[] args){
    13. //相应处理...发生网络异常
    14. String networdState = "网络异常";
    15. try{
    16. send(networdState);
    17. }catch(NetworkException e){
    18. e.printStackTrace();//打印栈区情况
    19. }
    20. }
    21. }

    运行结果:

    18c87abb0e32441da6dc106a56218640.png

  • 相关阅读:
    React高级特性之RenderProps
    基于SSM的智慧城市实验室主页系统的设计与实现
    4.10扁平化嵌套序列
    Windows10系统下以管理员身份修改系统文件,以修改hosts文件为例
    金融业务系统: Service Mesh用于安全微服务集成
    python面试常考题
    web前端网页实例:深度剖析与实践指南
    马上就2023年了,Go语言成了吗?
    Android 系统定位和高德定位
    一文深入理解Linux驱动整理
  • 原文地址:https://blog.csdn.net/CYK_byte/article/details/125846998