1.jdk的下载
-
通过官方网站获取
2.Notepad++7.7 /64位下载地址:
提取码:rjqv
快捷语法
psvm
public static void main(String[] args) { }
sout
System.out.println();
注释
单行注释
//单行注释
多行注释
/* */ 多行注释
文档注释
/**加回车
/** * */
有趣的代码注释
标识符
标识符:就是给类、方法、变量等起名字的符号
标识符的定义规则
-
由数字、字母、下划线(_)和美元符($)组成
-
不能以数字开头
-
不能是关键字
-
区分大小写
关键字
abstract | assert | boolean | break | byte |
---|---|---|---|---|
case | catch | char | class | const |
continue | default | do | double | else |
enum | extends | final | finally | float |
for | goto | if | implements | import |
instanceof | int | interface | long | native |
new | package | private | protected | public |
return | strictfp | short | static | super |
switch | synchronized | this | throw | throws |
transient | try | void | volatile | while |
标识符注意点
-
所有的标识符都应该以字母大小写(A-Z或a-z),美元符($),或者下划线(_)开始
//合法 String AHello = "李世民"; String hello = "李世民"; String $hello = "李世民"; String _hello = "李世民"; //不合法 String 1hello = "李世民"; String #hello = "李世民"; String *hello = "李世民";
-
首字符之后可以是字母大小写(A-Z或a-z),美元符($),下划线(_)或数字的任何字符组合
-
不能使用关键字作为变量名或者方法名
-
标识符是大小敏感的
-
可以用中文或者拼音,但是不建议,很low
常见命名约定
小驼峰命名法:一般用于方法和变量
-
约定1:标识符是一个单词的时候,首字母小写
-
范例1:name
-
约定2:标识符由多个单词组成的时候,第一个单词首字母小写,其他单词首字母大写
-
范例2:firstName
大驼峰命名法:一般用于类
-
约定1:标识符是一个单词的时候,首字母大写
-
范例1:Student
-
约定2:标识符由多个单词组成的时候,每个单词首字母大写
-
范例2:GoodStudent
单位
-
位(bit):是计算机内部数据储存的最小单位,11001100是一个八位二进制数
-
字节(byte):是计算机中数据处理的基本单位,习惯上用大写字母B表示
-
字符:是指计算机中使用的字母、数字、字和符号
1bit表示1位
1Byte表示一个字节
1B = 8bit
1024B = 1KB
1024KB = 1M
1024M = 1G
数据类型
基础类型(primitive type)
数值类型
整数类型(整数)
-
byte占1个字节范围:-128~127
-
short占2个字节范围:-32768~32767
-
int占4个字节范围:-2147483648~2147483647
-
byte占1个字节范围:-9223372036854775808~9223372036854775807
public static void main(String[] args) { //整数扩展 进制 二进制0b 八进制0 十进制 十六进制0x int i4 = 010; //二进制 binary int i = 10; //十进制 decimal int i2 = 010; //八进制 octal int i3 = 0x10; //十六进制 hex System.out.println(i); System.out.println(i2); System.out.println(i3); System.out.println(i4); }
浮点类型(小数)
-
float占4个字节
-
double占8个字节
浮点数拓展
银行业务怎么表示
BigDecimal 数学工具类
float 有限 离散 舍入误差 大约 接近但不等于
double
最好完全避免 使用浮点数进行比较
public static void main(String[] args) { //浮点数扩展 float f = 0.1f; double d = 1.0/10; System.out.println(f==d); //false float d1 = 232323f; float d2 = 232323f; System.out.println(d1==d2); //true }
字符类型(文字)
-
char占个字节
public static void main(String[] args) { //字符拓展 char c1 = 'a'; char c2 = '中'; System.out.println(c1); System.out.println((int)c1); //强制转换 System.out.println(c2); System.out.println((float) c2); //强制转换 //所有的字符本质还是数字 //编码 Unicode }
转义字符
boolean类型
-
占1位,其值只有true和false两个
public class Day02 { public static void main(String[] args) { //八大基本数据类型 //整数 int num1 = 10; //最常用 byte num2 = 20; short num3 = 30; long num4 = 40L; //long类型要在数字后面加个L //小数;浮点数 float num5 = 10.1F; //float类型要在数字后面加个F double num6 = 3.014159264561231651; //字符 char name= 'A'; //字符只有一个字或一个字母 //字符串 String不是关键字,是一个类 String name1 = "李世民"; //布尔值 是非 boolean flag = true; boolean flag1 = false; } }
引用类型(reference type)
-
类
-
接口
-
数组
类型转换
-
由于Java是强类型语言,所以要进行有些运算的时候,需要用到类型转换
优先级
低———————————————————————>高
byte,short,char —> int —> long —> float —> double
-
运算中,不同类型的数据先转换为同一类型,然后进行运算
强制类型转换
把一个表示数据范围大的数值或者变量赋值给另一个表示数据范围小的变量(可以做但不建议,会造成数值的丢失)
-
格式:目标数据类型 变量名 = (目标数据类型)值或变量
高————>低 public static void main(String[] args) { //强制转换 (类型)变量名 int i = 120; byte b = (byte)i; }
自动类型转换
把一个表示数据范围小的数值或变量赋值给另一个表示数据范围大的变量
低————>高 public static void main(String[] args) { //自动转换 int i = 120; double d = i; //这是不可以的,类型不兼容 byte b = 10; char c = b; }
溢出问题
public static void main(String[] args) { //操作比较大的数的时候,注意溢出问题 //JDK7新特性,数字之间可以用下划线分割 int money = 10_0000_0000; int years = 20; int total = money*years; //-1474836480,计算的时候溢出了 long total2 = money*years;//默认是int,转换之前已经存在问题了 long total3 = money*((long)years);//先把一个数转换为long System.out.println(total); System.out.println(total2); System.out.println(total3); }
注意点
-
不能对布尔值进行转换
-
不能把对象类型转换为不相干的类型
-
在把高容量转换到低容量的时候,强制转换
-
转换的时候可能存在内存溢出,或者精度问题
变量
-
变量是可以变化的量
-
Java是一种强类型语言,每个变量都必须声明其类型
-
Java变量是程序中最基本的储存单元,其要素包括变量名、变量类型和作用域
-
数据类型 变量名 =值;
-
可以使用逗号隔开来生命多个同类型变量
public static void main(String[] args) { int a=1,b=2,c=3; String name = "liu"; char x = 'x'; double p = 3.14; }
实例变量
-
实例变量:从属对象;如果不自行初始化,这个类型的默认值是0
-
布尔值:默认是flase
-
除了基本类型,其余的默认值都是null
public class Day07 { String name; int age; //main方法 public static void main(String[] args) { //变量类型 变量名字 = new Day08(); Day07 day07 = new Day07(); System.out.println(day07.age); System.out.println(day07.name); } }
局部变量
public class Day07 { //main方法 public static void main(String[] args) { //局部变量,必须声明和初始化值 int i = 10; System.out.println(i); } }
类变量
static 变量类型 变量名 = 值;
public class Day07 { //类变量 static double salary = 2500; //main方法 public static void main(String[] args) { //类变量 tatic System.out.println(salary); } }
注意点
-
每个变量都有类型,类型可以是基本类型,也可以是引用类型
-
变量名必须是合法的标识符
-
变量声明是一条完整的语句,因此每一个变量声明都必须以分号结束
-
变量名不能重复
-
变量未赋值,不能使用
-
long类型的变量定义的时候,防止整数过大,后面要加L
-
float类型的变量定义的时候,为了防止类型不兼容,后面要加F
变量的命名规范
-
所有的变量、方法、类名:见名知意
-
类成员变量:首字母小写和驼峰原则:monthSalary
-
局部变量:首字母小写和驼峰原则
-
常量:大写字母和下划线:MAX_VALUE
-
类名:首字母大写和驼峰原则:Man,GoodMan
-
方法名:首字母小写和驼峰原则:run(),runRun()
-
驼峰原则:除第一个单词意外,后面的单词首字母大写
常量
-
常量(Constant):初始化(initialize)后不能再改变值!不会变动的值
-
所谓常量可以理解成一种特殊的变量,它的值被设定后,在程序运行过程中不允许改变
-
常量名一般使用的大写字符
final 常量名 = 值;
final double PI=3.14;
public class Day08 { //修饰符,不存在先后顺序 static final double PI = 3.14; final static double PI2 = 3.14; public static void main(String[] args) { System.out.println(PI); System.out.println(PI2); } }
常量分类
-
字符串常量:用双引号括起来的内容。“HelloWorld”,”黑马程序员“
-
整型常量:不带小数的数字。666,-88
-
小数常量:带小数的数字。3.14,-5.12
-
字符常量:用单引号括起来的内容。’A‘ ,‘0’,‘我’
-
布尔常量:布尔值,表示真假。true,false
-
空常量:一个特殊的直,空值。null
运算符
Java语言支持以下运算符
名称 | 符号 |
---|---|
算数运算符 | +,-,*,/,%(取余),++,-- |
赋值运算符 | = |
关系运算符 | <,>,>=,<=,==,!=instanceof(不等于) |
逻辑运算符 | &&(与),||(或),!(非),^(异或) |
位运算符(了解) | &,!,^,~,>>,<<,>>> |
条件运算符 | ?: |
扩展赋值运算符 | +=,-=,*=。/= |
算数运算符
public static void main(String[] args) { //二元运算符 //ctrl + d 复制当前行到下一行 int a = 10; int b = 20; int c = 30; int d = 40; System.out.println(a+b); System.out.println(a-b); System.out.println(a*b); System.out.println(a/(double)b); //整数相除只能得到整数,要想得到小数,必须有浮点数 System.out.println(6.0 / 4); }
public static void main(String[] args) { long a = 1235431654L; int b = 123; short c = 10; byte d = 8; System.out.println(a+b+c+d); //long System.out.println(b+c+d); //int System.out.println(c+d); //int }
public static void main(String[] args) { //关系运算符返回的结果:正确,错误 布尔值 int a = 10; int b = 20; int c = 21; System.out.println(a>b); //false System.out.println(a<b); //true System.out.println(a==b); //false System.out.println(a!=b); //true System.out.println(c%a); // 21/10=2......1 结果为余数1 }
自增自减运算符
public static void main(String[] args) { //++ -- 自增,自减 一元运算符 int a = 3; int b = a++; //执行完这行代码后,先给b赋值,再自增 //a++ 即 a = a + 1 int c = ++a; //执行完这行代码前,先自增,再给c赋值 System.out.println(a); System.out.println(b); System.out.println(c); //幂运算 2^3 即 2*2*2=8 很多运算,我们会使用一些工具类来操作 double pow = Math.pow(2,3); System.out.println(pow); }
逻辑运算符
public static void main(String[] args) { //逻辑运算符 //与(and) 或(or) 非(取反) boolean a = true; boolean b = false; System.out.println("a && b:"+(a&&b)); //逻辑与运算:两个变量都为真,结果才为true System.out.println("a || b:"+(a||b)); //逻辑与运算:两个变量有一个为真,结果才为true System.out.println("!(a && b):"+!(a&&b)); //如果是真,则为假,如果是假则变为真 //短路运算 int c = 5; boolean d = (c<4)&&(c++<4); //一开始(c<4)是错的,c++不执行 System.out.println(d); System.out.println(c); }
扩展赋值运算符
public static void main(String[] args) { int a = 10; int b = 20; a+=b; //a=a+b a-=b; //a=a-b System.out.println(a); //字符串连接符 + // ""默认为String类型 // ""在最后不计算,在其余位置参与计算 System.out.println(""+a+b); System.out.println(a+""+b); System.out.println(a+b+""); }
条件运算符
public static void main(String[] args) { //三元运算符 // x ? y : z //如果x==true,则结果为y //如果x==false,则结果为z int score = 50; String type = score <60 ?"不及格":"及格"; System.out.println(type); }
案例
/* 两只老虎 需求: 动物园里有两只老虎,已知两只老虎的体重分别为160kg、200kg 请用程序实现判断两只老虎的体重是否相同 */ public class hello{ public static void main(String[] args) { //1:定义两个变量用于保存老虎的体重,单位为kg,这里仅仅体现数值即可 int weight1 = 160; int weight2 = 200; //2:用三元运算符实现老虎体重的判断,体重相同,返回true,否则,返回false boolean b = weight1 == weight2 ? true : false; //3:输出结果 if(b = true){ System.out.println("两只老虎的体重相同"); }else{ System.out.println("两只老虎的体重不相同"); } } }
/* 三个和尚 需求: 一座寺庙里住着三个和尚,已知他们的身高分别为150cm,210cm,165cm 请用程序实现获取这三个和尚的最高身高 */ public class hello{ public static void main(String[] args) { //1:定义三个变量用于保存和尚的身高,单位为cm,这里仅仅体现数值即可 int height1 = 150; int height2 = 210; int height3 = 165; //2:用三元运算符获取两个和尚的较高身高值,并用临时身高变量保存起来 int tempHeight = height1 > height2 ? height1 : height2; //3:用三元运算符获取临时身高和第三个和尚的身高值较高值,并用最大身高变量保存起来 int maxHeight = tempHeight > height3 ? tempHeight : height3; //4:输出结果 System.out.println("最高身高为" + maxHeight); } }
包机制
-
为了更好地组织类,Java提供了包机制,用于区别类名的命名空间
-
包语法的语法格式为:
package pkg1.pkg2.pkg3......;
例:
package src.operator;
-
一般利用公司域名倒置作为包名
-
为了能够使用某一个包的成员,我们需要在Java程序中明确导入该包。使用”import“语句可完成此功能
import package1.....
例:
import src.base.Day01;导入所有的包用"*"
import src.base.*;
JavaDoc
-
javadoc命令是用来生成自己的API文档
参数信息
-
@author
-
@version 版本号
-
@since 指明需要最早使用的jdk版本
-
@param 参数名
-
@return 返回值情况
-
@throws 异常抛出情况
-
用于文档注释
/** * @author * @version * @since * @param * @return * @throws */
Java流程控制
Scanner对象
Scanner使用的基本步骤
//1:导包 import java.util.Scanner; //导包的动作必须出现在类定义的上边 //2:创建对象 Scanner sc = new Scanner(System.in); //上面这个格式里面,只有sc是变量名,可以变,其他的都不允许变 //3:接收数据 int i = sc.nextInt(); //上面这个格式里面,只有i是变量名,可以变,其他的都不允许变
-
我们可以通过Scanner类来获取用户的输入
-
基本语法
Scanner s = new Scanner(System.in);
-
通过Scanner类的next()与nextLine()方法获取输入的字符串
-
在读取前我们一般需要使用hasNext()与hasNextLine()判断是否还有输入的数据
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(); }
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); } //凡是属于IO流的类若果不关闭会一直占用资源,要养成好习惯用完就关掉 scanner.close(); }
nextLine方法
-
以Enter为结束符,也就是说nextLine方法返回的是输入回车之前的所有字符
-
可以获得空白
public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("使用next方法接收:"); //判断用户没有输入字符串 if (scanner.hasNext()) { //使用nextLine方法接收 String str = scanner.nextLine(); //程序等待用户输入完毕 System.out.println("输出的内容为:" + str); } //凡是属于IO流的类若果不关闭会一直占用资源,要养成好习惯用完就关掉 scanner.close(); }
案例
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 + 1; sum = sum + x; } System.out.println(m + "个数的和为" + sum); System.out.println(m + "个数的平均值是" + (sum / m )); scanner.close(); }
/* 三个和尚 需求: 一座寺庙里住着三个和尚,他们的身高必须经过测试得出, 请用程序实现获取这三个和尚的最高身高 */ import java.util.Scanner; public class hello{ public static void main(String[] args) { //身高未知,采用键盘录入实现,首先导包,然后创建对象, Scanner sc = new Scanner(System.in); //键盘录入三个身高分别赋值给三个变量 System.out.println("请输入第一个和尚的身高"); int height1 = sc.nextInt(); System.out.println("请输入第二个和尚的身高"); int height2 = sc.nextInt(); System.out.println("请输入第三个和尚的身高"); int height3 = sc.nextInt(); //用三元运算符获取前两个和尚的较高身高值,并用临时身高变量保存起来 int tempHeight = height1 > height2 ? height1 : height2; //用三元运算符获取临时身高值和第三个和尚的身高值较高值,并用最大身高变量保存起来 int maxHeight = tempHeight > height3 ? tempHeight : height3; //4:输出结果 System.out.println("最高身高为" + maxHeight); } }
顺序结构
-
Java的基本结构就是顺序结构,除非特别指明,否则就按照顺序从上到下一句一句依次执行
-
顺序结构是最简单的算法结构
-
它是任何一个算法都离不开的一种基本算法结构
选择结构
if单选择结构
-
我们很多时候需要去判断一个东西是否可行,然后我们才去执行,这样一个过程在程序中用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("Hello,World!"); } scanner.close(); }
if双选择结构
-
我们需要有两个判断,需要一个双选择结构,所以就有了 if—else 结构
-
语法
if(布尔表达式){
//如果布尔表达式为true将执行的语句
}else{
//如果布尔表达式为false将执行的语句
}
public static void main(String[] args) { //考试分数大于60就是及格,小于60分就不及格 Scanner scanner = new Scanner(System.in); System.out.println("请输入成绩:"); int score = scanner.nextInt(); if (score>=60){ System.out.println("及格"); }else { System.out.println("不及格"); } scanner.close(); }
if多选择结构
-
在生活中我们很多时候的选择也不仅仅只有两个,所以我们需要一个多选择结构来处理这类问题!
-
语法
if(布尔表达式 1){
//如果布尔表达式 1的值为true将执行的语句
}else if(布尔表达式 2){
//如果布尔表达式 2的值为true将执行的语句
}else if(布尔表达式 3){
//如果布尔表达式 3的值为true将执行的语句
}else{
//如果布尔表达式为false将执行的语句
}
public static void main(String[] args) { //考试分数大于60就是及格,小于60就是不及格 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("优秀"); }else if (score<90 && score>=60){ System.out.println("及格"); }else if (score<60 && score>=0){ System.out.println("不及格"); }else{ System.out.println("请输入正确分数"); } scanner.close(); }
嵌套的if结构
-
使用嵌套的 if....else 语法是合法的。也就是说你可以在另一个 if 或者 else if 语句中使用 if 或者 else if 语句。你可以像使用 if 语句一样嵌套 else if...else。
-
语法
if(布尔表达式 1){
//如果布尔表达式 1的值为true将执行的语句
if(布尔表达式 2){
//如果布尔表达式 2的值为true将执行的语句
}
}
案例
考试奖励
/* 考试奖励 需求 小明快期末考试了,小明爸爸对他说,会根据他不同的考试成绩,送他不同的礼物,假如你可以控制小明的得分, 请用程序实现小明到底该获得什么样的礼物,并在控制台输出 奖励: 95-100 山地自行车一辆 90-94 游乐场玩一次 80-89 变形金刚玩具一个 80以下 胖揍一顿 */ import java.util.Scanner; public class hello{ public static void main(String[] args) { //小明的考试成绩未知,可以使用键盘录入的方式获取值 Scanner sc = new Scanner(System.in); System.out.println("请输入一个分数(0-100)"); int score = sc.nextInt(); //由于奖励种类较多,属于多种判断,采用if...else...if格式实现 //为每种判断设置对应的条件 //为每种判断设置对应的奖励 if(score >=95 && score <= 100){ System.out.println("山地自行车一辆"); }else if(score >=90 && score <= 94){ System.out.println("游乐场玩一次"); }else if(score >=80 && score <= 89){ System.out.println("变形金刚玩具一个"); }else if(score >=0 && score <= 79){ System.out.println("胖揍一顿"); }else{ System.out.println("数据不存在"); } } }
switch多选择结构
-
多选择结构还有一个实现方式就是 switch case 语句
-
switch case 语句判断一个变量与一系列值中某个值是否相等,每个值成为一个分支
-
switch 语句中的变量类型意义是
byte、short、int或者char
从 Java SE 7 开始
switch 支持字符串 String 类型
同时 case 标签必须为字符串常量或字面量
-
语法:
switch (expression){ case value : //语句 break; //可选 case value : //语句 break; //可选 //你可以有任意数量的case语句 default: //可选 //语句 }
public static void main(String[] args) { char grade = 'B'; switch (grade){ case 'A' : System.out.println("优秀"); break; case 'B': System.out.println("良好"); case 'C': System.out.println("及格"); case 'D': System.out.println("不及格"); default: System.out.println("未知等级"); } }
循环结构
while循环
-
while 是最基本的循环,他的结构为:
while( 布尔表达式){
//循环内容
}
-
只要布尔值为true,循环就会一直执行下去
-
我们大多数情况是会让循环停止下来的,我们需要一个让表达式失效的方式来结束循环
-
少部分情况需要循环一直执行下去,比如服务器的请求响应监听等
-
循环条件一直为true就会造成无限循环【死循环】。我们正常的业务编程中应该尽量避免死循环。会影响程序性能或者造成程序卡死崩溃
public static void main(String[] args) { //输出1~100 int i = 0; while (i<100){ i++; System.out.println(i); } }
public static void main(String[] args) { //死循环 while (true){ System.out.println(1); //等待客户端链接 //定时检查 //。。。。。 } }
public static void main(String[] args) { //计算1+2+3+4+.... int i = 0; int sum = 0; while (i<=100){ sum = sum + i; i++; } System.out.println(sum); }
//for与while对照 public class hello{ public static void main(String[] args) { //输出5次“hello” for(int i = 1 ; i <= 5; i++){ System.out.println("Hello"); } System.out.println("--------------"); int j = 1; while(j<=5) { System.out.println("Hello"); j++; } } }
案例
需求:世界最高峰珠穆朗玛峰(8844.43米=8843430毫米),假如我有一张足够大的纸,它的厚度是0.1毫米。
请问,我折叠多少次可以折成珠穆朗玛峰的高度?
public class hello{ public static void main(String[] args) { //定义一个计数器,初始值位为 int count = 0; //定义纸张厚度 double paper = 0.1; //定义珠穆朗玛峰高度 int zf = 8844430; //因为要反复折叠,所以使用循环,但是不知道折叠多少次。这种情况下更适合使用while循环 //折叠的过程中当纸张厚度大于珠峰就停止了,因此继续执行的要求是纸张厚度小于珠峰高度 while(paper <= zf) { //循环的执行过程中每次纸张折叠,纸张的厚度要加倍 paper *=2; //在循环中执行累加,对应折叠多少次 count++; } //打印计数器的值 System.out.println("需要折叠:"+count+"次"); } }
do....while 循环
-
对于 while 语句而言,如果不满足条件,就不能进入循环。但有时候我们需要即使不满足条件,也至少执行一次
-
do...while 循环和 while 循环相似,不同的是,do...while循环至少会执行一次
do {
//代码语句
}while(布尔表达式);
-
While和do...While的区别
-
while先判断后执行;do...While是先执行后判断
-
do...While总是保证循环体会被至少执行一次!这是他们的主要差别
-
public class hello{ public static void main(String[] args) { //需求:在控制台输出5次“HelloWorld" //for循环实现 for(int i=1; i<=5; i++) { System.out.println("HelloWorld"); } System.out.println("——————————————"); //do...while循环实现 int j = 1; do { System.out.println("HelloWorld"); j++; }while(j<=5); } }
for循环
-
虽然所有循环结构的可以用 while 或者 do...while 表示,但Java提供了 for 循环,是一些结构更加简单
-
for循环语句是支持迭代的一种通用结构,是最有效,最灵活的循环结构
-
for循环执行的次数是在执行前就确定的
for(初始化;布尔表达式;更新){
//代码语句
}
public static void main(String[] args) { for (int a = 1;a<=100;a++){ System.out.println(a); } System.out.println("for循环结束"); }
//死循环 for (;;){ //程序语句 }
public static void main(String[] args) { //练习一:计算0到100之间的奇数和偶数的和 int oddSum = 0; //奇数 int evenSum = 0; //偶数 for (int i = 0;i < 100;i++){ if (i%2!=0){ oddSum+=i; }else { evenSum+=i; } } System.out.println("奇数的和"+oddSum); System.out.println("偶数的和"+evenSum); }
public static void main(String[] args) { //练习二:用while或for循环输出1~1000之间能被5整除的数,并且每行输出3个 for (int i = 0; i <= 1000; i++) { if (i%5==0){ System.out.print(i+"\t"); } if (i%(5*3)==0){ //换行 System.out.println(); } } }
public static void main(String[] args) { //打印九九乘法表 for (int i = 1; i <= 9; i++) { for (int a = 1; a <= i; a++) { System.out.print(i+"*"+a+"="+(a*i)+"\t"); } System.out.println(); } }
增强for循环
-
语法
for(声明语句:表达式){
//代码句子
}
public static void main(String[] args) { //增强for循环 //遍历数组 int[] number = {1,2,3,4,5,6}; for (int x:number){ System.out.println(x); } }
案例
/* 水仙花 需求 在控制台输出所有的“水仙花数” 请用程序实现 */ public class hello{ public static void main(String[] args) { //输出所有的水仙花数必然要使用到循环,遍历所有的三位数,三位数从100开始,到999结束 for(int i = 100 ; i < 1000 ; i++){ //在计算之前获取三位数中每个位上的值 int ge = i%10; int shi = i/10%10; int bai = i/10/10%10; //判定条件是将三位数中的每个数值取出来,计算立方和后与原始数字比较是否相等 if(ge*ge*ge + shi*shi*shi + bai*bai*bai == i){ //输出满足条件的数字就是水仙花数 System.out.println(i); } } } }
三种循环的区别
/* 三种循环的区别 */ public class hello{ public static void main(String[] args) { //需求:在控制台输出5次“HelloWorld" //for循环实现 //先做条件判断,再执行循环体 for(int i=1; i<=5; i++) { System.out.println("HelloWorld"); } System.out.println("——————————————"); //while循环实现 //先做条件判断,再执行循环体 int k = 1; while(k<=5) { System.out.println("HelloWorld"); k++; } System.out.println("——————————————"); //do...while循环实现 //先执行循环体,再做条件判断 int j = 1; do { System.out.println("HelloWorld"); j++; }while(j<=5); } }
死循环
public class hello{ public static void main(String[] args) { //for循环实现 for(;;) { System.out.println("for"); } //while循环实现 while(true) { System.out.println("while"); } //do...while循环实现 do { System.out.println("do...while"); }while(true); } }
跳转控制语句
-
break在任何循环语句的主体部分,均可用break控制循环的流程。break用于强行退出循环,不执行循环中剩下的语句。(break语句也在switch语句中使用)
public class hello{ public static void main(String[] args) { for(int i=1; i<=5; i++){ if(i%2 == 0){ break; } System.out.println(i); } } } //结果:1
-
continue语句用在循环语句中,用于终止某次循环过程,即跳过循环体中尚未执行的语句,接着进行下一次是否执行循环的判定
public class hello{ public static void main(String[] args) { for(int i=1; i<=5; i++){ if(i%2 == 0){ continue; } System.out.println(i); } } } //结果:1 3 5
goto关键字
-
goto关键字很早就在程序设计语言中出现,尽管goto仍是Java的一个表刘子,但并未在语言中得到正式使用:Java没有用goto。然而,在break和continue这两个关键字的身上,我们仍能看到一些goto的影子——带标签的break和continue。
-
“标签”是指后面跟一个冒号的标识符,例如:label:
-
对于Java来说唯一用到标签的地方是在循环语句之前,而在循环之前设置标签的唯一理由是:我们希望在其中嵌套另一个循环,由于break和continue关键字通常只中断当前循环,但若随同标签使用,他们就会中断到存在标签的地方
public static void main(String[] args) { //打印101~150之间的质数 //质数是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。 int count = 0; //了解 outer:for (int i=101;i<150;i++){ for (int j = 2;j<i;j++){ if (i % j == 0){ continue outer; } } System.out.print(i+"\t"); } }
Random
Random的作用和使用步骤
作用:用于产生一个随机数
使用步骤:
//①导包 import java.util.Random; //导包的动作必须出现在类定义的上面 //②创建对象 Random r = new Random(); //上面这个格式里面,r是变量名,可以变,其他的都不允许变 //②获取随机数 int number = r.nextInt(10); //获取数据的范围:[0,10) 包括0,不包括10 //上面这个格式里面,number是变量名,可以变,数字10可以变,其他的都不允许变
import java.util.Random; public class hello{ public static void main(String[] args) { //创建对象 Random r = new Random(); //用循环获取10个随机数 for(int i=0; i<10; i++) { //获取随机数 int number = r.nextInt(10); System.out.println("number:" + number); } //需求:获取一个1-100之间的随机数 int x = r.nextInt(100) + 1; System.out.println(x); } }
案例
猜数字
需求:程序自动生成一个1~100之间的数字,使用程序实现猜出这个数字是多少?
当猜错的时候根据不同情况给出相应的提示
-
如果猜的数字比真实数字大,提示你猜的数据大了
-
如果猜的数字比真实数字小,提示你猜的数据小了
-
如果才的数字比真实数字相等,提示恭喜你猜中了
import java.util.Random; import java.util.Scanner; public class hello{ public static void main(String[] args) { //要完成猜数字的游戏,首先需要有一个要猜的数字,使用随机数生成该数字,范围1到100 Random r = new Random(); int number = r.nextInt(100) + 1; while(true) { //使用程序实现猜数字,每次均要输入猜测的数字值,需要使用键盘录入实现 Scanner sc = new Scanner(System.in); System.out.println("请输入你要猜的数字:"); int guessNumber = sc.nextInt(); //比较输入的数字和系统产生的数据,需要使用分支语句。 if(guessNumber > number) { System.out.println("你猜的数字" + guessNumber + "大了"); }else if(guessNumber < number) { System.out.println("你猜的数字" + guessNumber + "小了"); }else{ System.out.println("恭喜你猜中了"); break; } } } }
练习题
-
打印三角形
public static void main(String[] args) { //打印三角形 5行 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个功能,这样利于我们后期的扩展
public class 方法 { //main方法 public static void main(String[] args) { // int sum = add(1,2); // System.out.println(sum); test("#"); } //加法 public static int add(int a,int b){ return a+b; } public static void test(String a){ Scanner scanner = new Scanner(System.in); String s = scanner.nextLine(); a=s; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { System.out.print(a); } System.out.println(); } } }
方法的定义
-
Java的方法类似于其它语言的函数,是一段用来完成特定功能的代码片段,一般情况,定义一个方法包含一下语法
-
方法包含一个方法头和一个方法体,下面是一个方法的所有部分
-
修饰符:修饰符,这是可选的,告诉编译器如何调用该方法。定义了该方法的访问类型
-
返回值类型:方法可能会返回值。returnValueType是方法返回值的数值类型。有些方法执行所需的操作,但没有返回值。在这种情况下,returnValueType是关键字void
-
方法名:是方法的实际名称,方法名和参数表共同构成方法签名。
-
参数类型:参数像是一个占位符。当方法被调用时,传递值给参数,这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。
-
形式参数:在方法被调用时用于接收外界输入的数据
-
实参:调用方法时实际传给方法的数据
-
-
方法体:方法体包含具体的语句,定义该方法的功能
-
修饰符 返回值类型 方法名(参数类型 参数名){
......
方法体
......
return 返回值;
}
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; //方法体 }
public static void main(String[] args) { //实际参数:实际调用传递给他的参数 max(1,2); } //比大小 //形式参数,用来定义作用的 public static int max(int num1,int num2){ int result; if (num1>num2){ result = num1; System.out.println(result); //方法体 }else { result = num2; System.out.println(result); } return result; //return 返回值; }
方法调用
-
调用方法:对象名.方法名(实参列表)
-
Java支持两种调用方法的方式,根据方法是否返回值来选择
-
当方法返回一个值的时候,方法调用通常被当做一个值。例如:
int larger = max(30,40);
-
如果方法返回值是void,方法调用一定是一条语句。
System.out.println("Hello,world!");
//学生类 public class Student { //静态方法 //static 和类一起加载 public static void say(){ System.out.println("说话"); } //动态方法 //类实例化之后才存在 public void nosay(){ System.out.println("不说话"); } }
public class 方法调用 { public static void main(String[] args) { //静态方法调用 Student.say(); //动态方法调用 //实例化这个类 new //对象类型 对象名 = 对象值; Student student = new Student(); student.nosay(); } }
带返回值的调用
/* * 定义格式 * public static 数据类型 方法名(参数) { * return 数据; * } * * 调用格式 * 1、方法名(参数) * 2、数据类型 变量名 = 方法名(参数) * */ public class 带返回值的方法调用 { public static void main(String[] args) { //1、方法名(参数) //a(10); //2、数据类型 变量名 = 方法名(参数) boolean flag = a(10); System.out.println(flag); } public static boolean a(int number) { if (number%2 == 0){ return true; } else { return false; } } }
//获取两个数中的较大值 public static void main(String[] args) { int flag = max(10,20); System.out.println(flag); } public static int max(int a,int b) { if (a > b){ return a; } else { return b; } }
方法的重载
-
重载就是在一个类中,有相同的函数名称,但形参不同的函数
-
方法的重载的规矩:
-
方法名称必须相同
-
参数列表必须不同(个数不同、或类型不同、参数排列顺序不同等)
-
方法的返回类型可以相同也可以不相同
-
仅仅返回类型不同不足成为方法的重载
-
-
实现理论:方法名称相同时,编译器会根据调用方法的参数个数、参数类型等去逐个匹配,以选择对应的方法,如果匹配失败。则编译器报错
public static void main(String[] args) { max(1,2); } //比大小 public static int max(int num1,int num2){ int result; if (num1>num2){ result = num1; System.out.println(result); }else { result = num2; System.out.println(result); } return result; } //比大小 public static double max(double num1,double num2){ double result; if (num1>num2){ result = num1; System.out.println(result); }else { result = num2; System.out.println(result); } return result; }
命令行传参
-
有时候你希望运行一个程序时候再传递给他消息。这要靠传递命令行参数给main()函数实现
可变参数
-
JDK1.5 开始,Java支持传递同类型的可变参数给一个方法
-
在方法声明中,在指定参数类型后加一个省略号(...)
-
一个方法中只能指定一个可变参数,他必须是方法的最后一个参数。任何普通的参数必须再它之前声明
public class 方法4 { public static void main(String[] args) { //调用可变参数的方法 printMax(34,1,2,5,3,5); 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 = 1; i < numbers.length; i++) { if (numbers[i]>result){ result = numbers[i]; } } System.out.println("The max value is " + result); } }
递归
-
A方法调用A方法,即自己调用自己
-
利用递归可以用简单的程序来解决一些复杂的问题,它通常把一个大型复杂的问题层层转化为一个于原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次计算,大大的减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合
-
递归结构包含两个部分
-
递归头:什么时候不调用自身方法。如果没有头,将陷入死循环
-
递归体:什么时候需要调用自身方法
-
public class 方法5 { 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数组
-
数组是相同类型数据的有序集合
-
数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成
-
其中,每个数据称作一个数组元素,每个数组元素可以通过一个下标来访问他们
数组声明创建
-
首先必须声明数组变量,才能在程序中使用数组。下面是声明数组变量的语法:
dataType[ ] arrayRefVar;
例:int[ ] a;
dataType arrayRefVar[ ];
例:int a[ ];
-
Java语言使用new操作符来创建数组,语法如下:
dataType[ ] arrayRefVar = new dataType[arraySize ]
-
数组的元素是通过索引访问的,数组索引从0开始
-
获取数组长度
public static void main(String[] args) { int[] nums; //定义 nums = new int[10]; //创建一个数组 //给数组赋值 nums[0] = 1; nums[1] = 2; nums[2] = 3; nums[3] = 321; nums[4] = 51; nums[5] = 1132; nums[6] = 120; nums[7] = 12124; nums[8] = 112; nums[9] = 21; // System.out.println(nums[9]); //计算所有元素的和 int sum = 0; //获取数组长度:arrays.length for (int i = 0; i < nums.length; i++) { sum = sum + nums[i]; } System.out.println("总和为"+sum); }
三种初始化
-
静态初始化:初始化时指定每个数组元素的初始值,由系统决定数组长度
/* 格式:数据类型[] 变量名 = new 数据类型[]{数值1,数值2,数值3,...}; 范例:int[] arr = new int[]{1,2,3}; 简化格式:数据类型[] 变量名 = {数值1,数值2,数值3,...}; 范例:int[] arr = {1,2,3}; */ int[] a = {1,2,3,4,5}; Man[] mans = {new Man(1,1),new Man(2,2)};
-
动态初始化:初始化时只指定数组长度,由系统为数组分配初始值
//格式:数据类型[] 变量名 = new 数据类型[数组长度]; //范例:int[] arr = new int[2]; /* 左边: int:说明数组中的元素类型是int类型 []:说明这是一个数组 arr:这是数组的名称 右边: new:为数组申请内存空间 int:说明数组中的元素类型是int类型 []:说明这是一个数组 3:数组长度,其实就是数组中的元素个数 */ //输出数组名 System.out.println(arr); //[I@6f496d9f //输出数组中的元素 System.out.println(arr[0]); //0 System.out.println(arr[1]); //0 System.out.println(arr[2]); //0 /* 数组在初始化时,会为存储空间添加默认值 整数:默认值是0 浮点数:默认值是0.0 布尔值:默认值是false 字符:默认值是空字符 引用数据类型:默认值是null */ arr[0] = 1; arr[1] = 2;
-
数组的默认初始化
-
数组是引用类型,它的元素相当于类的实例变量,因此数组一层分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化
-
public static void main(String[] args) { //静态初始化:创建 + 赋值 int[] a = {1,2,3,4,5}; //引用类型(先创建一个Man的class类) Man[] mans = {new Man(),new Man()}; //动态初始化:包含默认初始化 int[] a = new int[2]; a[0] = 1; a[1] = 2; System.out.println(Man[0]); }
数组元素访问
数组元素访问
-
数组变量访问方式
-
格式:数组名
-
数组内部保存的数据的访问方式
-
格式:数组名[索引]
-
索引是数组中数据的编号方法
-
作用:索引用于访问数组中的数据使用,数组名[索引]等同于变量名,是一种特殊的变量名
-
特征①:索引是从0开始的
-
特征②:索引是连续的
-
特征③:索引逐一增加,每次加1
遍历
public class 数组遍历 { public static void main(String[] args) { int[] arr = {11,22,33,44,5,6}; //使用通用的遍历格式 //arr.length表示数组的长度 for (int i = 0; i < arr.length; i++) { System.out.println(arr[i]); } } }
获取最大值
public static void main(String[] args) { //定义数组 int[] arr = {11,22,33,44,5,6}; //定义一个变量,用于保存最大值 //取数组中第一个数据作为变量的初始值 int max = arr[0]; //与数组中剩余的数据逐个比对,每次对比将最大值保存到变量中 for (int i = 0; i < arr.length; i++) { if (arr[i] > max) { max = arr[i]; } } //循环结束后打印变量的值 System.out.println(max); }
数组使用
-
普通for循环
-
for~each 循环
-
数组做方法入参
-
数组做返回值
多维数组
-
多维数组可以看成是数组的数组,比如二维数组就是个特殊的一维数组,其每一个元素都是一个一维数组
-
二维数组
int a[ ] [ ] = new int[2] [5];
-
解析:以上二维数组a可以看成一个两行五列的数组
Arrays类
-
数组的工具类java.util.Arrays
-
由于数组对象本身并没有什么方法可以供我们调用,但API中提供了一个工具类Arrays供我们使用,从而可以对数据对象进行一些基本的操作
-
查看JDK帮助文档
-
Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用,而“不用”使用对象来调用(注意“不用”而不是“不能”)
-
具有以下功能
-
给数值赋值:通过 fill 方法
-
对数组排序:通过 sort 方法,按升序
-
比较数组:通过 equals 方法比较数组中元素值是否相等
-
查找数组元素:通过 binarySearch 方法能对排序好德 数组进行二分查找法操作
-
冒泡排序
-
冒泡排序无疑是最为出名的排序算法之一,总共有八大排序
-
冒泡的代码还是相当简单的,两层循环,外层冒泡轮数,里层依次比较,江湖中人尽皆知。
-
我么会看到嵌套循环,应该立马就可以得出这个算法的时间复杂度为O(n2).
public class 冒泡排序 { //冒泡排序 //1、比较数组中,两个相邻的元素,如果第一个数比第一个数大,我们就交换他们的位置 //2、每一次比较,都会产生一个最大,或者最小的数字 //3、下一轮则可以少一次排序 //4、依次循环,直到结束 public static void main(String[] args) { int[] a = {1,856,11,653,21,32,23,21}; int[] sort = sort(a); System.out.println(Arrays.toString(sort)); } public static int[] sort(int[] array){ //临时变量 int temp = 0; //外层循环,判断我们这个要走多少次 for (int i = 0; i < array.length; 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; } }
稀疏数组
-
当一个数组大部分元素为0.或者为同一值的数组时,可以使用稀疏数组来保存该数组。
-
稀疏数组的处理方法是:
-
记录数组一共有几行几列,有多少个不同值
-
把具有不同值的元素和行列及值记录在一个小规模的数组中,从而缩小程序的规模
-
public class 稀疏数组 { 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 < 11; i++) { for (int j = 0; j < 11; j++) { if (array1[i][j] != 0) { sum++; } } } System.out.println("有效值的个数为:"+sum); //2、创建一个稀疏数组的数组 int[][] array2 = new int[sum+1][3]; 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++; 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"); } //还原稀疏数组 System.out.println("======================="); System.out.println("还原稀疏数组"); //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:array1){ for (int anInt:ints){ System.out.print(anInt+"\t"); } System.out.println(); } } }
面向对象
-
面向对象编程(Object Oriented Programming,OOP)
-
面向对象编程的本质就是:以类的方式组织代码,以对象的组织(封装)数据
-
抽象
-
三大特性
-
封装
-
继承
-
多态
-
-
从认识论角度考虑是先有对象后有类。对象,是具体的事物。类,是抽象的,是对对象的抽象
-
从代码运行角度考虑是现有类后有对象。类是对象的模板
类
类的定义
类的重要性:是Java程序的基本组成单位
类是什么:是对现实生活中一类具有共同属性和行为的事物的朝向,确定对象将会拥有的属性和行为
类的组成:属性和行为
-
属性:在类中通过成员变量来体现(类中方法为的变量)
-
行为:在类中通过成员方法来体现(和前面的方法相比去掉static关键字即可
对象的使用
创建对象
-
格式:类名 对象名 = new 类名()
-
范例:Phone p = new Phone();
使用对象
1、使用成员变量
-
格式
类与对象的关系
-
类是一种抽象的数据类型,它是对某一类事物整体描述/定义,但是并不能代表某一个具体的事物
-
对象是抽象概念的具体实例
-
张三就是人的具体实例;张三家里的旺财就是狗的一个具体实例
-
能够体现出特点,展现出功能的是具体的实例,而不是一个抽象的概念
-
创建与初始化对象
-
使用new关键字创建对象
-
使用new关键字创建的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用。
-
类中的构造器也成为构造方法,是在进行创建对象的时候必须要调用的,并且构造器有以下两个特点
-
必须和类的名字相同
-
必须没有返回值类型,也不能写void
-
构造器详解
构造器: 1、和类名相同 2、没有返回值 作用: 1、new 本质在调用构造方法 2、初始化对象的值 注意点 1、定义有参构造之后,如果想使用无参构造,显示的定义一个无参的构造 快捷键 alt + insert
public class Person { //一个类即使什么都不写,它也会存在一个方法 //显示的定义构造器 String name; //无参构造 //实例化初始值 //1、使用new关键在,本质就是在调用构造器 public Person(){ this.name = "liu"; } //有参构造 一旦定义了有参构造,无参就必须显示定义 public Person(String name,int age){ this.name = name; } }
public static void main(String[] args) { //new 实例化一个对象 //Person person = new Person(); Person person = new Person("liu",23); System.out.println(person.name); }
封装
-
我们程序设计要追求”高内聚,低耦合“。高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合:仅暴露少量的方法给外部使用
-
封装:应禁止直接访问一个对象中数据的实际表现,而应通过操作接口来访问,这称为信息隐藏
-
属性私有:get/set
-
提高了程序的安全性,保护数据
-
隐藏代码的实现细节
-
统一接口
-
系统可维护增加
private关键字
-
是一个权限修饰符
-
可以修饰成员(成员变量和成员方法)
-
作用是保护成员不被别的类使用,被private修饰的成员只在本类中才能访问
针对private修饰的成员变量,如果需要其他类使用,提供相应的操作
-
提供“get变量名()"方法,用于获取成员变量的值,方法用public修饰
-
提供“set变量名(参数)"方法,用于获取成员变量的值,方法用public修饰
// 类 private:私有 public class Student { //属性私有 private String name; //名字 private int id; //学号 private char sex; //性别 //提供一些可以操作这个属性的方法! //提供一些 public 的get、set方法 //get 获得这个数据 public String getName(){ return this.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 class Application { public static void main(String[] args) { Student s1 = new Student(); s1.setName("六"); System.out.println(s1.getName()); } }
继承
-
继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模
-
extands 的意思是“扩展”。子类是父类的扩展
-
JAVA中类只有单继承,没有多继承
继承的优先级
public //先
protected
defallt
private
-
继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖、组合、聚合等
-
继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends来表示
-
子类和父类之间,从意义上讲应该具有“is a”的关系
-
object类
-
super
-
方法重写
super
super注意点
-
super调用父类的构造方法,必须在构造方法的第一个
-
super必须只能出现在子类的方法或者构造方法中
-
super和this不能同时调用构造方法
super与this比较
-
代表的对象不同
-
this:本身调用者这个对象
-
super:代表父类对象的应用
-
-
前提
-
this:没有继承也可以使用
-
只能在继承条件才可以使用
-
-
构造方法
-
this():本类的构造
-
super():父类的构造
-
方法重写
-
重写:需要有继承关系,子类重写父类的方法
-
方法名必须相同
-
参数列表必须相同
-
修饰符:范围可以扩大但不能缩小:public>Protected>Defaule>private
-
抛出异常:范围,可以被缩小,但不能扩大; ClassNotFoundException----->Exception(大)
-
-
重写:子类的方法和父类必须一致,方法体不同
为什么重写
-
父类的功能,子类不一定需要,或者不一定满足!
-
快捷键:AIT + Insert :override;
public class Application { //静态的方法和非静态的方法区别很大! //静态方法:方法的调用只和左边,定义的数据类型有关 //非静态方法:重写 public static void main(String[] args) { //方法的调用只和左边,定义的数据类型有关 A a = new A(); a.test(); //父类的引用指向了子类 B b = new A(); //子类重写了父类的方法 b.test(); //B } }
//继承 public class A extends B { @Override //注释:有功能的注释 public void test() { System.out.println("A=>test()"); } }
//重写都是方法的重写,和属性无关 public class B { public void test(){ System.out.println("B=>test()"); } }
多态
-
即同一方法可以根据发送对象的不同而采用多种不同的行为方式
-
一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多(父类,有关系的父类)
-
多态存在的条件
-
有继承关系
-
子类重写父类方法
-
父类引用指向子类对象
-
-
注意:多态是方法的多态,属性没有多态
-
instanceof (类型转变)~ 引用类型
多态注意事项
-
多态是方法的多态,属性没有多态
-
父类和子类,有联系 类型转换异常! ClassCactException!
-
存在条件:继承关系,方法需要重写,父类引用指向子类对象! Father f1 = new San( );
-
不能用多态的情况
-
static 方法,属于类,它不属于实例
-
final 常量
-
private 方法
-
public class Application { public static void main(String[] args) { //一个对象的实际类型是确定的 //new Student(); //new Person(); //可以指向的引用类型就不确定了:父类的引用指向子类 //Student 能调用的方法都是自己的或者继承父类的 Student s1 = new Student(); //Person 父类型,可以指向子类,但是不能调用子类独有的方法 Person s2 = new Student(); Object s3 = new Student(); //对象执行能哪些方法,主要看对象左边的类型,和右边关系不大 s2.run(); //子类重写了父类的方法,执行子类的方法 ((Student)s2).eat(); //强制转换 s1.eat(); } }
public class Person { public void run(){ System.out.println("跑了"); } }
public class Student extends Person{ @Override public void run() { System.out.println("son"); } public void eat(){ System.out.println("chi"); } }
static
//static public class Student { private static int age; //静态变量 多线程 private double score; //非静态变量 //非静态方法 public void run(){ //非静态方法可以直接调用静态方法 go(); } //静态方法 public static void go() { } public static void main(String[] args) { //静态方法可以直接调用静态方法 go(); Student s1 = new Student(); System.out.println(Student.age); System.out.println(s1.age); System.out.println(s1.score); Student.go(); Student s2 = new Student(); s2.run(); } }
public final class Person { //final 其他类不能继承 // { // //代码块(匿名代码块) // } // // static { // //静态代码块 // } //2 { System.out.println("匿名代码块"); } //1 static { System.out.println("静态代码块"); } //3 public Person() { System.out.println("构造方法"); } public static void main(String[] args) { Person person1 = new Person(); System.out.println("============"); Person person2 = new Person(); } }
//静态导入包 import static java.lang.Math.random; import static java.lang.Math.PI; public class Test { public static void main(String[] args) { //没有静态导入包时 System.out.println(Math.random()); //静态导入包后 System.out.println(random()); System.out.println(PI); } }
抽象类
-
abstract修饰符可以用来修饰方法也可以用来修饰类,如果修饰方法,那么该方法就是抽象方法;如果修饰类,那么该类就是抽象类
-
抽象类中可以没有抽象方法,但是又抽象方法的类一定要声明为抽象类
-
抽象类,不能使用new关键字来创建对象,它是用来让子类继承的
-
抽象方法,只有方法的声明,没有方法的实现,它是用来让子类实现的
-
子类继承抽象类,那么就必须要实现抽象类没有实现的抽象方法,否则该子类也要声明为抽象类
/abstract 抽象类:类 extends:单继承 接口可以多继承 public abstract class Action { //约束~ 有人帮我们实现~ //abstract,抽象方法,只有方法名字,没有方法的实现 public abstract void dosome(); //1、不能new这个抽象类,只能靠子类去实现它; 约束! //2、抽象类中可以写普通方法 //3、抽象方法必须在抽象类中 //抽象的抽象:约束~ }
//抽象类的所有方法,继承了它的子类,都必须要实现他的方法 public class A extends Action{ @Override public void dosome() { } }
接口
-
普通类:只能具体实现
-
抽象类:具体实现和规范
-
接口:只有规范!
-
接口就是规范,定义的是一组规则,体现了现实世界中“如果你是....则必须能...”的思想。若果你是天使,则必须能飞
-
接口的本质是契约,就像我们人间的法律一样。制定好后大家都遵守
-
OO的精髓,是对对象的抽象,最能体现这一点的就是接口。为什么我们讨论设计模型都只针对具备了抽象能力的语言(比如C++、Java、c#等),就是因为设计模式所研究的,实际上就是如何合理的去抽象
声明类的关键字是class,声明接口的关键字是interface
接口的作用
-
约束
-
定义一些方法,让不同的人实现
-
public abstract
-
public static final
-
接口不能被实例化~,接口中没有构造方法
-
implements 可以实现多个接口
-
必须要重写接口中的方法
//抽象的思维~~~~ //interface 定义的关键字 接口都需要有实现类 public interface UserService { //常量 public static final int AGE = 99; //接口中的所有定义的方法其实都是抽象的 public void add(String name); void delete(String name); void aupdate(String name); void aquery(String name); }
//抽象类:extends //一个类 可以实现接口 implements 接口 //实现了接口的类,就需要重写接口中的方法 //利用接口实现多继承 public class UserServiceImp1 implements UserService,TimeService { @Override public void add(String name) { } @Override public void delete(String name) { } @Override public void aupdate(String name) { } @Override public void aquery(String name) { } @Override public void time() { } }
public interface TimeService { void time(); }
内部类
-
内部类就是在一个类的内部在定义一个类,比如:A类中定义一个B类,那么B类相对A类来说就成为内部类,而A类相对B类来说就是外部类了
-
成员内部类
-
静态内部类
-
局部内部类
-
匿名内部类
public class Outer { private int id=10; public void out(){ System.out.println("这是外部类的方法"); } class Inner{ public void in(){ System.out.println("这是内部类的方法"); } //获得外部类的私有属性 public void getID(){ System.out.println(id); } } }
public class A { public static void main(String[] args) { //new Outer outer = new Outer(); //通过这个外部类来实例化内部类 Outer.Inner inner = outer.new Inner(); inner.in(); inner.getID(); } }
public class B { //局部内部类 public void method() { class inner{ public void in(){ } } } public static void main(String[] args) { //匿名内部类 //没有名字初始化类,不用将实例保存到变量中~ new c().eat(); User user = new User() { @Override public void hello() { } }; } } //一个Java类中可以有多个class类,但是只能有一个public class class c{ public void eat() { System.out.println("1"); } } interface User{ void hello(); }
异常机制
-
异常指程序运行中出现的不期而至的各种状况,如:文件找不到、网络连接失败、非法参数等
-
异常发生在程序运行期间,它影响了正常的程序执行流程
异常类型
-
检查型异常:最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单的忽略
-
运行时异常:运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略
-
错误:错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如:当栈溢出时,一个错误就发生了,它们在编译也检查不到的
异常体系结构
-
Java把异常当作对象来处理,并定义一个基类java.lang.Throwable作为所有异常的超类
-
在Java API中已经定义了许多异常类,这些异常类分为两大类,错误( Error ) 和 异常( Exception )
Error
-
Error类对象有 Java 虚拟机生成并抛出,大多数错误与代码编写者所执行的操作无关
-
Java 虚拟机运行错误(Virtual MachineError),当JVM不再有继续执行操作所需的内存资源时,将出现 OutOfMemoryError。这些异常发生时,Java虚拟机(JVM)一般会选择线程终止
-
还有发生在虚拟机试图执行应用时,如类定义错误(NoClassDefFoundError)、链接错误(LinkageError)。这些错误是不可查的,因为它们在应用程序的控制和处理能力之外,而且绝大多数是程序运行时不允许出现的状况
Exception
-
在Exception分支中有一个重要的子类RuntimeException(运行时异常)
-
ArrayIndexOutOfBoundsException(数组下标越界)
-
NullPointerException(空指针异常)
-
ArithmeticException(算数异常)
-
MissingResourceException(丢失资源)
-
ClassNotFoundException(找不到类)等异常,这些异常是不检查异常,程序中可以选择捕获处理,也不可以不处理
-
-
这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生
错误( Error ) 和 异常( Exception )的区别
-
Error通常是灾难性的致命的错误,是程序无法控制和处理的,当出现这些异常时,Java虚拟机(JVM)一般会选择终止线程;
-
Exception通常情况下是可以被程序处理的,并且在程序中应该尽可能的去处理这些异常
异常处理机制
-
抛出异常
-
捕获异常
-
异常处理五个关键字
-
try、catch、finally、throw、throws
-
public class Test { public static void main(String[] args) { int a = 1; int b = 0; try {//try监控区域 System.out.println(a/b); }catch (ArithmeticException e){ // 程序出现异常 即try中的程序出现异常 执行 catch //catch 捕获异常 System.out.println("程序出现异常"); }finally { //不管程序出不出现异常都 finally //处理善后工作 System.out.println("finally"); } //try catch 必须有 //finally 可以不要 } }
public class A { public static void main(String[] args) { try { new A().a(); }catch (Throwable e){ System.out.println("程序出现异常"); } } public void a(){b();}; public void b(){a();}; }
public class B { public static void main(String[] args) { /* int a = 1; int b = 0; //快捷键 ctrl + alt +t try { System.out.println(a/b); } catch (Exception e) { //System.exit(0);//程序结束 throw new RuntimeException(e);//打印错误的栈信息 } finally { } */ try { new B().test(1,0); } catch (ArithmeticException e) { throw new RuntimeException(e); } } //假设在方法中,处理不了这个异常,方法上抛出异常 public void test(int a,int b) throws ArithmeticException{ if(b==0){//主动抛出异常 throw throw new ArithmeticException(); } } }
自定义异常
-
使用Java内置的异常类可以描述在编程时出现的大部分异常情况。除此之外,用户还可以自定义异常。用户定义异常类,只需继承Exception类即可
-
在程序中使用自定义异常类,大体可分为以下几个步骤
-
创建自定义异常类
-
在方法中通过throw关键字抛出异常对象
-
如果在当前抛出异常的方法中处理异常,可以使用 try—catch 语句捕获并处理;否则在方法的声明处通过throws关键字指明要抛出给方法调用者的异常,继续进行下一步操作
-
在出现异常方法的调用者中捕获并处理异常
-
//自定义异常类 public class MyException extends Exception{ //传递数字>0 private int detail; public MyException(int a){ this.detail = a; } //toString:异常的打印信息 //alt + ins @Override public String toString() { return "MyException{" + "detail=" + detail + '}'; } }
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); } } }
实际应用中的经验总结
-
处理运行时异常时,采用逻辑去合理规避同时辅助 try—catch 处理
-
在多重catch块后面,可以加一个catch(Exception)来处理可能会被遗漏的异常
-
对于不确定的代码,也可以加上 try—catch ,处理潜在的异常
-
尽量去处理异常,切记只是简单地调用 printStsckTrace( ) 去打印输出
-
具体如何去处理异常,要根据不同的业务需求和异常类型去决定
-
尽量添加 finally 语句块去释放占用的空间