文章目录
- JavaSE知识体系
- 前言
- 简介Java
- Java的特性和优势
- Java的三大版本
- JDK、JRE、JVM
- Java开发环境搭建
- 卸载JDK
- 安装JDK
- HelloWorld
- 可能遇见的情况
- Java程序运行机制
- IDEA安装
- JavaSE
- 注释
- 标识符和关键字
- 数据类型
- 类型转换
- 变量和常量
- 变量
- 常量
- 运算符
- 包机制
- JavaDoc
- Java流程控制
- 用户交互Scanner
- 顺序结构
- 选择结构(重点)
- 1.if 单选择结构
- 2. if 双选择结构
- 3. if 多选择结构
- 4. 嵌套的 if 结构
- 5.switch 多选结构
- 循环结构
- 1. while 循环
- 2.do...while 循环
- 3.for 循环
- 4.增强for循环
- 5.break 与 continue
- 6.流程控制的训练
- Java方法详解
- 1.方法的定义
- 2.方法调用
- 3.值传递 与 引用传递
- 4.方法重载(重点)
- 5.命令行传参
- 6.可变参数
- 7.递归
- 数组
- 1.数组的定义
- 2.数组声明创建
- 3.内存分析
- 4.数组的三种初始化
- 5.数组的四个基本特点
- 6.数组的边界
- 7.数组使用
- 8.多维数组
- 9.Arrays 类
- 10.冒泡排序
- 11.稀疏数组
- 面向对象编程
- 1.面向过程 & 面向对象
- 2.什么是面向对象
- 3.回顾方法及加深
- 4.类与对象的关系
- 5.创建与初始化对象
- 6.封装
- 7.继承
- 8.多态
- instanceof
- 9.抽象类
- 10.接口
- 11.内部类
- 异常机制
- 1.什么是异常
- 2.异常体系结构
- 3.Error
- 4.Exception
- 5.异常处理机制
- 6.自定义异常
- 7.实际应用中的经验总结
- 代码案例还没补充完整
前言
从零开始学Java,让我们一起了解Java的知识体系。
简介Java Java的特性和优势
- 简单性
- 面向对象
- 可移植性(write once run anywhere)
- 高性能(即时编译)
- 分布式
- 动态性(反射机制)
- 多线程
- 安全性(异常机制)
- 健壮性
JavaSE:标准版(桌面程序,控制台开发…)
JavaME:嵌入式开发(手机,小家电…)
JavaEE:E企业级开发(web端,服务器开发…)
Write Once、Run Anywhere JVM(Java虚拟机) 实现跨平台
JDK、JRE、JVMJDK:Java Development Kit (Java开发者工具 包含了JRE和JVM)
JRE:Java Runtime Environment (Java运行时环境)
JVM:Java Virtual Machine (Java虚拟机)
Java开发环境搭建JDK下载与安装
卸载JDK- 删除Java的安装目录
- 删除JAVA_HOME
- 删除path下关于Java的目录
- 命令提示符中输入 java -version
-
百度搜索JDK8,找到下载地址
-
同意协议
-
下载电脑对应的版本
-
双击安装
-
记住安装的路径
-
配置环境变量
-
我的电脑 --> 右击 --> 属性 --> 高级系统设置
-
环境变量 --> 新建 名为:JAVA_HOME 值为:安装路径
-
配置Path变量
新建 %JAVA_HOME%bin
新建 %JAVA_HOME%jrebin
-
-
测试Java是否安装成功
- 打开cmd
- 命令提示符中输入 java -version
配置环境变量
JDK目录介绍
Hello World 及简单语法规则
HelloWorld-
新建一个文件夹,存放代码
-
新建一个java文件
- 文件后缀名为 .java
- Hello.java
- 注意:系统可能没有显示后缀名,我们需要手动打开
-
编写代码
public class Hello{
public static void main(String[] args){
System.out.println("Hello World");
}
}
-
编译 javac java文件,会生成一个class文件
-
运行class 文件 , java class文件
- 每个单词的大小写不能出现问题,Java大小写敏感的
- 尽量使用英文
- 文件名 和 类名 必须保持一致,并且首字母大写
- 符号用了中文
编译型
解释型
都有翻译的意思(时机的问题)。
编译:只翻译一次。
解释:执行一次翻译一次(实时翻译)。
IDEA安装IDEA官网
什么是IDE(集成开发环境)? eclipse…IDEA
集成开发环境(IDE,Integrated Development Environment )是用于提供程序开发环境的应用程序,一般包括代码编辑器、编译器、调试器和图形用户界面等工具。集成了代码编写功能、分析功能、编译功能、调试功能等一体化的开发软件服务套。所有具备这一特性的软件或者软件套(组)都可以叫集成开发环境。如微软的Visual Studio系列,Borland的C++ Builder、Delphi系列等。该程序可以独立运行,也可以和其它程序并用。IDE多被用于开发HTML应用软件。例如,许多人在设计网站时使用IDE(如HomeSite、DreamWeaver等),因为很多项任务会自动生成。
JavaSE 注释注释不会被执行,是给我们写代码的人看的。
书写注释是一个非常好的习惯。
平时写代码一定要注意规范。
Java中的注释:
- 单行注释 “//”
- 多行注释 “”
- 文档注释 “”
关键字:
Java所有的组成部分都需要名字。类名、变量名以及方法名都被称为标识符。
标识符的注意点:
- 所有标识符都应该以字母(A-Z或a-z),美元符号($)或者下划线(_)开始。
- 首字符之后可以有字母(A-Z或a-z)、美元符号($)、下划线(_)或数字的任意字符组合。
- 不能使用关键字作为变量名或方法名。
- 标识符是大小写敏感的。
- 合法标识符举例: age、$salary 、_value 、_1_value
- 非法标识符举例: 123abc 、-salary 、 #abc
- 可以使用中文名,但是一般不建议这样去使用,也不建议使用拼音,很low。
强制型语言:(安全性高,速度低)
要求变量的使用严格符合规定,所有变量都必须是定义后才能使用。
弱类型语言:
要求变量的使用要符合规定,所有变量都必须是定义后才能使用。
Java的数据类型分为两大类:
- 基本类型(primitive type)
- 引用类型(reference type)
八大基本数据类型
//八大基本数据类型
//整型
int num1 = 10; //最常用
byte num2 = 20;
short num3 = 30;
long num4 = 30L; //Long类型要在数字后面加L
//小数:浮点数
float num5 = 50.1F; //float类型要在数字后面加F
double num6 = 3.1415926535897932;
//字符
char name = 'A';
char a = '中';
//字符串 , String 不是关键字 是一个类
String namea = "三金";
//布尔值:是非
boolean flag = true;
// boolean flag = true;
类型拓展
//整数拓展: 进制 二进制0b 十进制 八进制0 十六进制0x
int i1 = 10;
int i2 = 010; //八进制
int i3 = 0x10; //十六进制 0-9 A-F
System.out.println(i1); //10
System.out.println(i2); //8
System.out.println(i3); //16
System.out.println("========================================");
//========================================
//浮点数的拓展 银行业务怎么表示?
//BigDecimal 数学工具类
//========================================
//flaot 有限的 离散的 舍入误差 大约 接近但不等于
//double
//最好完全避免使用浮点数进行比较
float f = 0.1f; //0.1
double d = 1.0/10; //0.1
System.out.println(f == d); //false
// System.out.println(f);
// System.out.println(d);
float d1 = 2313131323f;
float d2 = d1 + 1;
System.out.println(d1 == d2); //true
System.out.println("========================================");
//========================================
//字符拓展
//========================================
char c1 = 'a';
char c2 = '中';
System.out.println(c1);
System.out.println((int)c1); //强制转换 97
System.out.println(c2);
System.out.println((int)c2); //强制转换 20013
//所有的字符本质还是数字
//编码 Unicode 表: 2字节 0 - 65536 (a=97 A=65) Excel(2^16=65536)
//U0000 UFFFF
char c3 = 'u0061';
System.out.println(c3); //a
//转义字符
//t 制表符
//n 换行符
//....
System.out.println("HellotWorld!");
System.out.println("HellonWorld!");
//
String sa = new String("Hello World");
String sb = new String("Hello World");
System.out.println(sa == sb); //false
String sc = "Hello World";
String sd = "Hello World";
System.out.println(sc == sd); //true
//对象 从内存分析
//boolean 布尔值拓展
boolean flag = true;
if (flag) { }
if(flag==true){ }
//Less is More! 代码要精简易读
什么是字节?
位(bit):是计算机内部数据存储的最小单位,11001100是一个八位二进制数。
字节(byte):是计算机中数据处理的基本单位,习惯上用大写B表示。
1B(byte,字节):8bit(位)
字符:是指计算机中使用的字母、数组、字和符号。
1bit 表示 1位
1Byte 表示一个字节 1B = 8bit
1024B = 1KB
1024KB = 1B
1024M = 1G
电脑上的32位与64位的区别是什么?
类型转换由于Java是强类型语言,所以要进行有些运算的时候,需要用到类型转换。
低 -----------------------------------------> 高
byte、short、char --> int --> long --> float --> double
运算中,不同类型的数据先转换为同一类型,然后在进行计算。
强制类型转换
自动类型转换
int i = 128;
byte b = (byte)i; // 内存溢出
//强制类型转换 (类型)变量名 高 --> 低
//自动类型转换 低 --> 高
System.out.println(i+"n"+b);
System.out.println("==================");
System.out.println((int) 23.7); //23
System.out.println((int) -45.89f); //-45
System.out.println("==================");
char c = 'a';
int d = c + 1;
System.out.println(d);
System.out.println((char) d);
//操作比较大的数的时候,注意溢出问题
//JDK 新特性 数字之间 可以用下划线分割
int money = 10_0000_0000;
int years = 20;
int total = money * years; // -1474836480 计算的时候溢出了
long total2 = money * years; //-1474836480 默认是int,转换之前已经存在问题
long total3 = money * (long) years; //20000000000 先把一个数转换为long
System.out.println(total3);
System.out.println(total2);
System.out.println(total);
System.out.println(money);
变量和常量
变量
变量是什么?
就是可以变化的量。
Java是一种强类型语言,每个变量都必须声明其类型。
Java变量是程序中最基本的存储单元,其要素包括变量名,变量类型和作用域。
type varName [=value] [{,varName[=value]}];
//数据类型 变量名 = 值; 可以使用逗号隔开来声明多个同类型变量
注意事项:
- 每个变量都有类型,类型可以是基本类型,也可以是引用类型。
- 变量名必须是合法的标识符。
- 变量声明是一条完整的语句,因此每一个声明都必须以分号结束。
变量的作用域
类变量(static)
实例变量(跟类变量差不多,无static)
局部变量(方法里面)
public class Vaeriable{ // 类
static int allCkicks = 0; //类变量
String str = "Hello World"; //实例变量
public void method(){ //方法
int i = 0; //局部变量
}
}
//属性: 变量
//实例变量:从属于对象;若不自行初始化,这个类型的默认值 0 0.0
//布尔值:默认式false
//除了基本类型,其余的默认值都是null
String name;
int age;
//类变量
static double salary = 2500;
//修饰符 不存在先后顺序
static final double PI = 3.14;//常量
//main方法
public static void main(String[] args) {
// int a,b,c;
// int a = 1, b = 2, c = 3; //程序可读性
int a = 1;
int b = 2;
int c = 3;
String name = "mwx";
char x = 'X';
double pi = 3.14;
//局部变量:必须声明和初始化值
int i = 10;
System.out.println(i);
//变量类型 变量名字 = new base.Demo05();
Demo05 demo05 = new Demo05();
System.out.println(demo05.age);//0
System.out.println(demo05.name);//null
//类变量 static
System.out.println(salary);
System.out.println(PI);
}
//其他方法
public void add(){
}
常量
常量(Constant):初始化(intimate)后不能改变值!不会变动的值。
所谓常量可以理解成一种特殊的变量,它的值被设定后,在程序运行程序中不允许被改变。
final 常量名 = 值; final double PI = 3.1415926; final double MAX_A;
常量名一般用大写字符。
变量的命名规则:
- 所有变量、方法、类名:见名知意
- 类成员变量:首字母小写和驼峰原则 monthSalary 除了第一个单词外,后面的单词首字母大写
- 局部变量:首字母小写和驼峰原则
- 方法名:首字母小写和驼峰原则 run() , runRun()
- 类名:首字母大写和下划线 Man, GoodMan
- 常量:大写字母和下划线 MAX_VALUE
Java支持如下的运算符(了解运算符)
- 算术运算符:+、-、*、/、%、++、–
- 赋值运算符:=
- 关系运算符:>、<、>=、<=、==、!=、instanceof
- 逻辑运算符:&&、||、!
- 位运算符:&、|、^、~、>>、<<、>>>(了解)
- 条件运算符:?:
- 扩展赋值运算符:+=、-=、*=、/=
为了更好的组织类,Java提供了包机制,用于区别类名的命名空间。
包语句的语法格式为:
package pkg1[.pkg2[.pkg3...]];
一般利用公司的域名倒置作为包名。
为了能够使用某一个成员,我们需要在Java程序中明确导入该包。使用“import”语句可完成此功能。
import package1[.package2...].(classname|*);JavaDoc
Javadoc命令就是用来生成自己的API文档。
代码
public class Doc {
String name;
public String test(String name) throws Exception{
return name;
}
public static void main(String[] args) {
}
}
命令生成:(命令行中)
javadoc -encoding UTF-8 -charset UTF-8 Doc.java
使用IDEA生成JavaDoc文档:
在编写完文档注释和代码之后,进行如下操作来生成JavaDoc文档:
在IDEA中点击 Tools -> Generate JavaDoc… :
进入
点击OK开始打包javadoc。
在运行窗口看到: “javadoc” finished with exit code 0 打包成功
解释说明:
- Whole project:整个项目都生成文档
- Custom scope: 自定义范围。
- include JDK and … : 包含jdk和其他的第三方jar
- link to JDK documentation…: 链接到JDK api
- output directy :生成的文档存放的位置
- private、package、protected、public :生成文档的级别(类和方法)
- Generate…:是选择生成的文档包含的内容,层级树、导航、索引…
- Generate右边的@:是生成的文档包含的内容信息,作者版本等信息
- Locale :语言类型,zh-CN 或者不填
- Other command line arguments: 其他参数
- Maximum heep… :最大堆栈
建议使用UTF-8编码、否则会出现中文乱码: -encoding UTF-8 -charset UTF-8
写在方法上的javadoc
写在方法上的文档标注一般分为三段:
第一段:概要描述,通常用一句或者一段话简要描述该方法的作用,以英文句号作为结束。
第二段:详细描述,通常用一段或者多段话来详细描述该方法的作用,一般每段话都以英文句号作为结束。
第三段:文档标注,用于标注参数、返回值、异常、参阅等。
JavaDoc 标记有如下一些:
@author 标明开发该类模块的作者
@version 标明该类模块的版本
@see 参考转向,也就是相关主题
@param 对方法中某参数的说明
@return 对方法返回值的说明
@exception 对方法可能抛出的异常进行说明
@author 作者名
@version 版本号
其中,@author 可以多次使用,以指明多个作者,生成的文档中每个作者之间使用逗号 (,) 隔开。@version 也可以使用多次,只有第一次有效
使用 @param、@return 和 @exception 说明方法
这三个标记都是只用于方法的。@param 描述方法的参数,@return 描述方法的返回值,@exception 描述方法可能抛出的异常。它们的句法如下:
@param 参数名 参数说明
@return 返回值说明
@exception 异常类名 说明
Scanner对象
之前我们学的基本语法中并没有实现程序和人的交互,但是Java给我们提供了这样一个工具类,我们可以获取用户的输入。Java.util.Scanner 是Java5的新特性。我们可以通过Scanner类来获取用户的输入。
基本语法:
Scanner scanner = new Scanner(System.in);
通过Scanner 类的 next() 与 nextLine() 方法获取输入的字符串,在读取前我们需要用hasNext() 与 hasNextLine() 判断是否还有输入的数据。
next()
- 一定要读取到有效字符后才可以结束输入。
- 对输入有效字符之前遇到的空白,next()方法会自动将其去掉。
- 只有输入有效字符后才将其后面输入的空白作为分隔符或结束符。
- next() 不能得到带有空格的字符串。
public static void main(String[] args) {
//创建一个扫描器对象,用户接收键盘数据
Scanner scanner = new Scanner(System.in);
System.out.println("使用next方式接收:");
//判断用户有没有字符串
if (scanner.hasNext()) {
//使用next方式接收
String str = scanner.next(); //程序会等待用户输入完毕
System.out.println("输出的内容为:" + str);
//不接受空格 输入 : m w x 输出:m
}
//凡是余数IO(输入输出)流的类入关不关闭就会一直占用资源,要养成好习惯用完就关闭
scanner.close();
}
nextLine()
- 以Enter为结束符,也就是说nextLine() 方法返回的是输入回车之前的所有字符。
- 可以获得空白。
public static void main(String[] args) {
//创建一个扫描器对象,用户接收键盘数据
Scanner scanner = new Scanner(System.in);
System.out.println("使用nextLine方式接收:");
//判读是否还有输入
if (scanner.hasNextLine()) {
String str = scanner.nextLine();
System.out.println("输出的内容:"+str);
}
scanner.close();
}
顺序结构
Java的基本结构就是顺序结构,除非特别指明,否则就按照一句一句执行。
顺序结构是最简单的算法结构。
语句与语句之间,框与框之间是按从上到下的顺序进行的,它是由若干个依次执行的处理步骤组成的,它是任何一个算法都离不开的一种算法结构。
public static void main(String[] args) {
System.out.println("hello1");
System.out.println("hello2");
System.out.println("hello3");
System.out.println("hello4");
System.out.println("hello5");
}
选择结构(重点)
1.if 单选择结构
//语法:
if(布尔表达式){
//如果布尔表达式为true将执行的语句
}
//例如:
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入内容:");
String s = scanner.nextLine();
//equals:判断字符串是否相等
if (s.equals("Hello")) {
System.out.println(s);
}
System.out.println("End");
scanner.close();
}
2. if 双选择结构
// 语法:
if(布尔表达式){
//如果布尔表达式为true将执行的语句
}else{
//如果布尔表达式为false将执行的语句
}
//例如:
public static void main(String[] args) {
//考试分数 大于60 及格 反之不及格
Scanner scanner = new Scanner(System.in);
System.out.println("请输入成绩:");
int socre = scanner.nextInt();
if (socre >= 60) {
System.out.println("及格");
}else{
System.out.println("不及格");
}
scanner.close();
}
3. if 多选择结构
// 语法:
if(布尔表达式1){
//如果布尔表达式1为true将执行的语句
}else if(布尔表达式2){
//如果布尔表达式2为true将执行的语句
}else if(布尔表达式3){
//如果布尔表达式3为true将执行的语句
}else{
//如果以上布尔表达式都不为true将执行的语句
}
//例如:
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入成绩:");
int socre = scanner.nextInt();
if (socre == 100) {
System.out.println("恭喜满分!");
} else if (socre >= 90 && socre < 100) {
System.out.println("A");
} else if (socre >= 80 && socre < 90) {
System.out.println("B");
} else if (socre >= 70 && socre < 80) {
System.out.println("C");
} else if (socre >= 60 && socre < 70) {
System.out.println("D");
} else {
System.out.println("成绩不合法");
}
scanner.close();
}
4. 嵌套的 if 结构
使用嵌套的 if…else 语句是合法的。也就是说你可以在另一个 if 或者 else if 语句中使用 if 或者 else if 语句。
//语法:
if(布尔表达式1){
//如果布尔表达式1为true将执行的语句
if(布尔表达式2){
//如果布尔表达式2为true将执行的语句
}
}
5.switch 多选结构
多选择结构还有一个实现方法就是 switch case 语句。
switch case 语句判断一个变量与一个系列中某个值是否相等,每个值称为一个分支。
//语句:
switch(experssion){
case value:
//语句
break; //可选
case value:
//语句
break; //可选
//可以由任意数量的case语句
default: //可选
//语句
}
switch 语句中的变量类型可以是:
- byte、short、int或者char
- 从Java SE 7 开始
- switch 支持字符串 String 类型
- 同时 case 标签必须为字符串常量或字面量
public static void main(String[] args) {
//case 穿透
//switch 匹配一个具体的值
char grade = 'P';
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("未知等级");
}
}
===========================================================================
public static void main(String[] args) {
String name = "三金";
//JDK 7 的新特性 表达式结果可以是字符串
//字符串的本质还是数字
//反编译 java--class(字节码文件)--反编译(IDEA)
switch (name) {
case "小马":
System.out.println("小马啊");
break;
case "三金":
System.out.println("三金啊");
break;
default:
System.out.println("弄啥啊");
}
}
循环结构
- while 循环
- do…while 循环
- for循环
在Java 5 中引入了一种主要用于数组的增强型 for 循环
1. while 循环while 是最基本的循环,它的结构为:
while(布尔表达式){
//循环内容
}
只要布尔表达式为true,循环就会一直执行下去。
我们大部分情况是会让循环停止下来的,我们需要一个让表达式失效的方式来结束循环。
少部分情况需要循环一直执行,比如服务器的请求响应监听等。
循环条件一直为true就会造成无限循环(死循环),我们正常的业务编程中应尽量避免死循环。会影响程序性能或造成程序卡死崩溃。
思考:计算1+2+3+…+100=?
public static void main(String[] args) {
int i = 0;
int sum = 0;
while (i < 100) { //1....100
i++;
sum += i;
}
System.out.println("sum:"+sum);
}
2.do…while 循环
对于while语句而言,如果不满足条件,则不能进入循环。但有时候我们需要即使不满足条件,也至少执行一次。
do{
//代码语句
}while(布尔表达式)
do…while 和 while 的区别:
- while 先判断后执行,do while 先执行后判断。
- do while 总是保证循环体会被至少执行一次。
public static void main(String[] args) {
int i = 0;
int sum = 0;
do {
sum += i;
i++;
} while (i <= 100);
System.out.println("sum:" + sum);
}
3.for 循环
for循环语句是支持迭代的一种通用结构,是最有效、最灵活的循环结构。
for 循环执行的次数是在执行前就确定的。
for( 初始化 ; 布尔表达式 ; 更新){
//执行语句
}
public static void main(String[] args) {
int i = 1; //初始化条件
while (i <= 1000) { //条件判断
System.out.println(i); // 循环体
i += 2; //迭代
}
System.out.println("while循环结束!");
//100.for
for (int j = 1; j < 1000; j++) {
System.out.println(j);
}
System.out.println("for循环结束!");
//死循环
for (; ; ) {
}
}
===================================================================================
public static void main(String[] args) {
int[] nums = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100}; //定义了一个数组
//遍历数组的元素
for (int x : nums) {
System.out.println(x);
}
System.out.println("================================");
for (int i = 0; i < 10; i++) {
System.out.println(nums[i]);
}
}
练习:
1.计算0到100之间奇数和偶数的和
2.用while或for循环输出1-100之间能被5整除的数,并且每行输出三个
3.打印九九乘法表
public static void main(String[] args) {
oddNumberAndEvenNumber();
modFive();
multiplicationTables();
}
private static void oddNumberAndEvenNumber() {
// 计算0到100之间的奇数和偶数的和
System.out.println("计算0到100之间的奇数和偶数的和");
int oddNumber = 0;
int evenNumber = 0;
for (int i = 0; i <= 100; i++) {
if (i % 2 == 0) { //偶数
evenNumber += i;
} else { //奇数
oddNumber += i;
}
}
System.out.println("奇数:"+oddNumber);
System.out.println("偶数:"+evenNumber);
System.out.println("=======================");
}
private static void modFive() {
// 用while或for循环输出1-1000之间能被5整除的数,并且每行输出三个
System.out.println("用while或for循环输出1-1000之间能被5整除的数,并且每行输出三个");
int flag = 0;
for (int i = 0; i <= 1000; i++) {
if (flag == 3) {
flag = 0;
System.out.println();
}
if (i % 5 == 0) {
System.out.print(i+"t");
flag++;
}
}
System.out.println();
System.out.println("===========================");
int i = 1000;
flag = 0;
while (i >= 0) {
if (flag == 3) {
System.out.println();
flag = 0;
}
if (i % 5 == 0) {
flag++;
System.out.print(i + "t");
}
i--;
}
//换行
System.out.println();
// System.out.print("n");
}
private static void multiplicationTables() {
System.out.println("=======================");
System.out.println("九九乘法表:");
//九九乘法表
for (int i = 1; i < 10; i++) {
for (int j = 1; j <= i; j++) {
// System.out.print(j + " * " + i + " = " + (i * j)+" ");
System.out.print(j + "*" + i + "=" + (i * j)+"t");
}
System.out.println();
}
}
4.增强for循环
Java 5 引入了一种主要用于数组或集合的增强型 for 循环。
for(声明语句 : 表达式){
//代码语句
}
声明语句:声明新的局部变量,该变量类型必须和数组元素的类型匹配。其作用域限定在循环语句块,其值与此时数组元素的值相等。
表达式:表达式是要访问的数组名,或者是返回值为数组的方法。
5.break 与 continuebreak 在任何循环语句的主体部分,均可用break控制循环的流程。break用于强行退出循环,不执行循环中剩下的语句。(break语句也在switch语句中使用)
public static void main(String[] args) {
int i = 0;
while(i<100){
i++;
System.out.println(i);
if (i == 30) {
break;
}
}
}
continue 语句用在循环语句体中,用于终止某一次循环过程,即跳过循环体中尚未执行的语句,接着进行下一次是否执行循环的判断。
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+"t");
}
}
关于goto关键字:
- goto关键字很早就在程序设计语言中出现。尽管goto 仍是一个保留字,但并未在语言中得到正式使用:Java没有goto。然而,在break 和 continue 这两个关键字的身上,我们仍然能看出一些 goto 的影子—带标签的 break 和 continue。
- “标签”是指后面跟一个冒号的标识符,例如: label:
- 对Java来说唯一用到标签的地方是在循环语句之前。而在循环之前设置标签的唯一理由是:我们希望在其中嵌套另一个循环,由于break 和continue 关键字通常指中断当前循环,他们就会中断存在标签的地方。
public static void main(String[] args) {
//打印101——150之间的质数
//质数:在大于1的自然数中,除了一跟本身以外不再有其他因数的自然数。
int count = 0;
outer: for (int i = 101; i <= 150; i++) {
for (int j = 2; j < i / 2; j++) {
if (i % j == 0) {
continue outer;
}
}
System.out.print(i+" ");
}
}
6.流程控制的训练
输出三角形(五行)
* *** ***** ******* *********
public static void main(String[] args) {
//打印三角形 五行
for (int i = 1; i <= 5; i++) {
// for (int j = 1; j <= 5 - i; j++) {
for (int j=5;j>i;j--){
System.out.print(" ");
}
for (int j = 1; j <= 2 * i - 1; j++) {
System.out.print("*");
}
System.out.println();
}
System.out.println("=====================");
for (int i = 1; i <= 5; i++) {
for (int j = 5; j > i; j--) { //输出前面空格
System.out.print(" ");
}
for (int j = 1; j <= i; j++) { //三角形折半
System.out.print("*");
}
for (int j = 1; j < i; j++) {
System.out.print("*");
}
System.out.println();
}
}
Java方法详解
何谓方法?
Java方法是语句的集合,它们在一起执行一个功能。
- 方法是解决一类问题的步骤的有序集合。
- 方法包含于类或对象中。
- 方法在程序中被创建,在其他地方被引用。
设计方法的原则:
方法的本意是功能块,就是实现某个功能的语句块的集合。我们设计方法的时候,最好保持方法的原子性,就是一个方法只完成一个功能,这样就有利于我们后期的扩展。
方法的命名规则:首字母小写,驼峰原则。
1.方法的定义Java的方法类似于其他语言的函数,是一段用来完成特定功能的代码片段,在一般情况下,定义一个方法包含以下语法:
方法包含一个方法头和一个方法体。下面是一个方法的所有部分:
-
修饰符:修饰符,这是可选的,告诉编译器如何调用该方法。定义该方法的访问类型。
-
返回值类型:方法可能有返回值。returnValueType 是方法返回值的数据类型。有些方法执行所需要的操作,但没有返回值,在这种情况下,returnValueType 的关键字是void。
-
方法名:是方法的实际名称。方法名和参数表共同构成方法名。
-
参数类型:参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。
- 形式参数:在方法被调用时用于接收外界输入的数据。
- 实参:调用方法时实际传给方法的数据。
-
方法体:方法体包含具体的语句,定义该方法的功能。
修饰符 返回值类型 方法名(参数类型 参数名){
...
方法体
...
return 返回值;
}
2.方法调用
类名.方法
对象.方法
调用方法:对象名.方法名(实参列表)
Java支持两种调用方法的方式,根据方法是否返回值类选择。
当方法返回一个值的时候,方法调用一定是一条语句。
int larger = max(30,40);
如果方法返回值为void,方法调用一定是一条语句。
System.out.println("Hello ThreeGold!");
//main方法
public static void main(String[] args) {
//实际参数:实际调用传递给它的参数
int add = add(1, 2);
System.out.println(add);
System.out.println("==================================================================");
test();
}
//加法
//形式参数:用来定义作用
public static int add(int a,int b) {
return a+b;
}
public static void test() {
// 用while或for循环输出1-1000之间能被5整除的数,并且每行输出三个
System.out.println("用while或for循环输出1-1000之间能被5整除的数,并且每行输出三个");
int flag = 0;
for (int i = 0; i <= 1000; i++) {
if (flag == 3) {
flag = 0;
System.out.println();
}
if (i % 5 == 0) {
System.out.print(i+"t");
flag++;
}
}
}
3.值传递 与 引用传递
Java是值传递。
值传递:
在方法被调用时,实参通过形参把它的内容副本传入方法内部,此时形参接收到的内容是实参值的一个拷贝,因此在方法内对形参的任何操作,都仅仅是对这个符本的操作,不影响原始值的内容。
值传递传递的是真实内容的副本,对副本的操作不影响原内容,也就是形参怎么变化,不会影响实参对应的内容。
引用传递:
“引用”也就是指向真实内容的地址值,在方法调用时,实参的地址通过方法调用传递给相应的形参,在方法体内,形参和实参指向同一块内存地址,对形参的操作会影响真实内容。
引用传递,在Java中并不存在。
4.方法重载(重点)名字相同参数列表不同。
重载就是在一个类中,有相同的函数名称,但形参不同的函数。
方法重载的规则:
- 方法名称必须相同。
- 参数列表必须不同(个数不同,类型不同、参数排列顺序不同等)。
- 方法的返回值类型可以相同也可以不相同。
- 仅仅返回值类型不同不足以称为方法重载。
实现理论:
- 方法名称相同时,编译器会根据调用方法的参数个数、参数类型等去逐个匹配,以选择对应的方法,如果匹配失败则编译器报错。
public static void main(String[] args) {
int max = max(23, 23);
double max1 = max(23.0, 32);
max(10, 20, 30);
System.out.println(max);
System.out.println("=============");
System.out.println(max1);
}
//比大小
public static int max(int num1 , int num2) {
int result;
if (num1 == num2) {
System.out.println("num1==num2");
return 0; //终止方法
}
if (num1 > num2) {
result = num1;
} else {
result = num2;
}
return result;
}
//比大小
public static double max(double num1, double num2) {
double result;
if (num1 == num2) {
System.out.println("num1==num2");
return 0; //终止方法
}
if (num1 > num2) {
result = num1;
} else {
result = num2;
}
return result;
}
//比大小
public static double max(double num1, double num2,double num3) {
double result;
if (num1 == num2) {
System.out.println("num1==num2");
return 0; //终止方法
}
if (num1 > num2) {
result = num1;
} else {
result = num2;
}
return result;
}
5.命令行传参
有时候希望运行一个程序时候再传递给它消息。这要靠传递命令行参数给main()函数实现。
public static void main(String[] args) {
//args.length 数组长度
for (int i = 0; i < args.length; i++) {
System.out.println("args[" + i + "]" + args[i]);
}
}
6.可变参数
JDK 1.5 开始,Java支持传递同类型的可变参数给一个方法。
在方法声明中,在指定参数类型后面加一个省略号(…)。
一个方法中只能指定一个可变参数,它必须是方法的最后一个参数,任何普通的参数必须在它之前声明。
public void test(int... ints){}
public void test(double x,int... ints){}
public static void main(String[] args) {
Demo04 demo04 = new Demo04();
demo04.printMax(10,20,30,40,9,100);
demo04.printMax(23,12,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 = 1; i < numbers.length; i++) {
if (numbers[i] > result) {
result = numbers[i];
}
}
double max = numbers[0];
for (double a : numbers) {
if (a > max) {
max = a;
}
}
System.out.println("=============================================");
System.out.println("The max value is :" + result);
System.out.println("The max value is :" + max);
}
7.递归
A方法调用B方法,很容易理解。
递归就是:A方法调用A方法,就是自己调用自己。
利用递归可以用简单的程序来解决一些复杂的问题。它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。
递归结构包括两个部分:
- 递归头:什么时候不调用自身方法。如果没有头,将陷入死循环。
- 递归体:什么时候需要调用自身方法。
边界条件:边界
前阶段
返回条件
Java使用栈机制
public static void main(String[] args) {
Demo05 demo05 = new Demo05();
demo05.test();
}
//会出现栈溢出异常
public void test() {
test();
}
public static void main(String[] args) {
Demo06 demo06 = new Demo06();
int num = demo06.fun(5);
System.out.println(num);
}
//5!
//2 2*f(1) f(1) = 1 2 * 1
//3 3*f(2) f(2) = 2*f(1) f(1) = 1 3*2*1
public static int fun(int n) {
if (n == 1) {
return 1;
} else {
return fun(n - 1) * n;
}
}
数组
1.数组的定义
数组是相同类型数据的有序结合。
数组描述的是相同数据按照一定的先后次序排列组合而成的/
其中,每一个元素称作为一个数组元素,每一个数组元素可以通过一个下标来访问他们。
2.数组声明创建首先必须声明数组变量,才能在程序中使用数组。声明数组变量的语法:
dataType[] arrayRefVar; //首选方法 或 dataType arrayRefVar[]; //效果相同
Java语法使用new操作符来创建数组,语法如下:
dataType[] arrayRefVar = new dataType[arraySize];
数组元素是通过索引访问的,数组的索引从0开始。
获取数组的长度:
array.length;
// 变量类型 变量名 = 变量的值;
// 数组类型
public static void main(String[] args) {
int[] numbers; //定义 首选 1.声明一个数组
int num2[];
numbers = new int[10]; // 2.创建一个数组
//这里面可以存放10个int类型的数字
int[]nums = new int[10];
//3.给数组元素中赋值
numbers[0] = 1;
numbers[1] = 2;
numbers[2] = 3;
numbers[3] = 4;
numbers[4] = 5;
numbers[5] = 6;
numbers[6] = 7;
numbers[7] = 8;
numbers[8] = 9;
numbers[9] = 10;
int sum = 0;
//计算所有元素的和
for (int i = 0; i < numbers.length; i++) {
sum += numbers[i];
}
System.out.println("总和为:" + sum);
}
3.内存分析
Java内存分析
1.静态初始化
int[] a = {1,2,3};
Man[] mans = {new Man(1,1),new Man(2,2)};
2.动态初始化
int[] a = new int[2]; a[0] = 1; a[1] = 2;
3.数组的默认初始化
数组是引用类型,他的元素相当于类的实例变量,因此数组一经分配空间,其中的每一个元素也被按照实例变量同样的方式被隐式初始化。
public static void main(String[] args) {
//静态初始化: 创建 + 赋值
int[] a = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// Man[] mans = {new Man(), new Man()};
System.out.println(a[0]); // 1
//动态初始化: 包含默认初始化
int[] b = new int[10];
b[0] = 10;
System.out.println(b[0]); // 10
System.out.println(b[1]); // 0
System.out.println(b[10]); //ArrayIndexOutOfBoundsException
//数组下标越界异常
}
5.数组的四个基本特点
- 长度是固定的。数组一旦被创建,它的大小就是不可以改变的。
- 元素必须是相同是相同类型,不允许出现混合类型。
- 数组中的元素可以是任何数据类型,包括基本类型和引用类型。
- 数组变量属于引用类型,数组也可以看成是对象,数组中的每个元素相当于该队行的成员变量。数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中的。
下标的合法区间:[0,length-1],如果越界就会报错。
public static void main(String[] args){
int[] a = new int[2];
System.out.println(a[2]);
}
ArrayIndexOutOfBoundsException:数组下标越界异常。
小结:
- 数组是相同数据类型(数据类型可以为任意类型)的有序集合。
- 数组也是对象。数组元素相当于对象的成员变量。
- 数组长度是确定的,不可变的。如果越界,则报:ArrayIndexOutOfBoundsException
普通的for循环
public static void main(String[] args) {
int[] array = {1, 2, 3, 4, 5};
//打印全部的数组元素
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
System.out.println("=======================");
//计算所有元素的和
int sum = 0;
for (int i = 0; i < array.length; i++) {
sum += array[i];
}
System.out.println("sum:"+sum);
//查找最大元素
int max = array[0];
for (int i = 1; i < array.length; i++) {
if (array[i] > max) {
max = array[i];
}
}
System.out.println("最大值:"+max);
}
For-Each循环
public static void main(String[] args) {
int[] arrays = {1, 2, 3, 4, 5};
//JDK 1.5 ,没有下标
for (int array : arrays) {
System.out.println(array);
}
}
数组作为方法入参
public static void main(String[] args) {
int[] arrays = {1, 2, 3, 4, 5};
//JDK 1.5 ,没有下标
for (int array : arrays) {
System.out.println(array);
}
printArrays(arrays);
System.out.println();
}
//打印数组元素
public static void printArrays(int[] arrays) {
for (int i = 0; i < arrays.length; i++) {
System.out.print(arrays[i]+" ");
}
}
数组作返回值
public static void main(String[] args) {
int[] arrays = {1, 2, 3, 4, 5};
//JDK 1.5 ,没有下标
for (int array : arrays) {
System.out.println(array);
}
printArrays(arrays);
System.out.println();
System.out.println("反转数组");
int[] reverseArrays = reverse(arrays);
printArrays(reverseArrays);
}
//打印数组元素
public static void printArrays(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; i < arrays.length; i++) {
result[i] = arrays[arrays.length - i - 1];
}
return result;
}
8.多维数组
多维数组可以看成是数组的数组,比如二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组。
二维数组
int[][] a = new int[2][5];
以上二维数组 a 可以看成一个两行五列的数组。
public static void main(String[] args) {
int[][] array = {{1, 2}, {2, 3}, {3, 4}, {4, 5}};
//[4][2]
System.out.println(array.length);
System.out.println(array[0].length);
for (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();
}
}
9.Arrays 类
数组的工具类 java.util.Arrays
由于数组对象本身并没有什么方法可以提供我们调用,但是 API 中提供了一个工具类 Arrays 供我们使用从而可以对数据对对象进行一些基本的操作。
查看 JDK 帮助文档。
Arrays 类中的方法都是 static 修饰的静态方法,在使用的时候可以直接使用类名进行调用,而“不用”使用对象来调用。(注意是“不用”而不是“不能”)
具有以下常用功能:
- 给数组赋值:通过 fill 方法。
- 对数组排序:通过 sort 方法,按升序。
- 比较数组:通过 equals 方法比较数组中元素值是否相等。
- 查找数组元素:通过 binarySearch 方法能够对排好序的数组进行二分查找法操作。
public static void main(String[] args) {
int[] a = {1, 2, 3, 90, 12, 21, 32, 23};
System.out.println(a); // [I@7c30a502
//打印数组元素Arrays.toString()
System.out.println(Arrays.toString(a));
printArrays(a); // 自定义的打印输出方法
//数组进行排序 升序
Arrays.sort(a);
System.out.println(Arrays.toString(a));
//数组填充
Arrays.fill(a, 2,4,0);
System.out.println(Arrays.toString(a));//[1, 2, 0, 0, 21, 23, 32, 90]
Arrays.fill(a, 0);
System.out.println(Arrays.toString(a));//[0, 0, 0, 0, 0, 0, 0, 0]
}
public static void printArrays(int[] a) {
for (int i = 0; i < a.length; i++) {
if (i == 0) {
System.out.print('[');
}
System.out.print(a[i]);
if (i == a.length - 1) {
System.out.print(']');
} else {
System.out.print(", ");
}
}
System.out.println();
}
10.冒泡排序
冒泡排序无疑是最为出名的排序算法之一,总共有八大排序算法。
冒泡的代码很简单,两层循环,外层冒泡轮数,里层一次比较,江湖中人人尽皆知。
我们看到嵌套循环,应该立马就可以得出这个算法的时间复杂度为O(n2)。
如何优化?
public static void main(String[] args) {
int[] a = {1, 2, 40, 56, 98, 45, 78, 0};
System.out.println("排序前:");
System.out.println(Arrays.toString(a));
sort(a);
System.out.println("排序后:");
System.out.println(Arrays.toString(a));
}
//冒泡排序
//1.比较数组中,两个相邻的元素,若第一个数比第二个数大,我们就交换它们的位置
//2.每一轮比较,都会产生一个最大或最小的数字
//3.下一轮则可以少排序一次
//4.依次循环,直到结束
public static int[] sort(int[] arrays) {
int temp = 0; //临时变量
//外层循环 判断们这个要走多少次
for (int i = 0; i < arrays.length; i++) {
//优化
boolean flag = false; //通过flag标志位减少没有意义的比较
//内层循环 比较判断两个数,若第一个数比第二个数大,则交换位置
for (int j = 0; j < arrays.length - i - 1; j++) {
if (arrays[j] > arrays[j + 1]) {
temp = arrays[j];
arrays[j] = arrays[j + 1];
arrays[j + 1] = temp;
flag = true;
}
}
if (flag == false) {
break;
}
}
return arrays;
}
11.稀疏数组
稀疏数组是一种数据结构。
需求:编写五子棋游戏中,有存盘退出贺续上盘的功能。
分析问题:因为该二维数组的很多默认值为0,因此记录了很多没有意义的数据。
解决:稀疏数组
稀疏数组:
- 当一个数组中大部分元素为0,或者为同一值的数组时,可以使用稀疏数组来保存该数组。
- 稀疏数组的处理方式是:
- 记录数组一共有几行几列,有多少个不同值
- 把具有不同值的元素贺行列及值保存在一个小规模的数组中,从而缩小程序的规模 - 如下图:左边是原始数组,右边是稀疏数组
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) {
for (int anInt : ints) {
System.out.print(anInt + "t");
}
System.out.println();
}
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);
//创建一个稀疏数组
int[][] array2 = new int[sum + 1][3];
//遍历二维数组,将非零的值存放在稀疏数组中
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++;
array2[count][0] = i;
array2[count][1] = j;
array2[count][2] = array1[i][j];
}
}
}
array2[0][0] = array1.length;
array2[0][1] = array1[0].length;
array2[0][2] = count;
//输出稀疏数组
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");
}
System.out.println("=================");
System.out.println("还原:");
//读取稀疏数组
int[][] array3 = new int[array2[0][0]][array2[0][1]];
//给其中的元素还原它的值
for (int i = 1; i < array2.length; i++) {
array3[array2[i][0]][array2[i][1]] = array2[i][2];
}
//打印
System.out.println("还原的数组:");
for (int[] ints : array3) {
for (int anInt : ints) {
System.out.print(anInt+"t");
}
System.out.println();
}
}
面向对象编程
Java的核心思想OOP
1.面向过程 & 面向对象面向过程的思想
- 步骤清晰简单,第一步做什么,第二步做什么…
- 面向过程适合处理一些较为简单的问题
面向对象的思想:
- 物以类聚,分类的思维模式,思考问题首先解决需要那些分类,然后对这些进行单独思考。最后,才对某个分类下的细节进行面向过程的思索。
- 面向对象适合处理复杂的问题,适合处理需要多人协作的问题!
对于描述复杂的事物,为了从宏观上把握、从整体上合理分析,我们需要使用面向对象的思路来分析整个系统。但是,具体到微观操作,仍然需要面向过程的思想去处理。
2.什么是面向对象面向对象编程(OOP,Object-Oriented Programming)
面向对象编程的本质就是:以类的方式组织代码,以对象的方式组织(封装)数据。
抽象
三大特性:
- 封装
- 继承
- 多态
从认识角度考虑是先有对象后有类。
对象,是具体的事物。
类,是抽象的,是对对象的抽象。
从代码运行角度考虑是先有类后有对象。
类是对象的模板。
3.回顾方法及加深方法的定义:
- 修饰符
- 返回类型
- break 和 return 的区别
break 跳出switch,结束循环。
return 方法结束。 - 方法名:注意规范(驼峰命名),见名知意。
- 参数列表:参数类型 参数名 …
- 异常抛出
方法的调用:
- 静态方法
- 非静态方法
- 形参和实参
- 值传递和引用传递
- this关键字
//Demo01 类
public class Demo01 {
//main方法
public static void main(String[] args) {
}
//return 结束方法,返回一个结果!
public String sayHello(){
return "Hello World!";
}
public void print() {
return;
}
public int max(int a, int b) {
return a > b ? a : b; //三元运算符
}
public void readFile(String file) throws IOException {
return ;
}
}
静态方法 非静态方法
public class Demo02 {
//静态方法 static
//非静态方法
public static void main(String[] args) {
//静态方法 类名.方法名
Student.say();
//非静态方法
//实例化这个类 new
//对象类型 对象名 = 对象值;
// new Student().saySay();
Student student = new Student();
student.saySay();
}
// static 和类一起加载的
public static void a() {
// b();
}
//类实例化之后才存在
public void b() {
}
}
//学生类
public class Student {
//静态方法
public static void say() {
System.out.println("学生说话");
}
//非静态方法
public void saySay() {
System.out.println("学生说悄悄话");
}
}
值传递和引用传递
public class Demo03 {
public static void main(String[] args) {
//实际参数和形式参数的类型要对应
int add = Demo03.add(1300, 14);
System.out.println(add);
}
public static int add(int a, int b) {
return a + b;
}
}
//值传递
public class Demo04 {
public static void main(String[] args) {
int a = 1;
System.out.println(a); //1
Demo04.cahnge(a);
System.out.println(a); //1
}
//返回值为空
public static void cahnge(int a) {
a = 10;
}
}
//引用传递 : 对象 本质还是值传递
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是一个对象
//指向的是 Person person = new Person(); 这个一个具体的人 可以改变属性!
person.name = "小马";
}
}
//定义了一个Person类 有一个属性 name
class Person {
String name; //默认值:null
}
4.类与对象的关系
类是一种抽象的数据类型,它是对某一类事物整体的描述/定义,但是并不能代表某一具体的事物。
- 动物、植物、授手机、电脑…
- Person类、Pet类i、Car类,这些类都是用来描述/定义某一类具体事物应该具备的特点和行为
对象是抽象概念的具体实例
- 张三就是人的一个具体实例,张三加的一条狗就是狗的一个具体实例
- 能够体现出特点,展现处功能的具体实例,而不是一个抽象的概念
使用new关键字创建对象
使用new关键字创建的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用。
类中的构造器也成为构造方法,是在进行创建对象的时候必须要调用的。并且构造器又有一下两个特点:
- 必须和类的名字相同。
- 必须没有返回类型,也不能写void。
构造器必须掌握
6.封装该露的露,该藏的藏。
- 我们设计程序要追求“高内聚,低耦合”。
- 高内聚:就是类的内部数据操作细节自己完成,不允许外部干涉。
- 低耦合:仅暴露少量的方法给外部使用。
封装(数据的隐藏)
通常,应禁止直接方法一个对象中数据的实际表示,而应通过操作接口来访问,这成为信息隐藏。
属性私有,get/set
7.继承继承的本质就是对某一批类的抽象,从而对现实世界更好的建模。
extends 的意思是“扩展”。子类是父类的扩展。
Java中类只有单继承,没有多继承。
子类拥有父类的全部特性。
继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖、组合、聚合等。
继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends来表示。
子类和父类之间,从意义上讲应该具有“is a”的关系。
Object 类
super this
方法重写 (重点 ) 多态
动态编译: 类型: 可扩展性
即同一个方法可以根据发送对象的不同而采用多种不同的行为方式。
一个对象的实际类型是确定的,但可以指向对象的引用类型由很多(父类,有关系的类)。
多态存在的条件:
- 有继承关系
- 子类重写父类方法
- 父类引用过 指向子类对象
注意:多态是方法的多态,属性没有多态性。
instanceof 类型转换(引用类型)
instanceof判断一个对象时什么类型
9.抽象类abstract 修饰符可以用来修饰方法也可以修饰类,如果修饰方法,那么该方法就是抽象方法;如果修饰类,该类就是抽象抽象类。
抽象类中可以没有抽象发方法,但是有抽象方法的类一定要声明为抽象类。
抽象类,不能用 new 关键字来创建,它使用来让子类继承的。
抽象方法,只有方法的声明,没有方法的实现,它是用来让子类实现的。
子类继承抽象类,那么就必须实现抽象类中没有实现的抽象方法,否则该子类也被声明为抽象类。
10.接口普通类:只有具体实现。
抽象类:具体实现和规范(抽象方法)都有。
接口:只有规范!自己无法写方法 专业的约束 约束和实现的分离:面向接口编程。
接口就是规范,定义的是一组规则,体现了现实世界中“如果你是…则必须能…”的思想。如果你是天使,则必须能飞。如果你是汽车,则必须能跑。如果你是好人,则必须干掉坏人。如果你是坏人,则必须欺负好人。
接口的本质是锲约,就像我们人间的分人间的方法一样,制定好后大家都遵守。
OO的精髓,是对对象的抽象,最能体现这一点的就是接口。为什么我们讨论设计模式都能只针对具备抽象能力的语言(比如C++、Java、C#等),就是因为设计模式所研究的,实际上就是如何合理的去抽象。
声明类的关键字是class,声明接口的关键字是interface。
只有一个方法的接口叫做函数式接口,可以使用lambba表达式简化。
11.内部类内部类就是在以类的内部再定义一个类,比如,A类中定义一个B类,那么B类相对A类来说就称为内部类,而A类相对于B类就称为外部类。
- 成员内部类
- 静态内部类
- 局部内部类
- 匿名内部类
Exception
1.什么是异常异常指程序运行中出现的不期而至的各种情况,如:文件找不到、网络连接失败、非法参数等。
异常发生在程序运行期间,它影响了正常的程序执行流程。
异常处理框架
简单分类:
三种类型的异常:
- 检查性异常:最具代表的检查性异常时用户错误或问题引起的异常,这是程序员无法预见的。
例如要打开一个不存在的文件时,一个异常就发生了,这些异常再编译时不能被简单地忽略。 - 运行时异常:运行时异常时可能被程序员避免的异常。与检查性异常相反,运行时异常可以再编译时被忽略。
1/0 ClassNotFound NullPoint UnKownType 下标越界异常 - 错误(error):错误就不是异常,而是脱离程序员控制的问题。错误再代码中通常被忽略。
例如,当栈溢出时,一个错误就产生了,它们在编译也检查不出来。
AWT错误 和 JVM错误
JVM错误 StackOverFlow(栈溢出) OutOfMemory(内存溢出)
- Java把无序当作对象来处理,并定义一个基类 java.lang.Throwable 作为所有异常类的超类。
- 在 Java API 中已经定义了许多异常,这些异常分为两大类,错误 Error 和 异常 Exception。
Error类对象由Java虚拟机生成并抛出,大多数错误与代码编写者所执行的操作无关。
Java虚拟机运行错误(Virtual Machine Error),当JVM不再有继续执行操作所需的内存资源时,将出现OutOfMemoryError,Java虚拟机(JVM)一般会选择线程终止。
还有发生在虚拟机试图执行应用时,如类定义错误(NoClassDefFoundError)、链接错误(linkageError)。这些错误时不可查的,因为它们在应用程序的控制和处理能力之外,而且绝大多数是程序运行时不允许出现的状况。
4.Exception在Exception分支有一个重要的子类RuntimeException(运行时异常)
- ArrayIndexOutOfBoundsException 数组下标越界
- NullPointerException 空指针异常
- ArithmeticException 算术异常
- MissingResourceException 丢失资源
- ClassNotFoundException 找不到类异常 等异常,这些异常时不检查异常,程序中可以选择捕获处理,也可以不处理。
这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。
Error 和exception 的区别:
- Error通常是灾难性的致命的错误,是程序无法控制和处理的,当出现这些异常时,Java虚拟机一般会选择终止线程;
- Exception通常情况下是可以被程序处理的,并且在程序中应该尽可能的去处理这些异常。
抛出异常
捕获异常
异常处理五个关键字
try、catch、finally、throw、throws
使用Java内置的异常类可以描述子啊编程时出现的大部分异常情况。除此之外,用户还可以自定义异常。用户自定义异常类,只需继承Exception类即可。
在程序中使用自定义异常类,大体可以一下几个步骤:
- 创建自定义异常类
- 在方法中通过throw关键字抛出异常对象。
- 如果在当前异常的方法中处理异常,可以使用 try-catch 语句捕获处理;否则在方法的声明处通过 throws 关键字指明要抛出给要调用者的异常,继续进行下一步操作。
- 再出现异常方法的调用者中捕获并处理异常。
处理运行时异常时,采用逻辑区合理规避同时辅助 try-catch 处理
在多重 catch 块后面,可以加一个 catch(Exception e) 来处理可能会被遗漏的异常
对于不确定的代码,也可以加上 try-catch 处理潜在的异常
尽量去处理异常,切忌只是简单地调用 printStackTrace()去打印输出
具体如何处理异常,要根据不同的业务需求和异常类型去决定
尽量添加finally语句块去释放占用的资源
代码案例还没补充完整



