目录

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自定义异常




高老爷子保佑!!!



1.初识JAVA

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


1.2Java代码运行过程

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

http://t.csdn.cn/lkZ5J


1.3一个简单Java程序的解释


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

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

                                        苹果电脑 没问题 可以跑

                                        你是linux也可以

                                        windows也可以


1.5注释常见错误

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


1.6标识符

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

【硬性规则】

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

【软性建议】

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

1.7关键字

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

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

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



2.数据类型

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


2.1基本数据类型


2.2.引用型数据类型

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


2.3.不同数据类型解析

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

http://t.csdn.cn/QOGH6

要注意以下这些不同点:

  • 整形(int):

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

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

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

问题来了,如下图

 注        意: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

注意如果你这样赋值:

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

注意:

更改办法:

问答:

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

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

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

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

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

http://t.csdn.cn/Wecgu

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

单精度浮点型(float):

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

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

注意:

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

更改:

双精度浮点型(double):

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

字符型(char):

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

布尔类型(boolean):

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

也不能存在如下写法:


2.4类型转换

自动类型转换(隐式):

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

强制类型转换(显式):

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

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

public class test {public static void main(String[] args){//代码1byte a = 1;byte b = 2;byte c = a + b;System.out.println(c);//代码2int i = 10;float f = 19.9f;i = f;}
}

解释如下:

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

字符串类型(String):

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

Java中使用String定义字符串:

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

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

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

1.int转化成String

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

2.String转化成int

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


3.运算符常见易错点

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

3.1 + - * /

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

你计算的结果是?

public class operator {public static void main(String[] args){System.out.println(10 % 3);System.out.println(10 % -3);System.out.println(-10 % 3);System.out.println(-10 % -3);}
}

解析:


3.2 x=x+1与x+=1

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

解析:

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

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


3.3 > < >= <= == !=

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

解析:


3.4 && 和 ||

逻辑与(&&):

逻辑或(||):


3.5 无符号右移

 存在无符号位左移吗?

                                        不存在!

                                                        因为右边不是符号位!


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

解析:



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

import java.util.Random;
import java.util.Scanner;
//猜数字游戏
public class test{public static void main(String[] args){}public static void main1(String[] args){//生成随机数Random ran = new Random();int randNum = ran.nextInt(101);//[0~101)//int randNum = ran.nextInt(100)+1;//[1~101)while(true){System.out.print("请输入数字:");Scanner scanner = new Scanner(System.in);int input = scanner.nextInt();if(input > randNum){System.out.println("猜大了!");}else if(input < randNum){System.out.println("猜小了!");}else{System.out.println("恭喜你猜中了!");break;}}}
}


5.方法重载

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

重载  注意以下几点就好了

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

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

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

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

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

函数栈帧的创建与销毁

http://t.csdn.cn/hU5oV



6.数组

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

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

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

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


6.1数组的三种访问方式

第一种

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

第二种

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

第三种

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

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

以下代码会打印什么?

public class Test{public static void fun1(int[] array1){array1 = new int[]{4,5,6};}public static void fun2(int[] array2){array2[0] = 100;}public static void main(String[] args){int[] array = {1,2,3};fun1(array);int i = 0;for(i = 0; i < array.length; i++){System.out.print(array[i] + " ");}System.out.println();fun2(array);for(i = 0; i < array.length; i++){System.out.print(array[i] + " ");}}

分析:

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

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

3.出函数销毁

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

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


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

6.3.1 数组拷贝(Arrays.copyOf)

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

有以下copyOf重载:

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

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

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

Arrays.toString(数组名)

重载:

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

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

6.3.3数组排序(Arrays.sort)

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

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

重载:

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

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

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

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

重载:

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

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

6.3.5数组比较(Arrays.equals)

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

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

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

6.4二维数组

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


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

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

三种不同的遍历方式:

import java.util.Arrays;
public class Test{public static void main(String[] args) {int[][] array = {{1,2,3},{4,5,6}};//1for(int i = 0; i < array.length; i++){for(int j = 0; j < array[i].length; j++){System.out.print(array[i][j] + " ");}}System.out.println();//2for(int[] tmp : array){for(int x : tmp){System.out.print(x + " ");}}System.out.println();//3System.out.println(Arrays.deepToString(array));}

如何理解呢?


对二维数组遍历的解释:


不规则二维数组:

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



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

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

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

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

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

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

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

代码如下:

class robot{//成员属性(字段)public String colour;public double height;public double weight;//...//成员方法(行为)public void fun1(){System.out.println("与人沟通");}public void fun2(){System.out.println("做饭");}public void fun3(){System.out.println("洗衣服");}
}public class Test{public static void main(String[] args){robot machine1 = new robot();machine1.colour = "蓝色";machine1.height = 1.88;machine1.weight = 300.25;machine1.fun1();}

图解:


7.1this

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

(存在即合理)

class student{public String name;public int age;public void fun(String name, int age){this.name = name;this.age = age;}public void print(){System.out.println("name :" + this.name);System.out.println("age :" + this.age);}
}
public class Test{public static void main(String[] args){student stu = new student();stu.fun("jay chou",46);stu.print();}

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

class student{public String name;public int age;public student(){this("jay chou",46);}public student(String name, int age){this.name = name;this.age = age;System.out.println("name:" + this.name + "age:" + this.age);}public void fun(String name, int age){this.name = name;this.age = age;}public void print(){System.out.println("name :" + this.name);System.out.println("age :" + this.age);}
}
public class Test{public static void main(String[] args){student stu = new student();}

7.2构造

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

使用如下:

class student{//成员变量public String name;public int age;//构造方法public student(String name, int age){//public 可加可不加,后期会讲this.name = name;this.age = age;System.out.println("name:" + this.name + "age:" + this.age);}//成员方法public void fun(String name, int age){this.name = name;this.age = age;}public void print(){System.out.println("name :" + this.name);System.out.println("age :" + this.age);}
}
public class Test{public static void main(String[] args){student stu = new student("jay chou",46);}

执行过程如下:


7.2.1 构造重载

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

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



8.static修饰的静态变量

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


8.1类变量和类方法

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

如下代码:

class Student{public String name;public int score;//类变量public static String classes = "火箭6班";//类方法public static void fun1(){System.out.println("类方法");}
}
public class Test {public static void main(String[] args){Student stu = new Student();System.out.println(Student.classes);Student.fun1();}
}

内存布局如下:

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

如下代码:

class Student{public String name;public int score;//类变量public static String classes = "火箭6班";//类方法public static void fun1(){name = "jay";//错误System.out.println("类方法");}public void fun2(){name = "jay";//正确}
}
class Student{public String name;public int score;//类变量public static String classes = "火箭6班";//类方法public static void fun1(){Student stu = new Student();stu.name = "jay";           //正确System.out.println("类方法");}
}

8.2代码块

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

http://t.csdn.cn/NGixv



9.内部类

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


9.1实例内部类

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

如下代码:

class OutClass{//成员变量public int data1 = 1;private int data2 = 2;public static int data3 =3;//类变量//构造方法public OutClass(){System.out.println("外部类的构造方法!");}//实例内部类class InsideClass{//成员变量public int data1 = 4;private int data2 = 5;public static final int date3 = 6;//必须用 final 修饰为常量,必须初始化//构造方法public InsideClass(){System.out.println("实例内部类的构造方法!");}//成员方法public void fun2(){System.out.println(OutClass.this.data1);//访问外部System.out.println(data2);//优先访问内部System.out.println("实例内部类的成员方法");}}//成员方法public void fun1(){OutClass.InsideClass inside = new InsideClass();//外部类中需要先创建对象内部类对象System.out.println(inside.data1);//在外部类中访问内部类成员System.out.println(inside.data2);System.out.println("外部类的成员方法!");}}
public class Test{public static void main(String[] args){OutClass out = new OutClass();OutClass.InsideClass inside = out.new InsideClass();//必须建立在外部类对象的前提的下}
}

9.2静态内部类

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

如下代码:

class OutClass{public int data1 = 1;private int data2 = 2;public static int data3 = 3;public OutClass(){System.out.println("外部类的构造方法!");}static class InsideClass{public int data3 = 3;private int data4 = 4;public static int data5; // 可以不加final修饰,可以不用先初始化public InsideClass(){System.out.println(OutClass.data3);//只能访问外部静态的变量OutClass out = new OutClass();out.fun1();//访问外部非静态成员System.out.println("静态内部类构造方法!");}public void fun2(){System.out.println("静态内部类成员方法!");}}public void fun1(){System.out.println(InsideClass.data5);//没引入内部类对象前只能访问静态变量OutClass.InsideClass inside = new OutClass.InsideClass();System.out.println(inside.data3);//访问静态内部类System.out.println("外部类的成员方法!");}}
public class Test{public static void main(String[] args){//创建静态内部类对象时不需要先创建外部类对象OutClass.InsideClass inside = new OutClass.InsideClass();}
}

9.3局部内部类

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

如下代码:

class OutClass{public int data1 = 1;private int data2 = 2;public static int data3 = 3;public OutClass(){System.out.println("外部类构造方法!");}public void fun(){System.out.println("外部类成员方法!");//局部内部类class InsideClass{public void fun(){System.out.println("外部类成员变量:" + data1);}}}}
public class Test{public static void main(String[]  args){OutClass out = new OutClass();out.fun();}
}


10.封装、继承、多态

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

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

http://t.csdn.cn/KUJrv



11.抽象类(abstract)

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

注意事项:

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

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

abstract class Human{public abstract void func();
}
class Art extends Human{@Overridepublic void func(){System.out.println("画画~");}
}
class Music extends Human{@Overridepublic void func(){System.out.println("唱歌~");}
}
public class Test{public static void function(Human human){human.func();}public static void main(String[] args){//Human human = new Human();//抽象类不能实例化对象Human human1 = new Art();Human human2 = new Music();function(human1);function(human2);}
}


12.接口

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

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

注意事项:

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

例子:

abstract class Animal{public String name;public int age;Animal(String name, int age){this.name = name;this.age = age;}public abstract void eat();
}
interface IRun{int a = 1;void run();
}
interface IFly{void fly();
}
class Brid extends Animal implements IRun, IFly{Brid(String name, int age){super(name,age);}@Overridepublic void eat(){System.out.println(name + "正在吃小虫子~");}@Overridepublic void run(){System.out.println(name + "正在用两条腿蹦来蹦去~");}@Overridepublic void fly(){System.out.println(name + "正在飞翔~");}
}
class Dog extends Animal implements IRun{Dog(String name, int age){super(name, age);}@Overridepublic void eat(){System.out.println(name + "正在啃骨头~");}@Overridepublic void run(){System.out.println(name + "正在用四条腿跑~");}
}
public class Test{public static void func1(Animal animal){animal.eat();}public static void func2(IRun run){run.run();}public static void func3(IFly fly){fly.fly();}public static void main(String[]  args){func1(new Brid("小鸟",1));func1(new Dog("狗子",2));func2(new Brid("小鸟",1));func2(new Dog("狗子",2));func3(new Brid("小鸟",1));}
}

12.1制作一个简单的比较器

import java.util.Arrays;
import java.util.Comparator;class Student /*implements Comparable<Student>*/ {public String name;public int age;public int score;public Student(String name, int age, int score) {this.name = name;this.age = age;this.score = score;}@Overridepublic String toString() {return "Student = {" +name + ", " + age+ ", " + score +"} ;";}
}
//比较器
class AgeCompare implements Comparator<Student>{@Overridepublic int compare(Student o1, Student o2) {return o1.age - o2.age;}
}
class ScoreCompare implements Comparator<Student>{@Overridepublic int compare(Student o1, Student o2){return o1.score - o2.score;}
}
class NameCompare implements Comparator<Student>{@Overridepublic int compare(Student o1, Student o2){return o1.name.compareTo(o2.name);}
}
public class Test {public static void main(String[] args){Student[] student = new Student[3];student[0] = new Student("张三",19,90);student[1] = new Student("李四",17,82);student[2] = new Student("王五",18,85);System.out.println("排序前:" + Arrays.toString(student));Arrays.sort(student,new ScoreCompare());System.out.println("排序后:" + Arrays.toString(student));}


13.浅拷贝和深拷贝

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

http://t.csdn.cn/bu7wd



14.Object类

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

如下代码:

import java.util.Objects;
class A{}
class B{}
public class Test{public static void main(String[] args){Object obj1 = new A();Object obj2 = new B();System.out.println(obj1);System.out.println(obj2);}
}

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

import java.util.Objects;
class Human{public String id;public Human(String id){this.id = id;}@Overridepublic boolean equals(Object obj){if(obj == null){//判断参数是否为空return false;}if(this == obj){//判断地址是否相等return true;}Human tmp = (Human)obj;return this.id.equals(tmp.id);}}
public class Test{public static void main(String[] args){Object o1 = new Human("610");Object o2 = new Human("610");System.out.println(o1.equals(o2));}
}


15.String类

string的三种定义方法

public class Test {public static void main(String[] args){String str1 = "hello";String str2 = new String("world");char[] s = {'a','b','c'};String str3 = new String(s);}
}

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


15.1字符串常量池

观察如下代码 s1 == s2 ?

public class Test {public static void main(String[] args){String str1 = "hello";String str2 = "hello";System.out.println(str1 == str2);}
}

内存分析:


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

博主已经整理好博客啦

http://t.csdn.cn/n1n5z


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

public class Test {public static void main(String[] args){String str1 = "hello";String str2 = "hell";System.out.println(str1.equals(str2));}
}

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

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

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

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

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

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

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

public class Test {public static void main(String[] args){//double转StringString str1 = String.valueOf(12.5);System.out.println(str1);//String转intint value =Integer.valueOf("64");System.out.println(value);}
}

15.3.6小写转大写(toUpperCase())

public class Test {public static void main(String[] args){String str1 = "abc";String str2 = str1.toUpperCase();System.out.println(str2);}
}

15.3.7大写转小写(toLowerCase())

public class Test {public static void main(String[] args){String str1 = "ABC";String str2 = str1.toLowerCase();System.out.println(str2);}
}

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

class Solution {private boolean legal(char ch){if(((ch >= 'a') && (ch <= 'z')) || ((ch >= '0') && (ch <= '9'))){return true;}return false;}public boolean isPalindrome(String s) {s = s.toLowerCase();int left = 0;int right = s.length() - 1;while(left < right){while(left < right && !legal(s.charAt(left))){left++;}while(left < right && !legal(s.charAt(right))){right--;}if(s.charAt(left) != s.charAt(right)){return false;}left++;right--;}return true;}
}

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

public class Test {public static void main(String[] args){String str1 = "hello";char[] str2 = str1.toCharArray();System.out.println(str2);}
}

15.3.9字符串切割(split())

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

15.3.10字符串替代(replaceFirst())

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

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

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

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

public class Test {public static void main(String[] args){Scanner scanner = new Scanner(System.in);String str = scanner.nextLine();int i = 0;int count = 0;for(i = str.length() - 1; i > 0; i--){if(str.charAt(i) == ' '){break;}count++;}System.out.println(count);}
}

16.异常处理

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

1.LBYL:事前防御型

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

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

2.EAFP:事后认错型

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

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

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

如下代码:

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

面试题:

throw 和 throws 的区别?

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

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

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

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

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

面试题:

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

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


16.2自定义异常

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

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

class NetworkException extends Exception{public NetworkException(String message){super(message);}
}
public class Test{public static void send (String networdState) throws NetworkException{if(networdState.equals("网络异常")){throw new NetworkException("网络状况不佳,无法发送消息!");}}public static void main(String[] args){//相应处理...发生网络异常String networdState = "网络异常";try{send(networdState);}catch(NetworkException e){e.printStackTrace();//打印栈区情况}}
}

运行结果:

【Java SE】SE“细节”知识大总结相关推荐

  1. Java SE 部分基础知识

    javaSE基础 1.介绍 2.学习方法 先理解,再实践 认知天性:编码->巩固(回顾,复习,过遍数)->检索 刻意练习:3F ​ focus: ​ feedback:反馈,主动,被动,英 ...

  2. 2020年末知识大总结:Java程序员转Android开发必读经验一份,嵌入式开发入门教程

    Android是主流智能手机的操作系统,Java是一种开发语言,两者没有好坏优劣之分,只是两种职业岗位的选择.学安卓从事移动互联方向开发,学Java从事软件.网站开发.而安卓上的应用大多是Java编写 ...

  3. 初学Java该学哪些知识?这6大知识必学

    目前,Java是开发人员的热宠,很多论坛都有不少热爱Java的开发人员,也有不少想成为Java程序员,但苦于不知道该如何学习Java,也不清楚该学些什么知识才能成为一个Java程序员.小千在这里抛砖引 ...

  4. 刷新器-Java EE 7后端十大功能

    这是我的Java EE 7小知识系列的第二部分. 在进行简要介绍的第一个介绍之后,我决定请Arjan Tijms撰写有关Java EE 7中他最喜欢的新后端功能的文章.如果您关注Java EE领域,您 ...

  5. Java语言的基础知识

    目录 一. 步入Java编程 1.1 Java的发展史 1.2 Java的基本思路 1.3 Java的工作原理 1.4 搭建Java环境 面试解析与技巧 二. java开发基础 2.1 java语法基 ...

  6. 关于Java的JIT(即时编译器)知识整理

    文章目录 前言 一.JIT(即时编译器) 1.1 解释执行和编译执行的区别 1.2 Java代码编译过程 1.3 JIT是什么 二.HotSpot是什么 2.1 说JIT比解释快,其实说的是" ...

  7. java项目实战应用知识概括

    java项目实战应用知识概括 Jasypt 加密 ICU4J Idea插件 BI商业智能 Google验证码Kaptcha 数据脱敏 QRCode二维码 邮件发送与接收 富文本与Markdown Ja ...

  8. Java Web 编程入门知识

    Java SE 的内容基本都讲完了. 但是 Java一般用于网络编程, 就是所谓的web编程. Java SE讲的基本上都是本地程序的内容. 而Java web编程需要在两个程序中传输数据, 以后就是 ...

  9. 必读!Java开发人员的十大戒律

    以下是笔者列举的Java开发人员的十大戒律: 一. 在你的代码里加入注释 每个人都知道这点,但不知何故忘记了遵守.算一算有多少次你"忘记"了添加注释?这是事实:注释对程序在功能上没 ...

最新文章

  1. Django REST framework API 指南(12):验证器
  2. 看美女有助于男士长寿
  3. 探索Julia(part2)--关于IDE
  4. python正则表达式group用法_【Python】正则表达式用法
  5. LeetCode-MySQL-174. 第二高的薪水
  6. 【十五分钟Talkshow】如何理解并优化.NET应用程序对内存的使用
  7. 手柄游戏之《恶魔城暗影之王》推荐
  8. idea svn分支与分支合并_IDEA用SVN创建分支和合并分支的方法步骤
  9. 列车停站方案_浅谈地铁列车停站方案.doc
  10. 如何在Oracle中检测和修复块损坏
  11. Win10如何删除登录账号?Win10删除登录账号的方法
  12. 每晚泡脚15分钟,5年下来有哪些变化
  13. python2.7运行报警告:UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode
  14. 计算机游戏快速退出的快捷键,电脑玩游戏怎么快速切回桌面
  15. 数字IC后端设计技术全局观
  16. matlab对稀疏矩阵求特征值,使用ARPACK查找稀疏矩阵的特征向量和特征值(称为PYTHON,MATLAB或FORTRAN子例程)...
  17. maven项目调转servlet 500异常
  18. 读《臧圩人的Java面试题解惑系列》
  19. Druid and Imply
  20. Fix for BOOTMGR Error

热门文章

  1. CSS cursor(鼠标状态)属性
  2. 一脚蹬+健走鞋 咕咚5K2.0智能跑鞋强势回归
  3. 网络通是免费的内网端口映射软件
  4. 关于MySQL 出现问题:1264 - Out of range value for column 'columns' at row 167
  5. 南京中软/软通/金证/易宝等外包公司面试题
  6. javaScript基础面试题 ---闭包
  7. 让Enter键实现Tab键的功能
  8. Dagger2的基本使用
  9. 学习数学建模算法与应用【数据预处理】
  10. ROS十年期安全维护由Open Robotics和Canonical提供