Java基础笔记(无限整合更新)

Java必学的基础部分为1-10章,其中每个部分包含少量的扩展内容,而扩展内容会随着时间增加,对于初学者不必太纠结扩展内容,当基础内容学完,扩展内容便可达到一种豁然开朗的程度。
建议初学自学者根据视频结合自己的理解参考本笔记,右侧有大纲,点击直达相关位置,对于未来的复习也很有帮助。
对于自学,视频建议观看狂神,和尚硅谷。在这里也要感谢他们提供了免费的学习路线和全套的教学视频。本笔记参考了许多教程视频,整合而来。

希望初学者,对Java感兴趣,对做网站感兴趣,对编程感兴趣,对底层充满好奇,对计算机充满好奇,对这个世界充满好奇。
什么东西都不是凭空产生的,多了解底层,了解实现这些功能背后的原理。

如果你想做一个自己的动态网站,相信你自己,通过传统路线很快就能达到。

[info:]
本文使用MarkDown语法编写

0、初见:

编程语言发展史:(点击查看链接)

第一代:机器语言。二进制,直接输入给计算机使用,不经过任何的转换。

第二代:汇编。相对机器语言人性化了不少。

第三代:高级语言。面向过程(如:C语言)和面向对象(如:C++语言、JAVA语言、C#语言、Python、PHP、JavaScript)

Java发展史:

Java是在1991年由SUN公司的James Gosling(Java之父)及其团队所研发的一种编程语言。

在1995年更名为Java(印度尼西亚爪哇岛的英文名称,因盛产咖啡而闻名)。

JAVA语言特性:

  • JAVA是一种面向对象的编程语言

  • 简单易学:相对于其他编程语言来说,JAVA语言的语法相对简单,易于学习和理解。

  • 平台无关性:JAVA程序可以在不同的操作系统上运行,只要安装了JAVA虚拟机(JVM)即可。

  • 面向对象:JAVA是一种纯粹的面向对象的编程语言,通过封装、继承和多态等特性,可以更好地组织和管理代码。

  • 安全性:JAVA提供了一些安全性机制,如类加载机制、异常处理机制以及访问控制等,可以保证程序的安全性。

  • 高性能:虽然JAVA是解释型语言,但通过JIT编译器的优化,可以提高代码的执行效率。

  • 线程支持:JAVA内置了对线程的支持,方便开发多线程程序,实现并发操作。

  • 开放性:JAVA提供了大量的开源库和框架,方便开发人员快速构建复杂的应用程序。

  • 可移植性:由于JAVA的平台无关性,JAVA程序可以在不同的硬件平台上运行,保证了程序的可移植性。

  • 自动内存管理:JAVA通过垃圾回收器(Garbage Collector)来管理内存,开发人员无需手动进行内存管理。

Java的三大版本:

  • JavaSE:Java平台的标准版,它提供了Java语言的核心API和基本功能,适用于开发普通的桌面应用程序、命令行工具和服务器端应用程序等。
  • JavaME(Java Micro Edition):是Java平台的微型版,专门设计用于嵌入式设备和移动设备的应用程序开发。我们熟知的Android它所运行的app也是由Java编写的(更多可了解kotlin)
  • JavaEE(JavaEnterpriseEdition):是Java平台的企业版,用于开发大型、复杂的企业级应用程序。JavaEE提供了一套丰富的API和服务,用于构建分布式、可扩展和安全的企业应用。

JDK\JVM\JRE的区别:

  • JDK(Java Development Kit)Java开发工具包,包含Java语言、Java虚拟机、Java类库,是支持Java程序开发的最小环境。
  • JVM(Java Virtual Machine)Java虚拟机,运行于各种操作系统Linux,Windows,Solaris等之上,执行编译好的Java字节码class文件。
  • JRE(Java Runtime Environment)Java运行时环境,包含JavaSE中核心类库API和Java虚拟机,简单理解为JVM+核心类库API。

配置Java环境变量

  1. 下载JDK https://www.oracle.com/java/technologies/downloads/

  2. 右键 This PC(此电脑) -> Properties(属性) -> Advanced system settings(高级系统设置) -> Environment Variables(环境变量)

  3. 新建JAVA_HOME 变量

    1. 变量名:JAVA_HOME
      变量值:电脑上JDK安装的绝对路径
      
  4. 新建/修改 CLASSPATH 变量

    1. 变量名:CLASSPATH
      变量值:.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;
      
  5. 新建两条Path路径

    1. %JAVA_HOME%\bin
      %JAVA_HOME%\jre\bin
      
  6. 打开cmd输入 java 出现一连串的指令说明配置成功了。

O.o 常见的Dos命令:

Win键+R 输入"cmd"打开

切换盘符:

格式:盘符 + :

C:\User\Administrator>d:
D:\>

查看当前目录下所有的文件夹和文件

格式:dir+Enter回车(dir是英文directory的缩写,意为“目录)

切换目录
格式:cd+空格+要切换的目录(cd是英文change directory的缩写)

D:\> cd softwareDevelopment
D:\softwareDevelopment>

输入cd…返回上一层目录

D:\softwareDevelopment>cd..
D:\>

回到此盘根目录

D:\softwareDevelopment\doc\ajax>cd\
D:\>

创建文件夹
格式:md+空格+文件夹名称(md是英文make directory的缩写)

删除文件夹
格式:rd+空格+文件夹名称(rd是英文remove directory的缩写)

创建文件
格式:copy con+空格+文件名

删除文件
格式:del+空格+文件名(del是单词delete的简写)

清屏
格式:cls(cls是英文clear screen的缩写)

退出命令行界面
格式:exit

o.O hello word

新建一个文件夹,创建一个名为Hello后缀为.java的文件

编辑内容:(可以使用notepad++编辑)

public class Hello{
    public static void main(String args){
        System.out.println("Hello,World!");
    }
}

开始编译:

在这个Java文件的地址栏输入cmd回车

输入 javac Hello.java

会在目录里生成class文件

输入 Hello

运行成功后会输入一句Hello,World!

可能遇到的情况:

  • Java大小写时非常敏感的,主要大小写
  • 尽量使用英文
  • 文件名和类名必须保持一致,并且首字母大写
  • 结尾分号,使用英文分号
  • 以上情况都没遇到则可能是之前Java环境配置出现了问题

如何学习Java

Java是一个面向对象编程的编程语言,重在培养面向对象的编程思想,这是根据自己的理解一步步形成的思想。

遇到困难或者不能理解的部分,要多思考,当然可能依然是似懂非懂的感觉,但是学习到了后面就会逐渐理解。

要学会自己做笔记,最好是自己发表博客,像我一样,每天都要写,每天都要发布。如果你也发表了博客请记得艾特我,我也好奇你写的啥。

必学MarkDown语法

无论是做笔记还是编写博客,或者以后写项目的说明档.md文件都需要学习MarkDown语法,这个很简单也很好学习,教程很多,例如你编辑一篇新的CSDN文档的时候,默认显示的就是语法教程(在编辑界面右上角也有语法说明)。

个人记笔记建议使用Typora,是一款很方便的markdown语法编辑器,这里附上教程:

Typora的使用教程(CSND)


1、注释Comments

package com.bsy;
/**
 * @author bsy
 * 文档注释
 */
public class Comments {
    public static void main(String[] args) {
        //编辑注释
        //TODO 标签主要标记遇到的问题
        //在工具类最下方点击TODO窗口,可以查看当前所有的项目代码中标识的TODO标签
        System.out.println("hello worold!!!");
        /*
         * 长注释
         *
         *
         * 注释在setting → editor → Java 中的 comments中进行设置样式
         *
         * comments表示注释的意思,翻译可以为“评论”的意思
         *
         */
    }
}

1.1、标识符Identifier

        //TODO 标识符的命名规则
        //1,英文字母
        String name = "xiaoming";
        String xingming = "xiaohong";
        //2,可使用的符号
        //标识符只能采用下划线和美元$符号,其余不可用,包括空格、@、#、%等
        String _name = "";
        String $name = "";
        //3,数字
        //0-9阿拉伯数字只能放在标识符的除开头以外的位置,放在开头会被识别为数字而非标识符
        //4,一个作用域内不允许出现同名(标识符不允许重复)。
        //5,标识符区分大小写
        //6,标识符不能为Java关键字(例如static、public、final等
        //7,使用驼峰命名,先小后大;尽量见名知意(看见其名字就知道其含义)。
        String userNameFist = "";
        //8,标识符长度没有限制

2、基本数据类型Primitive Tpye

package com.bsy;
public class PrimitiveType {
    //整数类型Datatype:
    //bit位:比特,数据运算的最小单位,采用二进制存储,见下方。
    byte numByte = -128;//字节。1byte=8bit位
    byte numByte1 = 127;//字节:计算机存储数据的最小单位
    short numShort = -32768;//16位
    short numShort1 = -32767;
    int numInt = -2147483648;//32位
    int numInt1 = 2147483647;
    long numLong = 30L;//64位,Long类型后面加上L进行标记(范围-9223372036854775808L~9223372036854775807L)

    //浮点数
    float numFloat = 50.1F;//单精度浮点类型
    //Float类型在后面加上F进行表示,部分大小写,不写f会被识别为双精度。范围+/-3.4E+38F(6~7 个有效位)
    double numDouble = 3.1415926;//双精度浮点类型
    //+/-1.8E+308 (15 个有效位)

    //布尔
    boolean aBoolean = true;// ture or false

    //字符
    char aChar = '字';//单一字符(ISO 单一字符集)

    //字符串(不是关键字,不属于八大类型,是类)
    String name1 = "字符串";

    /*
     * bit 位 最小存储单位,例如 11001100是一个 八位 二进制 数。
     * 1Byte = 8bit(1B = 8b)
     * 1KB = 1024B
     * 1M  1024KB
     * 1G = 1024M
     */
}

2.1、扩展

2.1.1 Float、Double

float 是有限 离散 舍入误差 大约 接近但不等于的。不要用浮点型进行作比较。因为↓

float d1 = 123123123F;
float d2 = d1 +1;
System.out.println(d1 == d2);//ture

如果要使用很大的数值作比较可以使用一个现有的类

BigDecimal 数学工具类

2.1.2 强制转换

所有的字符本质是数字

char a1 = 'a';
char a2 = "中";
System.out.println(a1);//a
System.out.println((int)a1);//97
System.out.println(a2);//中
System.out.println((int)a1);//20013

Unicode编码表对应的编号数字(范围:U0000 - UFFFF)

char a3 = '\u0061';
System.out.println(a3);//a
2.1.3 转义字符

摘录自掘金网

\r 表示回车符,将光标定位到当前行的开头,不会跳到下一行。

\n 表示换行符,换到下一行的开头。

\t 表示制表符,将光标移到下一个制表符的位置,就像在文档中用Tab键一样。

\b 表示退格符号,就像键盘上的Backspace键。

Java以下的字符都有特殊意义,无法直接表示,所以用反斜杠加上另外一个字符来表示。

\’ 表示单引号字符,Java代码中单引号表示字符的开始和结来,如果直接写单引字符('),程序会认为前两个是一对,会报错,因此需要使用转义符“\’”。

\" 表示双引号字符,Java代码中双引号表示字符串的开始和结来,包含在字符串中的双引号需要转义,比如(hesays,\”thankyou\”.)。

\ 标识反斜杠字符,由于在Java代码中的反斜杠(\)是转义字符,因此需要表示字面意义上的\,就需要使用双反斜杠(\)。

2.1.4 布尔值扩展
boolean flag = ture;
if (flag==ture){}
if (flag){}//默认等于ture,可以不写=ture
//Less is More!  代码要精简易读,更少就是更多。

2.2、引用数据类型

类、字符串、接口、数组、枚举等可以引用的数据类型都是引用数据类型

String name = "xiaoming";//这就是一个引用数据类型

3、类型转换

Java是强类型语言,运算时要进行类型转换

从上方得知,每种数据类型所能包含数的大小是不同的,例如你用一个32位的int大盒子装小的16位short盒子肯定可以直接装下。但是用小盒子装大盒子不是说不能装,而是会丢失一部分大盒子里的数据(精度丢失见下方)。

低 -------------------------------------------------→高

byte -> short -> char -> int -> long -> float -> double

3.1、强制类型转换

上面说到盒子的例子,在Java里低转高需要进行强制转换。

//高到低
int i = 128;
byte b = (byte)i;//byte最大127此时会发生内存溢出
//强制转换格式: (类型)变量名

3.2、自动类型转换

//低到高
int i = 128;
double b = i;//128.0

demo:

//根据上方的从低到高的顺序举例
byte b = 10;
short s = b;
int i = s;
long lon = i;
float f = lon;
double d = f;

注意:

​ 1,不能对布尔值进行转换。

​ 2,不能吧对象类型转换为不相干类型。

​ 3,在把高容量转换到低容量的时候,要使用强制转换。

​ 3,转换的时候可能存在内存溢出,或者精度问题。

//精度问题
System.out.println((int)23.7);//23
System.out.println((int)-45.89f);//-45
//char
char c = 'a';
int d = c + 1;
System.out.println(d);//98
System.out.println((char)d);//b
//可以将Unicode表打印出来
for(i=0;i<26;i++){
    char c = 'a';
    int d = c+i;
    System.out.println((char)d);
}

扩展:

int money = 100_000_000;//数字之间可以使用下划线分割
int years = 20;
int total = money*years;//内存溢出
long total2 = money*years;//依然内存溢出,因为先计算int类型之后才进行转换

long total3 = money*((long)years);//先把一个数转换为long就可以
System.out.println(total3);

4、变量&常量

变量,可以改变的向量存储

变量:

package com.bsy;

public class Demo1 {
    //类变量
    static double salary = 2500;
    //实例变量
    //布尔值:默认false
    String name;//默认值 null
    int age;//默认值0
    //main方法
    public static void main(String[] args) {
        //局部变量
        int i = 10;
        System.out.println(i);

        Demo1 demo1 = new Demo1();
        System.out.println(demo1.age);
        System.out.println(demo1.name);

        //类变量 static
        System.out.println(salary);
    }
}

常量:

package com.bsy;

public class Demo2 {
    //修饰符不分先后顺序,写成final statci对结果没有影响
    static final double PI = 3.14;//常量名使用大写
    /*
        常量定义格式:
        final 常量名 = 值;
     */
    public static void main(String[] args) {
        System.out.println(PI);
    }
}

(命名要见名知意,遵循驼峰命名法。常量使用大写字母加下划线MAX_VALUE。方法名首字母小写)

5、运算符

5.1、算术运算符

+(加),-(减),*(乘),/(除),%(求余),++(自增),–(自减)

System.out.println(1+2);
System.out.println(2-2);
System.out.println(3*2);
System.out.println(4/2);
System.out.println(1/2);//0(int,int)=>int
System.out.println(1.0/2);//0.5(double,int)=>double
System.out.println(5%2);//1(取余,模运算)
//TODO 最小使用类型位int
byte b1 = 10;
byte b2 = 20;
int b3 = b1 + b2;//如果写按照上面的(byte,byte)=>byte就不行了
byte b4 = (byte)(b1 + b2);//强转可使其为byte类型
//Java计算也是由优先级的
System.out.println(1 + 2 * 3);//7
System.out.println((1 + 2) * 3);//9
5.1.1、自增自减:
// ++  --
//a = a + 1;
int b = a++;//先赋值,再自增。相当于b=a,然后再进行下一步自增,也就是隐藏了一步代码

int c = ++a;//先自增,再赋值。上面自增之后a=4,这里a先自增a=5,再赋值给c。

int i = 0;
int j = i++;//先赋值给j,赋值时i还没有自增。
System.out.println(i +"\n"+ j);//i = 1,j = 0
int i = 0;
int j = ++i;//i先自增为1再赋值给j,此时j为1
System.out.println(i +"\n"+ j);//i = 1,j = 1
5.2、赋值运算符

=(等于),+=(自加一次等于),-=(自减一次等于),*=(自乘一次等于),/=(自除一次等于),+(字符串连接符)

//等号就是赋值运算符:将等号右边的表达式结果赋值给等候左边的变量
//赋值运算符需要考虑类型的关系
String name = "zhangsan";
byte b = 10;
char c = '字';
//复合赋值运算符
//如果元素进行运算后重新赋值给自己,那么可以将运算和赋值的符合进行简化
int i = 1;
i = i + 1;
i += 1;//其他的 -=、*=、/=同理
//如果使用复合赋值运算,那么数据的类型不会发生变化
byte b = 10;
b = b + 20;//20默认为int类型,而int不能直接转换为byte,所以报错。
b += 20;//但是使用复合赋值运算则不会。
5.3、比较(关系)运算符

用于比较两个数据之间关系的运算符,返回结果只有:true或者false

(大于),<(小于),>=(大于等于),<=(小于等于),==(比较等于),!= instanceof(不等于)

int i = 10;
int j = 20;
System.out.println(i > j);//false
System.out.println(i < j);//ture
5.4、逻辑运算符

&(按位与),&&(短路与),|(按位或),||(短路或),!(非,即取反)

5.4.1、与&&或||非!
boolean a = ture;
boolean b = false;

System.out.pintln("a && b:"+(b&&a));//逻辑与运算:两个变量都为真,结果才为真ture
System.out.pintln("a || b:"+(a||b));//逻辑或运算:两个变量只要有一个为真,则结果就为真ture
System.out.pintln("!(a && b):"+!(a&&b));//如果是真,则变为假,如果是假,则变为真。

//逻辑与运算:如果第一个变量都为假,则第二个就不会运算直接输出结果为假:
//短路运算:
int c  = 5;
boolean d = (c<4)&&(c++ <4);
System.out.pintln(d);
System.out.pintln(c);//5	因为与运算要求两个都为真结果才为真,但是第一个都为假,所以直接输出结果false,根本不需要第二个运算。如果做了第二个运算说明输出结果为6,本程序说明了&&运算的逻辑。
5.4.2、位运算(都是基于二进制来计算):

位运算符:& | ^ ~ >> << >>>

&(按位与),|(按位或),^(异或运算),<<(左移运算符),>>(右移运算符),>>>(无符号运算符),~(非、取反运算符)

**效率极高!!!**因为是底层,可以做一些很巧妙的计算。

/*
	A = 0011 1100
	B = 0000 1101
	
	A&B = 0000 1100 (进行每一位的比较,上下都是1才为1,不是则为0)
	A|B = 0011 1101 (如果每个位都为0结果才为0,否则为1)
	A^B = 0011 0001 (异或运算,两个位相同则为0,否则为1)
	~B = 1111 0010 (取反)
	
	<<	(左移:相当于 *2) 
	>>	(右移:相当于 /2) 举例:
	将2*8 更快的计算出来:(计算机理解为2*2*2*2)
	System.out.pintln(2<<3);//16
	
	二进制里面表示的数为:
	0000 0000	0
	0000 0001	1
	0000 0010	2
	0000 0011	3
	0000 0100	4
	0000 1000	8
	0001 0000	16
	把1数字向左移动一位,数字就变大,2移动一位就变成4了。移动3位就变成16,所以2*2*2*2看乘几个2就移几位。而移动3位就是16。
	*/
5.5、条件(三元)运算符?:

三个元素参与运算的运算符

// x ? y : z
//如果x==ture,则结果为y,否则结果为z
int score = 80;
//如果成绩大于 60 则为及格,给一个String类型的变量type赋值为“及格”
String type = score < 60 ? "不及格" : "及格";
5.6、扩展赋值运算符:

+= -= *= /=

int a = 10;
int b = 20;

a += b;//a = a+b
a -= b;//a = a-b
……
5.6.1、字符串连接符 +
int a = 10;
int b = 20;
//字符串连接 + 两侧只要一方出现String类型,就变成字符串拼接
System.out.pintln(""+a+b);//1020
System.out.pintln(a+b+"");//30
//程序是自上而下自左而右运算的,当字符串在前面则识别为字符串拼接,当运算在前面则先进行运算。
5.6.2、优先级()

跟数学算数一样,优先算一部分。

System.out.println(1 + 2 * 3);//7
System.out.println((1 + 2) * 3);//9
5.7、Math 数学工具类

很多特殊的运算都需要到它,例如幂运算。


6、包机制

包的本质就是文件夹

**包名:**域名倒置。例如com.baidu

**导包:**import

**导入包下所有类:*通配符

import com.clover.base.*;

7、JavaDoc

@author 作者名

@version 版本号

@since 指明需要最早使用的jdk版本

@param 参数名

@return 返回参数情况

@throws 异常抛出情况

可使用CMD命令生成说明文档:

javadoc -encoding UTF-8 -charset UTF-8 Doc.java

(encoding编码格式,charset字符集编码)

使用IDEA生成doc文档

Tools > Generate JavaDoc

参数举例:-encoding UTF-8 -charset UTF-8 -windowtitle “文档HTML页面标签的标题” -link http://docs.Oracle.com/javase/7/docs/api

8、Java流程控制

Java基础的第二部分,前面就像是游戏的新手教程,现在可以开始玩了。

8.1、Scanner对象

获取用户的输入

8.1.1、next()
package com.bsy;

import java.util.Scanner;

public class scannerDemo1 {
    public static void main(String[] args) {
        //创建一个扫描器对象,用于接收键盘数据
        Scanner scanner = new Scanner(System.in);//System.in输入,System.out输出

        System.out.println("使用next方式接收:");

        //判断用户有没有输入
        if (scanner.hasNext() == true){//默认为ture可以省略不写
            String str = scanner.next();
            System.out.println("输出的内容为" +str);
        }
        scanner.close();//IO流类的用完关掉,节省资源。好比水龙头用完要关掉。
        /**
         * 1、一定要读取到有效字符后才可以结束输入。
         * 2、对输入有效字符之前遇到的空白,next()方法会自动将其去掉。
         * 3、只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符。
         * 4、next()不能得到带有空格的字符。
         */
    }
}

8.1.2、nextLine()
package com.bsy;

import java.util.Scanner;

public class scannerDemo2 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("使用nextLine方式接收:");
        if (scanner.hasNext()){
            String str = scanner.nextLine();
            System.out.println("输出内容为:"+str);
        }
        scanner.close();
		/**
         * 1、以Enter为结束符,也就是说nextLine()方法返回的输入回车之前的所有字符。
         * 2、可以获得空白。
         */
    }
}

不使用if语句:

package com.bsy;

import java.util.Scanner;

public class scannerDemo3 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输出数据:");
        String str =  scanner.nextLine();
        System.out.println("输出的内容为:"+str);
        scanner.close();
    }
}
8.1.3、next()的多种用法
package com.bsy;

import java.util.Scanner;

public class scannerDemo4 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        //从键盘接收数据
        int i = 0;
        float f = 0.0f;
        System.out.println("请输入整数:");
        if (scanner.hasNextInt()){
            i = scanner.nextInt();
            System.out.println("整数数据:"+i);
        } else {
            System.out.println("输入的不是整数数据!");
        }

        System.out.println("请输入小数:");
        if (scanner.hasNextFloat()){
            f = scanner.nextFloat();
            System.out.println("小数数据:"+f);
        } else {
            System.out.println("输入的不是小数数据!");
        }
        scanner.close();
    }
}
8.1.4、举例
package com.bsy;

import java.util.Scanner;

public class scannerDemo5 {
    public static void main(String[] args) {
        //我们可以输入多个数字,并求其总和与平均数,每输入一个数字用回车确认,通过输入非数字来结束输入执行结果。
        Scanner scanner = new Scanner(System.in);
        //和
        double sum = 0;
        //计算输输入了多少个数字
        int m = 0;
        //通过循环判断是否还有输入,并在里面对每一次进行统计求和统计。
        while ((scanner.hasNextDouble())){
            double x = scanner.nextDouble();
            m++;//m = m + 1;
            sum+=x;//sum = sum + x;
            System.out.println("你输入了"+m+"个数据,当前总和为:"+m+"当前平均值为:"+(sum / m));
        }
        System.out.println(m+"个数的和为"+ sum);
        System.out.println(m+"个数的平均值是"+(sum / m));
        scanner.close();
    }
}

8.2、顺序结构

Java的基本结构就是顺序结构,除非特别指明,否则就按照顺序一句一句执行。它是任何一个算法都离不开的一种基本算法结构。

8.3、选择结构

8.3.1、if
8.3.1.1、if单选择结构

很多时候需要判断一个东西是否可行,然后我们才会去执行,这样一个过程在程序中使用if语句来表示。

package com.bsy;

import java.util.Scanner;

public class IfDemo1 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入Tencent的中文名");
        String str = scanner.nextLine();

        if (str.equals("腾讯")){
            System.out.println("回答正确");
        }else {
            System.out.println("回答错误");
        }
        System.out.println("END");
        scanner.close();
    }
}
8.3.1.2、if多选择结构

if语句至多且必须有一个else语句,并且是在所有else if语句之后。

一旦其中一个else if语句检测为ture,其他else if以及else语句都将跳过执行。

package com.bsy;

import java.util.Scanner;

public class IfDemo3 {
    public static void main(String[] args) {
        //根据输入的分数划分等级
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入成绩:");
        int score = scanner.nextInt();

        if (score == 100){
            System.out.println("恭喜满分");
        } else if (score<100 && score>=90) {
            System.out.println("A");
        } else if (score<90 && score>=80) {
            System.out.println("B");
        } else if (score<80 && score>=70) {
            System.out.println("C");
        } else if (score<70 && score>=60) {
            System.out.println("D");
        } else if (score<60 && score>=0) {
            System.out.println("不及格");
        } else {
            System.out.println("成绩不合法");
        }
        scanner.close();
    }
}
8.3.1.3、if嵌套结构

8.3.2、switch多选择结构

switch case语句判断一个变量与一系列值中某一个值是否相等,每个值成为一个分支。

  • switch语句中的变量类型可以是:
    • byte
    • short
    • int
    • char
    • String
    • 同时case标签必须字符串或字面量
package com.bsy;

public class SwitchDemo1 {
    public static void main(String[] args) {
        //不写break会发生case穿透
        //switch匹配一个具体的值
        char grade = 'C';
        switch (grade){
            case 'A':
                System.out.println("优秀");
                break;
            case 'B':
                System.out.println("良好");
                break;
            case 'C':
                System.out.println("及格");
                break;
            case 'D':
                System.out.println("优秀再接再厉");
                break;
            case 'E':
                System.out.println("挂科");
                break;
            default:
                System.out.println("未知等级");
        }
    }
}

8.4、循环结构

8.4.1、while循环
  • while是最基本的循环
  • 只要Boolean表达式为ture,循环就会一直执行下去
  • 我们大多数情况是会让循环停止下来,需要一个让表达式时效的方式来结束循环。
  • 少部分情况需要一直执行,比如服务器的请求响应监听等。
  • 循环条件一直为ture就会造成死循环,我们正常的业务编程中应尽量避免死循环。回应性程序性能或者程序崩溃。

Demo1:

package com.bsy;

public class WhileDemo1 {
    public static void main(String[] args) {
        //输出1~100
        int i = 0;
        while (i<100){
            i++;
            System.out.println(i);
        }
    }
}

Demo2:

package com.bsy;

public class WhileDemo2 {
    public static void main(String[] args) {
        //计算1+2+3+...+100=?

        int i = 0;
        int sum = 0;

        while (i<=100){
            sum+=i;
            i++;
        }
        System.out.println(sum);
    }
}
8.4.2、do…while循环
  • 对于while语句,即使不满足条件也至少循环一次。
  • while和do…while的区别:
    • while先判断后执行,不满足条件一次都不会执行。
    • do…while先执行一次再进行判断,即使不满足循环条件也会至少循环一次。
package com.bsy;

public class DoWhileDemo1 {
    public static void main(String[] args) {
        int i = 0;

        while (i<0){
            System.out.println(i);
            i++;
        }
        System.out.println("----------------");
        do {
            System.out.println(i);
            i++;
        }while (i<0);

    }
}

8.5、for循环

  • 虽然所有循环结构都可以使用while或者do…while表示,但Java提供了另一种语句——for循环,使一些循环结构变得更加简单。
  • for循环语句是支持迭代的一种通用结构,是最有效、最灵活的循环结构。
  • for循环执行的次数是在执行之前就确定的。

while和for的对比:

package com.bsy;

public class ForDemo1 {
    public static void main(String[] args) {

        int a = 1;//初始化条件
        while (a<=100){//条件判断
            System.out.println(a);//循环体
            a+=2;//迭代
        }
        System.out.println("while循环结束!");
        //初始化   //条件判断//迭代
        for (int i=1;i<=100;i++){
            System.out.println(i);
        }
        System.out.println("for循环结束!");

    }
}

关于for循环:

  • 先执行初始化步骤,可以声明一种类型,但可初始化一个或多个循环控制变量,也可以是空语句。
  • 随后检测Boolean表达式,为ture循环体被执行。
  • 执行一次循环后,更新循环控制变量(迭代因子控制循环变量的增减)。
  • 再次检测Boolean表达式,循环上面的过程,如果为false则循环终止。
//死循环
for(;;){}

Demo1:

package com.bsy;

public class ForDemo2 {
    public static void main(String[] args) {
        //计算0到100之间奇数和偶数的和

        int oddSum = 0;
        int evenSum = 0;

        for (int i = 0; i <= 100; i++) {//快捷键100.for
             if (i%2 != 0){//奇数
                 oddSum+=i;
             }else {
                 evenSum+=i;//偶数
             }
        }
        System.out.println("奇数的和为:"+oddSum);
        System.out.println("偶数的和为:"+evenSum);
    }
}

Demo2:

package com.bsy;

public class ForDemo3 {
    public static void main(String[] args) {
        //用while或者for循环输出1-1000之间能被5整除的数,并且每行输出三个

        for (int i = 1; i <= 1000; i++) {
            if (i%5==0){//5的倍数
                System.out.print(i+"\t");//输出5的倍数,添加制表符使其易读。
            }
            if (i%(5*3)==0){//每行
                System.out.println();//换行
                //System.out.print("\n");
            }
        }
        //注意print和println的使用
    }
}

Demo3:九九乘法表

package com.bsy;

public class ForDemo4 {
    public static void main(String[] args) {
        //打印乘法表
        //1、先打印第一列
        //2、把固定的1再用一个循环包起来
        //3、去掉重复项 i <= j
        //4、调整样式

        for (int j = 1; j <= 9; j++) {
            for (int i = 1; i <= j; i++) {
                System.out.print(j+"*"+i+"="+(j*i)+"\t");
            }
            System.out.println();
        }
    }
}
8.5.1、增强for循环
  • Java5引入了一种主要用于数组或者集合的增强型for循环
package com.bsy;

public class ForDemo5 {
    public static void main(String[] args) {
        int[] numbers = {10,20,30,40,50};

        //遍历数组的元素
        for (int x:numbers){
            System.out.println(x);
        }
        //等同于:
        for (int i = 0; i < 5; i++) {
            System.out.println(numbers[i]);
        }
    }
}

8.6、Break & Continue

  • break在任何循环语句的主体部分,均可以用break控制循环的流程。break用于强行退出循环,不执行循环中剩余的语句。(break语句也在switch语句中使用)
package com.bsy;

public class BreakDemo {
    public static void main(String[] args) {
        int i =  0;
        while(i<100){
            i++;
            System.out.println(i);
            if (i==30){
                break;
            }
        }
        System.out.println("123");
    }
}
  • continue语句用在循环体语句体中,用于终止某次循环过程,即跳过循环体中尚未执行的语句,接着进行下一次是否执行循环的判定。
package com.bsy;

public class ContinueDemo {
    public static void main(String[] args) {
        int i = 0;
        while (i<100){
            i++;
            if ((i%10==0)){
                System.out.println();
                continue;
            }
            System.out.print(i);
        }
    }
}
8.6.1、Label标签
  • 关于goto关键字
    • goto关键字很早就在程序设计语言上出现。尽管goto仍是Java的一个保留字,但是并未在语言中得到正式使用;Java没有goto。然而在break和continue这两个关键字上,仍然能够看到一些goto的影子,那就是带标签的break和continue、
    • “标签”是指后面跟一个冒号的标识符,例如:label:
    • 对于Java来说唯一用到标签的地方就是在循环语句之前。而在循环之前设置标签的唯一理由:我们希望在其中嵌套另一个循环,由于break和continue关键字通常只中断当前循环,但若随同标签使用,他们就会终端到存在标签的地方。
package com.bsy;

public class LabelDemo {
    public static void main(String[] args) {
        //打印101-150之间所有的质数
        //指数:大于1的自然数中,除了1和它本身意外不再有其他因数的自然数。

        int count = 0;

        outer:for (int i=101;i<150l;i++){//设置一个标签outer
            for (int j = 2;j<i/2;j++){
                if (i % j == 0){
                    continue outer;//当满足这一个条件之后,从小的循环直接跳到外面的大循环。
                }//所以outer标签就是一个定位的作用。
            }
            System.out.print(i+" ");
        }
    }
}

9、Java方法

前面我们使用的那些点出来的都是方法,例如System.out.print();就是系统类里面的标准输出对象out的print方法。

  • 方法是语句的集合,他们呢在一起执行一个功能。
    • 方法是解决一类问题的步骤的有序组合。
    • 方法包含于类或者对象中。
    • 方法在程序中被创建,在其他地方被调用。
package com.bsy.method;

public class Demo {
    public static void main(String[] args) {
        int sum = add(1,2);
        System.out.println(sum);
    }

    //加法
    public static int add(int a,int b){
        return a+b;
    }
}
  • 设计方法的原则:一个方法就完成一个功能,有利于后期的扩展。

  • Java的方法类似于其他语言的函数,是一段用来完成特定功能的代码片段。

  • 方法包含的部分:

    • 修饰符:可选,告诉编译器如何调用方法。
    • 返回值类型:方法可能会返回值,returnValueType是返回值的数据类型,没有返回值的关键字void。
    • 方法名:方法的实际名称。遵循驼峰命名法,先小后大。
    • 参数类型:传递值给参数,可选。
      • 形式参数:方法被调用时用于接收外界的输入数据。
      • 实参:调用方法时实际传给方法的数据。
    • 方法体:方法具体的语句,功能等。
修饰符 返回值类型 方法名(参数类型 参数名){
    ……
    方法体
    ……
    return 返回值;
}

9.1、return 0;

在执行到return时则终止方法。意思就是在有返回值的方法中,已经获得返回值了,下面的任何东西已经没有意义了,所以在return下面的代码则不会被执行。

//比大小
    public static int max(int num1,int num2){
        int result = 0;
        if (num1==num2){
            System.out.println("num1==num2)");
            return 0;
        }

        if (num1>num2){
            result = num1;
        }else {
            result = num2;
        }
        return result;
    }

9.2、方法调用

对象名.方法名(实参列表);

    public static void main(String[] args) {
        int max = max(10,20);
        System.out.println(max);
    }

9.3、方法的重载

在一个类中,可以有多个同名的方法,但形参不同。

  • 方法的重载的规则:

    • 方法名称必须相同。
    • 参数列表必须不同(个数不同、或类型不同、参数排列顺序不同等)。
    • 方法的返回值类型可以相同也可以不同。
    • 仅仅返回类型不同不足以成为方法的重载。
  • 实现理论:

    • 方法名称相同时,编译器会根据调用方法大参数个数、参数类型等去逐个匹配,以选择对应的方法发,如果匹配失败,则编译器报错。
package com.bsy.method;

public class Demo3 {
    public static void main(String[] args) {
        double max = max(10.4,20.5);
        System.out.println(max);
    }
    //比大小
    public static double max(double num1,double num2){
        int result = 0;
        if (num1==num2){
            System.out.println("num1==num2)");
            return 0;
        }

        if (num1>num2){
            result = (int)num1;
        }else {
            result = (int) num2;
        }
        return result;
    }
    //比大小
    public static int max(int num1,int num2){
        int result = 0;
        if (num1==num2){
            System.out.println("num1==num2)");
            return 0;
        }

        if (num1>num2){
            result = num1;
        }else {
            result = num2;
        }
        return result;
    }
}

9.4、命令行传参

有时候你希望运行一个程序时再传递给它消息。这要靠传递命令参数给main()函数实现。

注意:javac后运行class文件目录在src开始,不然提示找不到。

例如:java com.bsy.method.Demo4 This is bsy

9.5、可变参数

不确定给你多少个参数,有事我们也不确定传进来多少个参数,如果为每一种可能都写一个方法进行重载,那么会相当浪费时间。可变参数就是可以接收不确定数量的参数然后进行运算。这里使用数组举例。

  • JDK1.5开始,Java支持传递同类型的可变参数给一个方法。
  • 在方法声明中,在指定参数类型后加一个省略号(…)
  • 一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。任何普通的参数必须在它之前声明。
package com.bsy.method;

public class Demo5 {
    public static void main(String[] args) {
        //调用可变参数的方法
        printMax(34,5,22,3,5,8.7);//传递参数
        printMax(new double[]{1,2,3});//传递数组也可以
    }

    public static void printMax(double... numbers){
        if (numbers.length == 0){
            System.out.println("No argument passed");
            return;
        }

        double result = numbers[0];

        //排序
        for (int i = 0; i < numbers.length; i++) {
            if (numbers[i] > result){
                result = numbers[i];
            }
        }
        System.out.println("The max value is "+result);
    }
}

9.6、递归

A方法可以调用B方法,而递归则是可以自己调用自己。

利用递归可以用简单的程序解决一些复杂的问题,大大地减少了程序的代码量。

  • 递归结构包含两个部分:
    • 递归头:什么时候不调用自身方法。如果没有结束自我调用的判定条件,也就是没有这个头,那么将陷入死循环。
    • 递归体:什么时候需要调用自身方法。
package com.bsy.method;

public class Demo6 {
    /**
     * 阶乘概念:
     * 1!   1*1
     * 2!   2*1
     * 3!   3*2*1
     * 5!   5*4*3*2*1
     */
    public static void main(String[] args) {
        System.out.println(f(5));
    }

    public static int f(int n){
        if (n==1){
            return 1;
        }else {
            return n*f(n-1);
        }
    }
}

在数值比较小的时候可以使用。Java是栈机制,如果数值过大会占用很多内存。

9.7、数组

  • 相同类型数据的有序集合
  • 通过下标访问。从0开始。
package com.bsy.array;

public class Demo1 {
    public static void main(String[] args) {
        //变量类型  变量的名字   =   变量的值;
        //数据类型
        int[] nums;//1,声明了一个数组,但是没有分配空间
        int nunms2[];//跟上面的类型一样,这种是为了让C跟C++程序员更快适应Java

        nums = new int[10];//2,创建。定义了数组的长度
        int[] nums3 = new int[10];//声明和创建写一块也可以。
        //3,给数组中的元素赋值
        nums[0] = 1;
        nums[1] = 2;
        nums[2] = 3;
        nums[3] = 4;
        nums[4] = 5;
        nums[5] = 6;
        nums[7] = 8;
        nums[8] = 9;
        nums[9] = 10;

        System.out.println(nums[6]);//如果不赋值则默认值为0

        //计算所有元素的和
        int sum = 0;
        //获取数组的长度:arrays.length
        for (int i = 0; i < nums.length; i++) {
            sum = sum + nums[i];
        }
        System.out.println("总和为:"+sum);
    }
}
  • 数组的4个基本特点:
    • 长度是确定的。数组一旦被创建,他的大小是不可以改变的。
    • 其元素是相同类型,不允许出现混合类型。
    • 数组中的元素是可以是任何数据类型,包括基本类型和引用类型。
    • 数组变量是引用类型,数组本身就是对象,,Java中的对象是在堆中,数组对象本身是在堆中的。
9.7.1、内存分析 & 三种初始化
  • Java内存

    • 堆:
      • 存放new的对象和数组
      • 可以被所有线程共享,不会存放别的对象引用
    • 栈:
      • 存放基本变量类型(会包含这个基本类型的具体数值)
      • 引用对象的变量(会存放这个引用在堆里面的具体地址)
    • 方法区:
      • 可以被所有线程共享
      • 包含了所有的class和static变量

    三种初始化:

    • 静态初始化

      • //创建 + 赋值
        int[] a = {1,2,3}//花括号都是代表数组,一旦写好长度是固定的。
        Man[] mans = {new Man(1,1),new Man(2,2)};//引用类型,引用了Man类
        
    • 动态初始化

      • int[] a = new int[2]//声明数组类型,创建空间。包含默认初始化。
        a[0] = 1;
        a[1] = 2;
        
    • 数组的默认初始化

      • 数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐藏式初始化。
9.7.2、数组边界

下标合法区间:[0,length-1],如果越界就会报错

public static void main(String[] args){
    int[] a = new int[2];
    System.out.print(a[2]);
}
public static void main(String[] args){
    int[] a = {1,2,3,4,5}
    for (int i = 0;i <= a.length;i++){//这里注意不能用<=数组的长度是5但是下标最高为length-1也就是4
        System.out.print(a[i]);
    }
}

便会报错:ArraylndexOutOfBoundsException:数组下标越界异常

  • 数组是相同数据类型(数组类型可以为任意类型)的有序集合。
  • 数组也是对象。数组的元素相当于对象的成员变量。
  • 数组长度的确定的,是不可变的。
9.7.3、数组使用
  • 普通的for循环:
package com.bsy.array;

public class ArrayDemo01 {
    public static void main(String[] args) {
        int[] arrays = {1,2,3,4,5};

        //打印全部数组元素
        for (int i = 0; i < arrays.length; i++) {
            System.out.println(arrays[i]);
        }
        //计算所有元素的和
        int sum = 0;
        for (int i = 0; i < arrays.length; i++) {
            sum+=arrays[i];
        }
        System.out.println("sum="+sum);
        //查找最大元素
        int max = arrays[0];
        for (int i = 0; i < arrays.length; i++) {
            if (arrays[i] > max){
                max = arrays[i];
            }
        }
        System.out.println("max="+max);
    }
}

增强for循环(For-Each循环)、数组作为方法参数、数组作返回值:

package com.bsy.array;

public class ArrayDemo02 {
    public static void main(String[] args) {
        int[] arrays = {1,2,3,4,5};

        //快捷键 array.for
        for (int array : arrays) {//方便遍历,没有下标
            System.out.println(array);
        }

        int[] reverse = reverse(arrays);
        pringArray(reverse);
    }
        //打印数组元素
    public static void pringArray(int[] arrays){
        for (int i = 0; i < arrays.length; i++) {
            System.out.print(arrays[i]+" ");
        }
    }

    //反转数组
    public static int[] reverse(int[] arrays){
        int[] result = new int[arrays.length];

        //反转的操作
        for (int i = 0, j=result.length-1; i< arrays.length; i++,j--) {
            result[j] = arrays[i];
        }

        return result;
    }
}
9.7.4、多维数组

数组的数组。

package com.bsy.array;

public class Demo05 {
    public static void main(String[] args) {
        int[][] array = {{1,2},{2,3},{3,4},{4,5}};
        /**
         * int[长][宽]
         * 拆开就是:
         *  1,2     array[0]表示下标为0的数组
         *  2,3     array[1]表示下标为1的数组
         *  3,4     array[2]
         *  4,5     array[3]
         */
        System.out.println(array[0]);//直接打印不出来的

        ArrayDemo02.pringArray(array[0]);//使用前面写的打印数组元素方法

        System.out.println(array[0][0]);//打印第0个数组的第0个元素
        System.out.println(array[0][1]);//打印第0个数组的第2个元素

        //三维数组即array[][][]三个点来确定一个数
        //更多维度跟现实生活不一样,而Java只是一种量化

        //遍历出二维数组的全部元素
        for (int i = 0; i < array.length; i++) {//array里面有4个数组,长度为4
            for (int j = 0; j < array[i].length; j++){//array里面每一个数组的元素
                System.out.println(array[i][j]);
            }
        }
    }
}
9.7.5、Arrays类
  • 数组工具类java.util.Arrays
  • 里面很多方法可以快速使用按Alt+鼠标左键点进去,在IDEA界面左侧下方Structure查看所有方法。

自己多试试,或者看帮助文档。

9.7.6、冒泡排序
package com.bsy.array;

import java.util.Arrays;

public class Demo6 {
    public static void main(String[] args) {
        /**
         * 冒泡排序
         * 1、比较数组中,两个相邻的元素,如果第一个数比第二个大,我们就交换他们的位置。
         * 2、每一次比较,都会产生一个最大、最小数。
         * 3、下一轮就可以少一次排序。
         * 4、依次循环,直到结束.
         */
        int[] a = {2,6,22,92,76,9,36,12,75,30,68,19,25};
        System.out.println(Arrays.toString(sort(a)));
    }

    public static int[] sort(int[] array){
        //临时变量(第三个空杯子)
        int temp = 0;
        //外层循环,判断要走多少次。
        for (int i = 0; i < array.length-1; i++) {
            //内层循环,比较两个数,如果第一个数比第二个数大,则交换位置。
            for (int j = 0; j < array.length-1-i; j++) {
                if (array[j+1] > array[j]){
                    temp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = temp;
                }
            }
        }
        return array;
    }
}
9.7.7、稀疏数组

原始数组:

0002200
0110000
000-600
000090
000000
9100000
0028000

转化为稀疏数组:

行(row)列(col)值(value)
0766
10322
21111
323-6
4349
55091
66228

表中0行 表示这组数据为 7行6列共有6个有效数据。

第1个数据在 第0行的 第3列 值为22。

package com.bsy.array;

public class ArrayDemo08 {
    public static void main(String[] args) {
        //1、创建一个二维数组 11*11      0:没有棋子,1:黑棋,2:白棋
        int[][] array1 = new int[11][11];
        array1[1][2] = 1;
        array1[2][3] = 2;
        //输出原始数组
        System.out.println("输出原始数组");
        for (int[] ints : array1) {//遍历array1二维数组
            for (int anInt : ints) {//遍历数组中每个数组的元素
                System.out.print(anInt+"\t");
            }
            System.out.println();
        }
        //获取有效值的个数
        //转换为稀疏数组保存
        int sum = 0;
        for (int i = 0; i < array1.length; i++) {
            for (int j = 0;j < array1.length;j++){
                if (array1[i][j] != 0){
                    sum++;
                }
            }
        }
        System.out.println("有效值个数为:"+sum);

        //2、创建一个稀疏数组的数组
        int[][] array2 = new int[sum+1][3];//行、列、值。有效个数+1是稀疏数组的表头。所以这里是三行三列。
        //这张稀疏数组的表头,也就是声明了这张稀疏数组的表是11行,11列,一共有sum有效数据。
        array2[0][0] = 11;//行
        array2[0][1] = 11;//列
        array2[0][2] = sum;//值
        //遍历二维数组,将非零的值,存放稀疏数组中
        int count = 0;
        for (int i = 0; i < array1.length; i++) {//遍历原始二维数组表
            for (int j = 0;j < array1[i].length;j++){//遍历二维数组中每一个元素
                if (array1[i][j] != 0){//如果里面的元素不为零
                    count++;//那么计数+1,第一个数也就出来了
                    array2[count][0] = i;//存放横坐标
                    array2[count][1] = j;//存放纵坐标
                    array2[count][2] = array1[i][j];//存放这个坐标的数值
                }
            }
        }
        //输出稀疏数组
        System.out.println("稀疏数组");
        for (int i = 0; i < array2.length; i++) {
            System.out.println(array2[i][0]+"\t"
                            +array2[i][1]+"\t"
                            +array2[i][2]+"\t");
        }

        //还原稀疏数组
        //1、读取稀疏数组
        int[][] array3 = new int[array2[0][0]][array2[0][1]];
        //2、给其中的元素还原它的值
        for (int i = 1; i < array2.length; i++) {
            array3[array2[i][0]][array2[i][1]] = array2[i][2];
        }
        //3、打印还原
        System.out.println("输出还原的数组");
        for (int[] ints : array3) {
            for (int anInt : ints) {
                System.out.print(anInt+"\t");
            }
            System.out.println();
        }
    }
}

10、面向对象编程

  • 面向过程思想:

    • 步骤清晰简单,第一步做什么,第二部做什么……
    • 适合较为简单的问题
  • 面向对象思想

    • 分类思想模式,解决问题需要哪些分类,对分类进行单独思考。
    • 适合复杂的问题,多人协作。
  • 对于描述复杂的事物,为了从宏观上把握、从整体上合理分析,我们需要使用面向对象的思路来分析整个系统。从具体到微观操作,仍然需要面面向过程的思路去处理。

  • 什么是面向对象

    • 面向对象编程OOP(Object-Oriented Programming)
    • 面向对象的本质就是:以类的方式组织代码,以对象的组织(封装)数据。
    • 抽象
    • 三大特性:
      • 封装
      • 继承
      • 多态
    • 从知识论的角度考虑是先有对象,后有类。对象:具体的事物。类:抽象概念。
    • 从代码运行的角度考虑是先有类,后有对象。类就是对象的模板。

10.1、方法的定义

package com.bsy.oop;
//Demo01类
public class Demo01 {
    //main方法
    public static void main(String[] args) {

    }
    /*
        修饰符     返回值类型   方法名(……){
            //方法体
            return 返回值;
        }
     */
    public String sayHello(){//方法名要见名知意,驼峰命名,先小后大
        return "Hello,world";//return 结束方法,返回一个结果,返回可以为空。
    }

    public int max(int a,int b){
        return a>b ? a : b;//【三元运算符】如果a大于b,那么就返回a,否则就返回b
    }
}

10.2、方法的调用

10.2.1、静态方法 & 非静态方法

我们先创建一个学生类,里面有静态方法和非静态方法

package com.bsy.oop;
//学生类
public class Student {

    //静态方法
    public static void say(){
        System.out.println("学生说话了");
    }
    //非静态方法
    public void eat(){
        System.out.println("学生吃东西了");
    }

    //static表示跟类一起加载的,类存在了他就跟着存在
    public static void aVoid(){
        //在这里不能直接调用bVoid,因为它现在还不存在。
        //如果aVoid和bVoid都为非静态类 或者都为静态类,那么是可以互相调用的。
    }
    //非静态类,一开始不存在的,待类被实例化之后才存在
    public void bVoid(){

    }
}

然后我们要分别去调用两种方法

package com.bsy.oop;

public class Demo02 {

    public static void main(String[] args) {
    //静态方法 static 的调用
    Student.say();

    //非静态方法的调用(将对象实例化出来)
        Student student = new Student();
        //对象类型 对象名 = 对象值;
        student.eat();//直接使用对象名调用即可。
    }

}

10.2.2、形参和实参

就是形式参数和实际参数

package com.bsy.oop;

public class Demo03 {
    public static void main(String[] args) {
        Demo03 demo03 = new Demo03();
        //实参和形参的类型要一一对应
        System.out.println(demo03.add(1,2));//提供的实际参数的类型要符合形参对类型的定义。我们这里是int,所以就不能能写个sort、char之类的。
    }

    public int add(int a,int b){//形式参数a和b,名字无所谓,只是表示这个参数
        return a+b;
    }
}
10.2.3、值传递
package com.bsy.oop;
//值传递
public class Demo04 {
    public static void main(String[] args) {
        int a = 1;
        System.out.println(a);
        Demo04.change(a);//1    因为a传递进change方法后并没有返回值,又返回主程序了
    }
    //返回值为空
    public static void change(int a){
        a = 10;//值传递到这里为10,但没有返回值,相当于经过这个方法但是不产生变化。
    }
}
10.2.4、引用传递
package com.bsy.oop;
//引用传递:对象,本质还是值传递
public class Demo05 {
    public static void main(String[] args) {
        Person person = new Person();
        System.out.println(person.name);//null

        Demo05.change(person);
        System.out.println(person.name);//白三叶
    }
    public static void change(Person person){
        person.name = "白三叶";
    }
}
//定义了一个Person类,有一个属性name;
class Person{
    String name;
}

10.3、类与对象的关系

  • 类是一种抽象的数据类型,是对某一类事物整体的描述、定义,只能代表整体,并不能代表某一个具体的事物,对象才是代表一个具体的事物。
    • 例如Person类、Pet类、Car类等。
  • 对象是抽象概念的举例实例
    • 例如,张三,是人类里面一个具体的实例。张三家里的狗是狗类里的一个具体的实例。
    • 能够展现出特点,展现出功能的是具体的实例,而不是一个抽象的概念。
10.3.1、创建与初始化对象
  • 使用new关键字创建对象
  • 使用new关键字创建对象的时候,除了分配内存空间之外,还会给创建好的对象进行默认初始化,以及对类中构造器的调用。
package com.bsy.oop.Demo01;
//学生类
public class Student {
    //属性:字段
    String name;//默认初始化:null
    int age;//0

    //方法
    public void  study(){
        System.out.println(this.name+"在学习");//this代表当前对象,用的是当前对象的东西(下面有总结)
    }
}
package com.bsy.oop.Demo01;

import com.bsy.oop.Demo01.Student;

//一个项目应该只存在一个main方法
public class Application {
    public static void main(String[] args) {
        //使用new关键字创建对象
        //类:抽象的,需要实例化。
        //类实例化后会返回一个自己的对象
        //student对象就是一个Student类具体的实例!
        Student xiaoming = new Student();//同一个类可以产生不同的对象
        Student xh = new Student();
        /*
            使用new关键字创建的时候,除了分配内存空间之外,还会给创建好的对象 进行默认的初始化
            以及对类中构造器的调用。
         */
        xiaoming.name = "小明";
        xiaoming.age = 3;

        System.out.println(xiaoming.name);
        System.out.println(xiaoming.age);

        xh.name = "小红";
        xh.age = 12;

        System.out.println(xh.name);
        System.out.println(xh.age);



    }
}

面向对象编程的本质就是:以类的方式组织代码,以对象的组织(封装)数据。

10.4、构造器

  • 构造器

    • 和类名相同
    • 没有返回值
  • 作用

    • new本质就是在调用构造方法
    • 初始化对象的值
  • 注意点

    • 定义了有参构造之后,如果想使用无参构造,就必须显示定义一个无参构造器
  • 生成构造器快捷键

    • Alt + Insert
    • 选择你需要添加的构造器之后,点击“ok”生成有参构造器,点击“Select None”生成无参构造器。
  • this.

    • 根据”同名情况下,局部变量的优先级更高”原则,在构造方法执行的过程中,虚拟机会把参数值赋给”参数本身”,而不是赋值给对象的属性。

    • 把一个值赋值给对象的一个属性,而不是”再一次”把它赋值给构造方法的参数,就需this.

    • 本对象自己的属性

    • String name;
      public Person(String name){
          this.name = name;
      }
      //如果不写this.那么赋值的时候就会name属性重新赋值给name本身
      

Demo:

package com.bsy.oop.Demo01;

public class Person {
    //一个类即使什么都不写,他会存在一个方法(默认生成的,在java文件中不显示,但是在编译后的class文件中显示)
    //显示的定义构造器
    String name;
    //实例化初始值
    public  Person(){//无参构造器

    }
    /*
        1、使用new关键字,本质是在调用构造器
        2、用来初始化值
     */
    //有参构造:一旦定义了有参构造,再调用无参构造,无参构造器就必须显示(代码必须打出来)
    public Person(String name){
        this.name = name;//this.本对象自己的属性,而不是上面的。
    }

    //快捷键:alt + insert,选择constructor生成构造器;点击ok生成有参构造器,点击“select none”生成无参构造器

}
package com.bsy.oop.Demo01;

//一个项目应该只存在一个main方法
public class Application {
    public static void main(String[] args) {
        Person person = new Person("bsy");//如果有值,那么会调用有参构造器(方法的重载)

        System.out.println(person.name);

    }
}

10.5、创建对象内存分析

栈:存放方法、变量的引用

堆:存放具体的对象。堆里面有一个特殊的区域:方法区,方法区里面有一个静态方法区。

在这里插入图片描述

10.6、封装

程序设计追求“高内聚,低耦合”。

  • 高内聚:类的内部数据操作细节自己完成,不允许外部干涉。

  • 低耦合:仅暴露少量的方法给外部使用。

封装(数据的隐藏):

  • 通常应该禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问。

属性私有,get/set


封装的作用:

1,提高程序的安全性,保护数据

2,隐藏代码实现细节

3,统一接口

4,增加系统可维护性

package com.bsy.demo04;

public class Student {
    //private:属性私有
    private String name;
    private int id;
    private char sex;
    private int age;

    //提供一些可以操作这些属性的方法
    //提供一些public的get、set方法。(快捷键Alt + Insert)

    //get   获取这个数据
    public String getName() {
        return name;
    }
    //set   给这个数据设置值
    public void setName(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public char getSex() {
        return sex;
    }

    public void setSex(char sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }
    //对数据的合法性与安全性可以在set中作出限制,例如年龄的限制。
    public void setAge(int age) {
        if (age>120 || age<0){
            this.age = 0;
        } else {
            this.age = age;
        }
    }
}
package com.bsy.demo04;

public class Application {
    public static void main(String[] args) {
        Student student = new Student();//new出对象

        student.setName("白三叶");//set放入数据
        System.out.println(student.getName());//获取数据

        student.setAge(-1);//不合法的年龄,我们设置为0
        System.out.println(student.getAge());
    }
}

10.7、继承

extends的意思是“扩展”。子类继承父类使用关键字extends来表示。

继承是类跟类之间的关系,除此之外还有依赖,组合,聚合。

//Person 人(作为父类,也叫基类)
public class Person{}
//Student 学生类(作为子类,继承父类,也叫做派生类)
public class Student extends Person{}
//除了继承可以使用父类的方法之外,还可以使用聚合
public class Teacher{
    Person person();
}

快捷键:ctrl + H查看继承关系(继承树状图)Java中所有的类,都默认直接或者间接继承object类。

Java中类只有单继承,没有多继承,但是可以间接继承别的类。(接口可以多继承)

私有的private无法被继承。

package com.bsy.oop.demo05;
//在Java中所有的类,都默认直接或者间接继承object类。相当于extends Object,只是不显示。
public class Person {
    public void say(){
        System.out.println("说了一句话");
    }

    private int money = 10_0000_0000;//私有的是无法继承的。

    //public    公共的,优先级排序
    //protected 受保护的
    //default   默认,不写修饰符则为默认
    //private   私有的,一般属性才是私有的

    //私有的属性(钱)不让你直接使用,但是给了你方法可以使用。那就是get、set
    public int getMoney() {
        return money;
    }

    public void setMoney(int money) {
        this.money = money;
    }
}
package com.bsy.oop.demo05;
//子类继承了父类,就会拥有父类的全部方法。
public class Student extends Person{}
package com.bsy.oop.demo05;

public class Ace extends Student{}
package com.bsy.oop.demo05;

public class Application {
    public static void main(String[] args) {
        Student student = new Student();
        student.say();//调用student继承父类Person的方法。

        Ace ace = new Ace();
        ace.say();//间接继承了Person类。
    }
}
10.7.1、super

super注意点:

  • super调用父类的构造方法,必须在构造方法的第一个。
  • super必须只能出现在子类的方法或者构造方法中!
  • super和this不能同时调用构造方法!

super和this:

  • this调用本类的对象
  • super代表父类对象
  • this没有继承也可以使用
  • super只能在继承条件下才可以使用

构造方法:

  • this();本类的构造
  • super();父类的构造
package com.bsy.oop.demo05;
//在Java中所有的类,都默认直接或者间接继承object类。相当于extends Object,只是不显示。
public class Person {
    protected String name = "whitClover";
    public void print(){
        System.out.println("Person");
    }

    public Person() {
        System.out.println("Person无参构造器执行了");
    }
    //如果父类使用了有参构造器,没有写出无参构造器,那么子类在调用的无参构造器的时候会出错。
    //一般父类写出有参构造器,同时还要写出无参构造器,为了避免出现这个问题。
}
package com.bsy.oop.demo05;
//子类继承了父类,就会拥有父类的全部方法。
public class Student extends Person{
    private String name = "bsy";
    public void print(){
        System.out.println("Student");
    }

    public void test1(String name){
        System.out.println(name);//本方法传进来的name    白三叶
        System.out.println(this.name);//本类的name     bsy
        System.out.println(super.name);//父类的name    whiteClover
    }

    public void test(){
        print();//Student
        this.print();//Student
        super.print();//Person
    }

    public Student() {
        //无参构造器这里有一行隐藏代码 super();调用了父类的无参构造器。默认调用无参。
        super();//调用父类的构造器,必须在子类构造器的第一行。
        System.out.println("Student无参构造器执行了");
    }
}
package com.bsy.oop.demo05;

public class Application {
    public static void main(String[] args) {
        Student student = new Student();
        student.test1("白三叶");
        student.test();
    }
}

10.8、方法重写

前提:需要有继承关系,子类重写父类方法

  • 方法名必须相同
  • 参数列表必须相同
  • 修饰符:范围可以扩大,但不能缩小(public > protected > default > private)
  • 抛出的异常:范围,可以被缩小,但不能扩大(ClassNotFoundException --> Exception(大))

子类的方法名和父类必须要一直,方法体不同。

作用:

  • 父类的功能子类不一定需要,或者不一定满足。
  • 快捷键:Alt + Insert 选择override
package com.bsy.oop.demo05;
//重写都是方法的重写,和属性无关
public class B {
    public void test(){
        System.out.println("B=>test()");
    }
}
package com.bsy.oop.demo05;

public class A extends B{
    //Override 重写
    @Override//注解:有功能的注释
    public void test() {
        System.out.println("A=>test()");
    }
}
package com.bsy.oop.demo05;

public class Application {
    public static void main(String[] args) {
        //方法的调用只和左边的类型有关,定义的数据类型有关
        A a = new A();
        a.test();//A

        //父类的引用指向了子类
        B b = new A();
        b.test();//A
    }
}

10.9、多态

即同一方法可以根据发送对象的不同,而采用多种不同的行为方式。

一个对象的实际类型是确定的,但可以指向对象的引用类型有很多。

注意事项:

  • 多态是方法的多态,属性没有多态
  • 要有继承关系才能转换,不然会出现类型转换异常 ClassCastExecption

存在条件:

  • 要有继承关系
  • 子类重写父类方法
  • 父类引用子类对象 Fater f1 = new Son();

不能实现重写的方法关键字:

  • static 属于类,不属于实例
  • final 常量
  • private 方法

在下方的例子中,运行的run()方法可能是父类的,也可能是子类重写父类的,让程序更加灵活:

package com.bsy.oop.demo06;

public class Person {
    public void run(){
        System.out.println("person");
    }
}
package com.bsy.oop.demo06;

public class Student extends Person{
    @Override
    public void run() {
        System.out.println("student");
    }
    public void eat(){
        System.out.println("eat");
    }
}
package com.bsy.oop.demo06;

public class Application {
    public static void main(String[] args) {

        Student student = new Student();//student能调用自己和父类的方法
        Person person = new Student();//person父类,可以指向子类,但是不能调用子类独有的方法
        Object obj = new Student();

        //对象能执行哪些方法,主要看对象左边的类型,和右边关系不大
        ((Student) person).eat();//类似于之前数据类型的强制转换,高转低。
        student.eat();
    }
}
10.9.1、instanceof & 类型转换

instanceof:判断一个对象时什么类型,判断两个类之间是否存在父子关系。

举例:(其中Student跟Teacher都继承Person类)

package com.bsy.oop.demo07;

public class Application {
    public static void main(String[] args) {

        //Object > String
        //Object > Person > Teacher
        //Object > Person > Student
        Object obj = new Student();
        System.out.println(obj instanceof Student);//true//Object是基类不要忘了
        System.out.println(obj instanceof Person);//true
        System.out.println(obj instanceof Object);//true
        System.out.println(obj instanceof Teacher);//false//中间隔了一层,不再有关系
        System.out.println(obj instanceof String);//false

        System.out.println("=====================");

        Person person = new Student();
        System.out.println(person instanceof Student);//true
        System.out.println(person instanceof Person);//true
        System.out.println(person instanceof Object);//true
        System.out.println(person instanceof Teacher);//false
        //System.out.println(person instanceof String);编译报错

        System.out.println("=====================");

        Student student = new Student();
        System.out.println(student instanceof Student);//true
        System.out.println(student instanceof Person);//true
        System.out.println(student instanceof Object);//true
        //System.out.println(student instanceof Teacher);//跟teacher同级了
        //System.out.println(person instanceof String);//八竿子打不着
    }
}

类型转换:

package com.bsy.oop.demo07;

public class Application {
    public static void main(String[] args) {
         /*
            类型之间的转换:
                类型之间的转换,高转低需要强转,低转高则不需要。
                而类的转换可以理解为强转
         */
        //高                      低
        Person person = new Student();
        //person.go();person里面没有go方法,是student里面才有
        //将person转换为student类型,我们就可以使用student类型的方法了
        //Student student = (Student)person;
        //student.go();//这样就可以了
        //可以将上面两句话写成一句话,类似于强转(光标在person后方按alt+enter)
        ((Student) person).go();

        //子类转换为父类,可能会丢失一些自己的方法
        Student student = new Student();
        Person person1 = student;
        person1.run();//此时的person已经走不了go方法了。
        ((Student) person1).go();
    }
}

总结:

  • 父类引用指向子类对象
  • 把子类转换为父类,向上转型;
  • 把父类转换为子类,向下转型;(强制转换。数据类型强转会丢失精度,类强转会丢失方法)
  • 方便方法的调用,减少重复代码,提高代码复用率,更加简洁。

10.10、static

static静态的,可以不通过对象来访问,而是通过类直接访问。就像其他非静态常量变量方法等需要通过new一个对象来访问,而通过static修饰的则不需要。

注意:

  • static关键词修饰的成员变量和方法都属于类,不属于某个对象;

  • 普通变量和方法属于某个对象,每个对象都有自己的变量和方法,彼此之间是隔离的;

  • 静态方法不能调用非静态的变量和非静态的方法,否则编译时就会报错。

静态变量与实例变量的区别:

  • JVM虚拟机只会为静态变量分配一次内存,在加载类的过程中完成对静态变量的内存分配;
  • 而实例变量,每创建一个Java实例对象,JVM虚拟机就会为该实例变量分配一次内存;

(售票demo:票数是一定数量的,如果使用非静态,每个对象(售票员)被new出来的时候在内存里也生成了一份,这时候每个售票员都可以卖出票,但不符合现实中票数是一定数量的条件,要解决这个问题,就是将总票数的量设置为静态,因为静态的变量常量等跟类一起加载而且只加载一次,就不会出现每new一个对象JVM就分配新的内存,产生不符合现实的票。)

静态属性:

package com.bsy.oop.demo07;

public class Demo09 {
    private static int age;//静态的变量
    private double score;//非静态的变量

    public static void main(String[] args) {
        Demo09 demo09 = new Demo09();

        System.out.println(Demo09.age);//对于静态的推荐通过类名去访问
        System.out.println(demo09.score);//对于非静态的只能使用对象去访问
        System.out.println(demo09.age);//静态变量也可以使用对象去访问,但是不推荐
    }
}

静态方法:

package com.bsy.oop.demo07;

public class Demo09 {
    private static int age;//静态的变量
    private double score;//非静态的变量

    public void run(){
        go();//非静态方法可以调用静态方法
    }
    public static void go(){
        //静态方法可以调用静态方法(为什么?结合类加载顺序理解)
    }

    public static void main(String[] args) {

    new Demo09().run();//非静态方法只能通过new对象来调用
    Demo09.go();//静态方法可以直接用类名调用
    go();//在本类中甚至可以不用类名直接调用
    }
}
/*
    static方法跟类一起加载,所以当调用非静态方法的时候这个方法才被加载,
    但这个非静态方法所要调用的静态方法早就跟类一起生成了,所以可以调用。
    
    如果静态方法调用非静态方法,静态方法跟类一起加载的时候,非静态方法还没有生成,
    那就会调用一个不存在的方法,就会报错。
 */

代码块:(类加载顺序)

package com.bsy.oop;

import com.bsy.oop.demo07.Person;

public class demo08 {
    {//2,其次执行,赋初始值
        System.out.println("代码块(匿名代码块,在构造器之前)");
    }
    static {//1,首先执行,只执行一次
        System.out.println("静态代码块(可以用于加载初始的数据,跟类一起加载,只加载一次)");
    }
    public demo08(){//3,最后执行
        System.out.println("构造方法");
    }

    public static void main(String[] args) {
        demo08 demo08 = new demo08();
    }
}

静态导入包:

final:

package com.bsy.oop.demo07;

//静态导入包
import static java.lang.Math.random;
import static java.lang.Math.PI;
public final class Test {//使用了final关键字修饰,就不能有子类继承了,相当于断子绝孙了
    public static void main(String[] args) {
        System.out.println(random());
        System.out.println(PI);
    }
}

10.11、抽象类

abstract修饰符所修饰的类和方法被称为 抽象类 和 抽象方法。

为了在复杂庞大的项目中更好的细分,做一些特殊功能等。

demo:

package com.bsy.oop.Demo08;
//abstract 抽象类
public abstract class Action {
    //约束,有人帮我们实现
    //abstract抽象方法,只有方法名字,没有具体的实现
    public abstract void doSomething();

}
package com.bsy.oop.Demo08;
//抽象类的所有方法需要继承了他的子类去实现。
//也就是说继承了抽象类的子类,必须实现父类这个抽象类的方法。除非:
//除非这个子类也是抽象类,那就可以让这个子类的子类去实现。(无限套娃)
public class A extends Action{
    @Override
    public void doSomething() {

    }
}

注意点:

  • 不能new抽象类,只能靠子类去实现它
  • 抽象类中可以写普通方法
  • 抽象方法必须在抽象类中

(抽象类也是有构造器的)

10.12、接口 interface

  • 普通类:只有具体实现
  • 抽象类:具体实现和规范(抽象方法)都有
  • 接口:只有规范。(只能干约束,约束和实现分类。面向接口编程)

在大型系统开发中,一般先设计好接口、开发规范,然后找码农去填补。

  • 接口是规范,定义了一组规则,定义了什么就要做什么,制定好大家都要遵守。
  • 面向对象编程的精髓。

demo:

package com.bsy.oop.Demo9;
//interface 定义关键字。接口都需要有实现类。
public interface UserServices {
    //常量 public static final 一般不这样写
    int score = 10;

    //接口中所有定义的方法都是抽象的。默认加上了public abstract,所以我们直接写方法就行了。
    void add();
    void delete();
    void update();
    void query();
}
package com.bsy.oop.Demo9;

public interface TimeService {
    void timer();
}
package com.bsy.oop.Demo9;
//类可以实现接口。implements接口。
//实现接口的类,就需要重写接口的方法。
public class UserServicesImpl implements UserServices,TimeService{//利用接口实现多继承
    @Override
    public void add() {

    }

    @Override
    public void delete() {

    }

    @Override
    public void update() {

    }

    @Override
    public void query() {

    }

    @Override
    public void timer() {

    }
}

作用:

  • 约束
  • 定义一些方法,让不同的人实现。
  • 方法都是public abstract
  • 常量都是public static final
  • 接口不能被实例化,接口没有构造方法
  • implement可以实现多个接口
  • 必须要重写接口中的方法

11、异常机制

  • 异常:Exception

    • 包括运行时异常和非运行时异常。应尽量避免异常的发生。
  • 错误:Error

    • 一般是灾难性的问题。
    • 错误不可查,在应用程序控制和处理能力之外
    • 尽量为程序创造良好的运行环境避免错误的发生

异常体系结构:

所有的异常都可以在一个异常里面表示

  • Java吧异常当作对象来处理,并定义了一个基类java.lang.Throwable作为异常的超类。
  • 在Java API中已经定义了许多异常,这些异常类分为两大类:错误Error和Exception

在这里插入图片描述

11.1、捕获和抛出异常

package com.bsy.oop.exception;

public class Test {
    public static void main(String[] args) {
        int a = 1;
        int b = 0;

        try {//try监控区域
            System.out.println(a / b);
        } catch (ArithmeticException exception) {//catch 捕获异常类型
            System.out.println("程序出现异常,变量b不能为0");
            System.exit(0);//手动结束程序
            exception.printStackTrace();//打印错误信息
        } catch (Exception e){//可以捕获多个异常
            System.out.println("Exception");
        }finally {//finally可以不用,一般用于资源关闭等善后工作
            System.out.println("finally");
        }
    }
}

捕获多个异常:从小到大。

快捷键:Ctrl + Alt + T

package com.bsy.oop.exception;

public class Test {
    public static void main(String[] args) {
        try {//如果不适用try、catch捕获异常,遇到这种问题程序就停止运行了。
            new Test().test(1,0);
        } catch (ArithmeticException e) {
            e.printStackTrace();
        }
    }
    public void test(int a,int b) throws ArithmeticException{//方法上抛出以上需要主动捕获
        if (b==0){//方法里面用throw,方法名上用throws
            throw new ArithmeticException();//主动抛出异常,一般在方法中使用。
        }
    }
}

11.2、自定义异常

  • 处理运行时异常时,合理规避异常的同时辅助try-catch处理。
  • 在多重catch块后面,可以加一个catch(Exception)来处理可能遗漏的异常。
  • 对于可能出现的异常也可以加上try-catch,处理潜在的异常。
  • 出现异常就要尽可能地处理异常,不要总是简单的调用printStackTrace()去打印输出。
  • 尽量添加finally语句去释放占用的资源。
package com.bsy.oop.Demo08;
//自定义异常类
public class MyException extends Exception{//继承exception
    //传递数字
    private int detail;//异常消息

    public MyException(int a) {
        this.detail = a;
    }

    //异常的打印信息
    @Override
    public String toString() {
        return "MyException{" +
                "detail=" + detail +
                '}';
    }
}
package com.bsy.oop.Demo08;

public class Test {
    //可能会出现异常的方法
    static void test(int a) throws MyException {
        System.out.println("传递的参数为:"+a);
        if (a>10){
            throw new MyException(a);//抛出
        }
        System.out.println("OK");
    }
    public static void main(String[] args){
        try {
            test(11);
        } catch (MyException e) {
            //建议增加处理异常的代码块去处理异常
            System.out.println("MyException=>"+e);
        }
    }
}

扩展与补充

各种各样的内部类

class几乎可以写在任何地方

package com.bsy.oop.Demo10;

public class Outer {
    private int id = 133;
    public void out(){
        System.out.println("这是一个外部类的方法");
    }

    public class Inner {
        public void in(){
            System.out.println("这是一个内部类的方法");
        }
        //获得外部类的私有属性
        public void getId(){
            System.out.println(id);
        }
    }
}
//一个Java类中可以有多个class文件,但是只能有一个public class
class A{
    public static void main(String[] args) {

    }
}

调用:

package com.bsy.oop.Demo10;

public class Application {
    public static void main(String[] args) {
        Outer outer = new Outer();

        Outer.Inner inner = outer.new Inner();//通过外部类来实例化内部类outer.new Inner();
        inner.getId();

    }
}

局部内部类:

package com.bsy.oop.Demo10;

public class Outer {
    //局部内部类
    public void method(){
        class Inner{
            public void in(){

            }
        }
    }
}

匿名对象的使用:

package com.bsy.oop.Demo10;

public class Test {
    public static void main(String[] args) {
        //没有名字的初始化类,不用将实例保存到变量中
        new Tomato().say();
    }
}

class Tomato{
    public void say(){
        System.out.println("咿呀~");
    }
}

匿名内部接口:

package com.bsy.oop.Demo10;

public class Test1 {
    public static void main(String[] args) {
        UserService userService = new UserService() {
            @Override
            public void hello() {

            }
        };
    }
}
interface UserService{
    void hello();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值