1、卸载JDK
1.1、java的安装目录
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VqCy7BuW-1603698615853)(java.assets/image-20200708063518598.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v7US8Yrq-1603698615857)(java.assets/image-20200708063555787.png)]
1.2、删除JAVA-HOME
1.3、删除path下关于Java的目录
1.4、cmd下运行Java-version没有出现Java对应的版本则删除成功
2、安装jdk
2.1、百度搜索jdk8,找到下载协议、同意协议
下载对应的版本并解压
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ilqoPp8s-1603698615859)(java.assets/image-20200708064652146.png)]
双击安装
记住安装路径
2.2、配置环境变量
- 我的电脑->右键->属性->高级系统设置–>环境变量
- 系统变量->新建JAVA_HOME
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UDlCwwB4-1603698615861)(java.assets/image-20200708065601361.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UPjTpM0Q-1603698615863)(java.assets/image-20200708065746967.png)]
-
系统变量->新建path[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dZjiz8l8-1603698615865)(java.assets/image-20200708065859271.png)]
-
系统变量->新建classpath
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HAZhjAqb-1603698615865)(java.assets/image-20200708070046436.png)]
- 测试是否安装成功
- 运行cmd输入Java和javac
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EKiavUNx-1603698615866)(java.assets/image-20200708070238920.png)]
- 运行cmd输入Java和javac
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E774fyrx-1603698615867)(java.assets/image-20200708070308822.png)]
出现以上表示安装成功,否则检查环境变量·
3、Helloword(程序员的仪式感)
1.1、随便新建一个文件夹存放代码
-
新建一个java文件
-
后缀名为.java的文件
-
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B805Kieh-1603698615869)(java.assets/image-20200708070900290.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kGeqJVH1-1603698615869)(java.assets/image-20200708070946251.png)]
3、 用记事本打开编写代码
public class Hello{ public static void main(String[] args){ System.out.print("Hello,World!"); } }
4、cmd中打开Hello文件夹所在路径
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jCbdvXDp-1603698615870)(java.assets/image-20200708180248200.png)]
-
5、将Hello编译成字节码文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2Pai5kzS-1603698615871)(java.assets/image-20200708180420104.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WPycC3V1-1603698615872)(java.assets/image-20200708180516456.png)]
6、运行字节码文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1wMYFdKo-1603698615872)(java.assets/image-20200708180726832.png)]
可能遇到的情况
- 每个单词大小写不能出现问题,java大小写敏感
- 尽量使用英文
- 文件明类名必须保证一致,并且首字母大写
- 符号使用了中文的
4、Java程序运行机制
- 编译型
- 解释型
区别:
运行编译型语言是相对于解释型语言存在的,编译型语言的首先将源代码编译生成机器语言,再由机器运行机器码(二进制)。
解释性语言的程序不需要编译,省了道工序,解释性语言在运行程序的时候才翻译,比如解释性basic语言,专门有一个解释器能够直接执行basic程序,每个语句都是执行的时候才翻译。这样解释性语言每执行一次就要翻译一次,效率比较低。解释是一句一句的翻译。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d1xNCsNK-1603698615873)(java.assets/3VQ9YHO%5DIE20%7D%60K41%7D%60UCRG.png)]
- 程序运行机制
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bjklmCnw-1603698615874)(java.assets/image-20200708230331714.png)]
5、变量和数据类型
5.1、注释
-
平时我们编写代码,在代码量比较少的时候,我们还可以看懂自己写的代码,但是项目结构一旦复杂起来,我们就需要用到注释了。
-
注释并不会被执行,只是给读代码维护代码的人看的
-
书写注释是一个非常好的注释。
-
平时写代码一定要注意规范
-
Java中的注释有三种
-
单行注释
public class HelloWorld { // main方法是程序的入口 public static void main(String[] args) { //单行注释 //输出一个Hello,World System.out.println("Hello,Word!"); /*** * _ooOoo_ * o8888888o * 88" . "88 * (| -_- |) * O\ = /O * ____/`---'\____ * . ' \\| |// `. * / \\||| : |||// \ * / _||||| -:- |||||- \ * | | \\\ - /// | | * | \_| ''\---/'' | | * \ .-\__ `-` ___/-. / * ___`. .' /--.--\ `. . __ * ."" '< `.___\_<|>_/___.' >'"". * | | : `- \`.;`\ _ /`;.`/ - ` : | | * \ \ `-. \_ __\ /__ _/ .-` / / * ======`-.____`-.___\_____/___.-`____.-'====== * `=---=' * * ............................................. * 佛祖保佑 永无BUG */ } }
-
多行注释
/*
这里写注释
*/
-
文档注释
/**
*/
5.2、标识符和关键字
- 关键字
Java关键字是电脑语言里事先定义的,有特别意义的标识符,有时又叫保留字,还有特别意义的变量。
Java的关键字对Java的编译器有特殊的意义,他们用来表示一种数据类型,或者表示程序的结构等,关键字不能用作变量名、方法名、类名、包名和参数。
- Java所有的组成部分都需要名字、类名、变量名以及方法名都被称为标识符。
注意:
- 所有的标识符都应该以字母,美元符号($)或者下划线(__)开始
- 首字符之后可以是字母,数字。美元符号、下划线的任何字符组合
- 不能使用关键字作为变量名和方法名
- 标识符是大小写敏感的
- 可以使用中文命名,但不推荐,Low的一批
5.3、数据类型
- 强类型语言
- 要求变量的使用要严格符合规定,所有变量必须先定义在使用
- 弱类型语言
- Java的数据类型分两大类
- 基本类型
- 引用类型
- 变量
在JAVA中我们通过三个元素来描述变量:变量类型,变量名以及变量值。
变量,就是可以改变的量。
- 变量的使用
1、Java 中的变量需要先声明后使用;
2、变量使用时,可以声明变量的同时进行初始化,也可以先声明后赋值;
String love=“imooc”;或者String love;love=“I love imooc”;
3、变量中每次只能赋一个值,但可以修改多次;
4、main 方法中定义的变量必须先赋值,然后才能输出;
5、虽然语法中没有提示错误,但在实际开发中,变量名不建议使用中文,容易产生安全隐患,譬如后期跨平台操作时出现乱码等等。
使用变量的时候,有一些注意事项
- 如果创建多个变量,那么变量名称不可以重复
- 对于Float和long类型来说,字母后缀F和L不可缺少
- 如果使用byte或者short 类型的变量 那么右侧的的数值不能超过左侧类型的范围
- 没有初始化的变量 不能直接使用
- 变量使用不能超过作用域的范围
- 什么是字节
◆位(bit) :是计算机内部数据储存的最小单位,11001100是-一个八位二进制数。
◆字节(byte) :是计算机中数据处理的基本单位,习惯上用大写B来表示,
◆1B (byte,字节) = 8bit (位)
◆字符:是指计算机中使用的字母、数字、字和符号
- 1bit表示1位,
1Byte表示一个字节1B=8b。
1024B= 1KB
1024KB= 1M
1024M=1G.
5.4、数据类型转换
Java程序要求参与计算的数据,必须要保证数据类型的一致性,如果不一样将会发生类型的转换
自动转换(隐式的 )
-
一个int类型变量和一个byte类型的变量进行加减乘除运算,结果会是什么!
public static void main(String[] args) { int i=1; byte b=2; // b+i;//报错 需要强转 x=(byte)(b+i) // int 类型和byte运算结果是int int j=b+1;//自动转为 int System.out.println(x); System.out.println(j); }
运算结果:变量的类型将是int,这就是出现了数据类型的自动转换
-
特点
- 代码不需要进行特殊处理
-
规则
数据类型从小到大
-
有多种类型的数据混合运算时,系统首先自动将所有数据转换成容量最大的那种数据类型,然后再进行计算。
-
byte,short,char之间不会相互转换,他们三者在计算时首先转换为int类型。
-
boolean类型不能与其它数据类型运算。
当把任何基本数据类型的值和字符串(String)进行连接运算时(+),基本数据类型的值将自动转化为字符串 (String)类型。
强制类型转换(显示)
public static void main(String[] args) {
int num= (int) 100L;//强制转换
System.out.println(num);
}
- 特点
代码需要特殊的格式处理
- 格式
数据类型1 变量1=(数据类型1)(变量2);
注意事项
1、强转不推荐使用 可能会发生精度损失
6、运算符
6.1、算术运算符
符号 | 描述 |
---|---|
+ | 加法或者连接字符串 |
- | 减法 |
* | 乘法 |
/ | 除法 |
+ | 字符串连接符 |
% | 取模 |
++ , -- | 自增 |
java中 整数通过以上运算符 怎么也不会得到小数
-
++
运算,变量自增,反之,--
变量自减 -
%
取模运算 比如 15%2=1 -
+
四则运算中是加法 对于字符串就是连接符号 -
/
应用:利用 /
和 %
求一个 三位整数 n的各位数
n/10/10;百位数 n/10%10;十位数 n%10;个位数
注意:任何数据类型和字符串进行连接操作 结果都会变成字符串
自增自减运算
++
--
- 分类
i++,i-- 先对i进行别的操作 在进行+1或-1
++i,–i 先+1或-1,在做别的操作
6.2、赋值运算符
符号 | 描述 |
---|---|
= | 赋值(两侧类型要相同) |
+= | 加等于 |
*= | 乘等于 |
-= | 减等于 |
%= | 取模等于 |
/= | 除等于 |
6.3、比较运算符和逻辑
比较运算符
符号 | 描述 | 比如 |
---|---|---|
== | 比较两边是否相等 相等为 | 1==1 结果为true |
> | 大于 | 1>0 结果为true |
< | 小于 | 0<1 结果为true |
<= | 小于等于 | 0<=0 结果为true |
>= | 大于等于 | 0>=0 结果为true |
!= | 不等于 | 1 !=2 结果为true |
逻辑运算符
逻辑运算符一般用于连接boolean类型的表达式或者值。
表达式:就是用运算符把常量或者变量连接起来的符合java语法的式子。
算术表达式:a + b
比较表达式:a == b
符号 | 描述 |
---|---|
&& | 短路与 |
& | 逻辑与 |
|| | 短路或 |
| | 逻辑或 |
! | 逻辑非 |
^ | 逻辑异或 |
public static void main(String[] args) {
System.out.println(true&&false);//false
//true&&true-->true
System.out.println(3<4&&10>5);//true
System.out.println("+++++++++++++++++++++");
System.out.println(true||false);//true
System.out.println(true||true);//true
System.out.println(false||false);//false
System.out.println("++++++++++++++++++++====");
System.out.println(true);
System.out.println(!true);//false
}
注意:
&
:
在算术运算时分别计算表达式两边的结果,再作&运算
在位运算时&表示按位与
&&
:
短路与运算,先计算左边的表达式,如果结果是false,那么不用计算右边表达式,直接返回false
如果左边的表达式结果为true,再计算右边的表达式,如果右边的表达式为true,结果为true,否则为false
|与||的原理同上
短路与 或 短路或的计算效率更高,建议使用。
// && 和 &
public static void main(String[] args) {
/*
* &&
* ||
* */
int i=1,j=1;
if(i==2&&i++==2){}
System.out.println(i);//1
if(j==2&j++==2){}
System.out.println(j);//2
}
//||和|
public static void main(String[] args) {
/*
* &&
* ||
* */
int i=1,j=1;
if(i==1||i++==2){}
System.out.println(i);//1
if(j==1|j++==2){}
System.out.println(j);//2
}
6.4、位运算和三元运算符
位运算:直接对二进制数进行的运算
符号 | 描述 |
---|---|
<< | 左移 |
>> | 右移 |
>>> | 无符号右移 |
^ | 异或 |
~ | 取反运算 |
一元运算符:只需要一个运算符就可以进行操作的运算符。如:++
!
--
二元运算符:需要两个运算符才可以进行操作的运算符。
三元运算符:需要两个运算符才可以进行操作的运算符。
格式:数据类型 变量名=条件判断?表达式1:表达式2;
过程:
首先判断条件是否成立若为true,那么将表达式1的值赋给变量;否则将表达式2的值赋给变量
列如找出两个数的最大值
public static void main(String[] args) {
int a=10;
int b=20;
int max;
max=a>b?a:b;
System.out.println(max);
}
注意事项:
数据类型 变量名=条件判断?表达式1:表达式2;
-
必须同时保证表达式1和表达式2都符合等号左侧的数据类型的要求
-
三元运算符的结果必须被使用
a>b?a:b;//错误 结果没被使用,直接打印出来可以
7、方法入门
7.1、概述
我们在前面学习的时候,都为每一个新的类和main方法,我们会发现这样编写代码非常繁琐,而且重复的代码量过多。为了解决代码冗余 提高代码复用率,就需要引入方法的概念。
- 方法就是一个功能抽取出来,把代码单独定义在一个大括号类,形成一个单独的功能。当我们需要这个功能的时候,就可以去调用,这样就提高了代码的复用解决的代码的冗余。
7.2、方法的定义
- 定义格式
修饰符 返回类型 方法名 (参数列表){
方法体
}
- 定义格式解释:
- 修饰符:目前固定写法
public static
- 返回值类型:有 int float 等 当没有返回值的时候 用
void
- 方法名:我们定义的方法起名。
- 修饰符:目前固定写法
注意事项
- 方法的先后顺序无所谓
- 方法的定义不能产生嵌套包含关系、
- 方法定义好了之后,不会被执行,一定要进行方法的【调用】
调用:
方法名();
8、流程概述
8.1、概述
在一个程序执行的过程中,各条语句的执行顺序对程序的结果都是有直接影响的。也就是说程序的流程对运行结果有直接影响。所以,我们必须清楚每条语句的执行流程。而且很多时候我们要通过控制语句的执行顺序来实现我们要完成的功能。
8.2、顺序结构
从上到下依次执行
public static void main(String[] args) {
int i=1;
byte b=2;
byte x=(byte)(b+i);//报错 需要强转 x=(byte)(b+i)
// int 类型和byte运算结果是int
int j=b+1;//自动转为 int
System.out.println(x);
System.out.println(j);
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mESV8ssX-1603698615875)(java.assets/image-20200814081312121.png)]
8.3、判断语句
if
- if语句的第一种格式:if
if(关系表达式){
语句体;
}
- 执行过程:
- 判断关系表达式的结果:true 或者false
- 如果为true执行语句体
- 如果为false就不执行语句体
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XAEkbycS-1603698615876)(java.assets/image-20200814081808374.png)]
if-else
- 第二种标准的if-else
if(关系表达式){
语句体A;
}else{
语句体B;
}
- 执行过程
- 判断关系表达式的真假】
- true执行语句体A
- false执行语句体B
- 结束
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IXmtjYgN-1603698615876)(java.assets/image-20200814081924490.png)]
if-else if。。。else
- 扩展if-else if。。。else
if(判断条件1){
语句体1;
}else if(判断条件2){
语句体2;
}
....
}else if(判断条件n){
语句体n
}else{
语句体n+1;
}
- 执行流程
- 判断条件1的布尔值
- true就执行语句体1
- 如果为false就继续往下判断 判断条件2的布尔值
- true就执行语句体2;
- false就继续往下判断 判断条件的布尔值
- 。。。。。
- 如果前面的判断条件都为false就执行 语句体n+1
8.4、switch语句
- switch语句格式:
switch(表达式) {
case 常量值1:
语句体1;
break;
case 常量值2:
语句体2;
break;
case 常量值3:
语句体3;
break;
.....
case 常量值n:
语句体n;
break;
default:
语句体n+1;
break;
}
-
执行流程
- 首先计算出表达式的值
- 其次,和case依次比较,一旦有对应的值就会执行响应的语句体,在执行的过程中,遇到break就会结束。
- 最后,如果所有的表达式的值不匹配,就会default语句体部分,然后程序结束掉。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IZ96iLd1-1603698615877)(java.assets/image-20200815224958754.png)]
-
switch语句使用的注意事项:
-
多个case后面的数值不可以相同
-
case子句中的值必须是常量值
-
switch后面的小括号只能是下列数据类型
byte
short
char
int
String
enum枚举
-
switch语句格式可以很灵活:前后顺序可以颠倒,而且break还可以省略。
-
-
switch 穿透
8.5、循环语句
- 循环概述
循环语句可以在满足循环条件的情况下,反复的执行某一段代码,这段被重复的代码被称为循环语句体,当反复执行这个语句体时,需要在合适的时候把判断条件改为**false。**从而结束循环,否则循环将一直进行下去,形成死循环。
8.5.1、循环语句----for
- for循环的语句格式:
for(初始化条件;布尔表达式;步进表达式){
循环体;
}
for(;布尔表达式;){
循环体;
}
- 执行流程
- 执行顺序:①②③④–>②③④—>②③④…②不满足条件为止
- ①负责完成变量初始化
- ②判断是否满足循环条件,不满足则跳出循环
- ③具体执行的语句
- ④循环后,循环条件所涉及变量的变化情况
for循环的应用
/*打印输出三角形
*
***
*****
*******
*********
*/
public static void main(String[] args) {
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();
}
}
注意:
- 循环的条件部分是布尔表达式 true则进入循环,false则退出循环
- 初始化部分可以声明多个变量 数据类型必须相同 用逗号隔开
- 步进语句可以跟新多个变量,用逗号隔开
8.5.2、while循环
- while循环语句格式
//扩展格式
初始化表达式;
while(布尔表达式式){
循环体;
步进表达式;
}
//标椎格式
while(条件判断){
循环体;
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6S7dN3fl-1603698615878)(java.assets/image-20200816220933471.png)]
执行流程
- 执行顺序:①②③④–>②③④—>②③④…②不满足条件为止
- ①负责完成变量初始化
- ②判断是否满足循环条件,不满足则跳出循环
- ③具体执行的语句
- ④循环后,循环条件所涉及变量的变化情况
利用while循环求1~100的累加
public class WhileDemo02 {
public static void main(String[] args) {
int i=0;//c初始化条件
int sum=0;
while(i<=100){//条件判断
sum+=i;//循环体
i++;//步进
}
}
}
do-while
- do…while 格式
初始化表达式;
do{
循环体;
步进语句;
}while(布尔表达式);
- 执行流程
- 执行顺序:①②③④–>②③④—>②③④…②不满足条件为止
- ①负责完成变量初始化
- ②判断是否满足循环条件,不满足则跳出循环
- ③具体执行的语句
- ④循环后,循环条件所涉及变量的变化情况
注意:
while和do…while的区别
- while先判断在执行
- do…while先执行在判断
- do…while至少执行一次
8.5.3、循环控制语句
break关键字的两种常见用法
- 可以用在switch语句当中,一旦执行整个switch立刻结束
- 可以用在循环语句当中,一旦执行,整个循环立刻结束,打断循环
关于循环的选择:
次数确定的用for循环 否则用while循环
public class BreakDemo03 {
public static void main(String[] args) {
for (int i = 1; i <=10; i++) {
//如果当i=4,后面的循环都不要了
if (i==4){
break;
}
System.out.println("hello");
}
}
}
continue
- 一旦执行,立即结束当前剩下的循环
循环的应用
//输入一个五位数并判断是否为回文数
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n;
char[] str;
System.out.println("请输入一个五位数进行判断是否为回文数:");
while(in.hasNextInt()){//当输入的值不是整数时终止循环
n=in.nextInt();
if (n<10000||n>99999){//输入的数不是五位数重新输入
System.err.println("输入错误!!请输入一个五位数:");
continue;
}
str=Integer.toString(n).toCharArray();
if(str[0]==str[4]&&str[1]==str[3]){
System.out.println(n+"是回文数");
}
else{
System.out.println(n+"不是回文数");
}
System.out.println("请输入一个五位数进行判断是否为回文数:");
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-To78sbLj-1603698615878)(java.assets/image-20200819183052856.png)]
9、数组
9.1、数组概述
什么数组
数组就是多个相同的数据类型按一定的顺序排列的集合,并且使用同一个名字命名,通过编号的方式进行管理
数组是一种容器,可以存放多个数值
数组的特点
- 数组是引用类型,而数组元素可以是任何数据类型
- 数组中的多个数据,是同一种数据类型
- 数组的长度在程序运行期间不可改变
数组初始化:在内存当中创建一个数组,并向其中赋予一些默认值
创建数组:
会在内存中开辟一段连续的空间,数组名引用的是连续空间的首地址
- 动态初始化(指定长度)
数据类型 [] 数组名称=new 数据类型[length];
解析:
左侧数据类型,也就是数组当中保存的数据,全是统一的一个类型
左侧[]:代表他是一个数组
数组名称:数组的名字
右侧new:创建数组的动作
右侧数据类型:必须和左边保持一致
length:数组的大小
-
静态初始化(指定内容)
-
基本格式
数据类型 [] 数组名称={元素1,元素2,元素3,元素4.....};//方式一 数据类型 [] 数组名称=new int[]{元素1,元素2,元素3,元素4.....};//方式二
-
注意:
- 虽然静态数组初始化没有直接告诉长度,但是可以根据内容算出长度
-
访问数组元素
-
直接打印数组名称,得到的是数组对应的,内存地址哈希值。
- [I@1b6d3586
[
:代表是一个数组 -
访问数组元素个格式
-
数组名称[索引值]; //索引值 int类型 代表数组元素的编号 索引值从零开始
-
9.2、java的内存分为五个部分
- 栈内存(Stack): 存放的都是方法中的局部变量。方法的运行一定要在栈当中运行
- 局部变量:方法的参数,或者{}内的变量
- 作用域:一旦超出作用域,就立刻从栈内存中消失
- 堆内存(Heap):凡是new出来的东西,都在堆当中。
- 堆内存中的东西都有一个地址值:16进制的
- 堆内存中的数据都有默认值
- 如果整数 默认为0
- 如果是浮点数 默认 0.0
- 如果是字符 默认 ‘\u0000’
- 如果是布尔 默认 false
- 如果是引用类型 默认 null
- 方法区(Method Are):存储
.class
相关信息,包括方法的信息。 - 本地方法栈(Native Method Stack):与操作系统相关。
- 寄存器(pc Register):与cpu相关。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N7rXwXm4-1603698615879)(java.assets/image-20200820153128222.png)]
一个数组的内存图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-odCzSWta-1603698615880)(java.assets/image-20200820134054060.png)]
两个数组的内存图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QmCoTn4S-1603698615880)(java.assets/image-20200820134910632.png)]
两个引用指向同一个数组
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SiHRd0UU-1603698615881)(java.assets/image-20200820140155879.png)]
9.3、数组应用
9.3.1、数组索引越界
数组的索引从0开始到数组长度-1结束
如果访问数组元素的时候。索引编号不存在,那么就会发生数组索引越界异常 :
ArrayIndexOutOfBoundsException
int [] a={10,20,30};
System.out.println(a[3]);//数组索引越界
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4bQhywnX-1603698615882)(java.assets/image-20200820140624676.png)]
9.3.2、空指针异常
所有的引用变量,都可以赋值为一个null,但是代表其中什么都没有。
数组必须进行new 初始化才能使用其中的元素
如果只是赋值null,没有进行new创建 那么将发生空指针异常
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UsVDRLbF-1603698615882)(java.assets/image-20200821075842166.png)]
9.3.3、获取数组长度
如何获取数组长度,格式:
数组名.length
这将会得到一个int数字,代表数组的长度
数组一旦创建,程序运行期间长度不可改变
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-16zgzv2B-1603698615883)(java.assets/image-20200821080942468.png)]
9.3.4、数组的遍历
对数组的每一个元素进行逐一处理,默认的处理方式就是输出
//方式一 for循环
for(int i=0;i<数组名称.length;i++){
System.out.println(数组名[i]);
}
//方式二增强for循环
for(数组元素数据类型 i:数组名){
System.out.println(i);
}
//方式三
System.out.println(Arrays.toString(数组名));
求出数组元素最大值(最小值也是一样的)
public static void main(String[] args) {
int [] a={1,2,5,88,6,5,9};
int max;
max=a[0];
for (int i=1;i<a.length;i++) {
if(a[i]>max){
max=a[i];
}
}
System.out.println("max="+max);//88
}
数组元素反转
数组元素反转就是对称位置的元素交换位置
public static void main(String[] args) {
int [] a={1,2,3,4,5,6};
for (int min=0,max=a.length-1;min<max;min++,max--){
int temp=a[min];
a[min]=a[max];
a[max]=temp;
}
System.out.println(Arrays.toString(a));
}
9.4、排序算法
1、冒泡排序
冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。 它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果他们的顺序(如从大到小、首字母从A到Z)错误 就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。 这个算法的名字由来是因为越大的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二 氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。 冒泡排序算法的原理如下:
- \ 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
- 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的 数。
- 针对所有的元素重复以上的步骤,除了最后一个。
- 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pBAOYfTC-1603698615884)(java.assets/bubbleSort.gif)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m8B1KfI1-1603698615885)(java.assets/EJ@(QA1WLR)]B43CR$MN92EG.png)
public class ArrayDemo07 {
public static void main(String[] args) {
int [] a={11,22,1,2,3,5,9};
int [] sort=sort(a);
System.out.println(Arrays.toString(sort));
}
//冒泡排序
public static int [] sort(int [] array){
boolean flag=false;
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;
flag=true;
}
}
if (!flag){
break;
}
}
return array;
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5M9Bn7C6-1603698615885)(java.assets/image-20200821092217206.png)]
2、选择排序
选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理是每一次从待排序的数据元素中选出最小 (或最大)的一个元素,存放在序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到全部待排序的数据元素排完。 选择排序是不稳定的排序方法。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Fahko5ST-1603698615886)(java.assets/selectionSort.gif)]
public class SortDemo01 {
public static void main(String[] args) {
int [] a={1,2,5,6,8,9,5,4,3};
int [] b=selectSort(a);
System.out.println(Arrays.toString(b));
}
//选择排序
public static int [] selectSort(int [] array){
int minIndex=0;
int temp=0;
for (int i=0;i<array.length;i++){
minIndex=i;
for (int j=i+1;j<array.length;j++){
if(array[minIndex]>array[j]){
minIndex=j;
}
}
if (i!=minIndex){
temp=array[i];
array[i]=array[minIndex];
array[minIndex]=temp;
}
}
return array;
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v5u8CoZK-1603698615887)(java.assets/image-20200821094108240.png)]
3、插入排序
有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,这 个时候就要用到一种新的排序方法——插入排序法, 插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算 法适用于少量数据的排序,时间复杂度为O(n^2)。是稳定的排序方法。插入算法把要排序的数组分成两部分:第一部 分包含了这个数组的所有元素,但将最后一个元素除外(让数组多一个空间才有插入的位置),而第二部分就只包含 这一个元素(即待插入元素)。在第一部分排序完成后,再将这个最后元素插入到已排好序的第一部分中。 插入排序的基本思想是:每步将一个待排序的记录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直 到全部插入完为止。 包括:直接插入排序,二分插入排序(又称折半插入排序),链表插入排序,希尔排序(又称缩小增量排序)。属于 稳定排序的一种(通俗地讲,就是两个相等的数不会交换位置) 。 一般来说,插入排序都采用in-place在数组上实现。具体算法描述如下: ⒈ 从第一个元素开始,该元素可以认为已 经被排序 ⒉ 取出下一个元素,在已经排序的元素序列中从后向前扫描 ⒊ 如果该元素(已排序)大于新元素,将该元 素移到下一位置 ⒋ 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置 ⒌ 将新元素插入到下一位置中 ⒍ 重复步骤2~5 如果比较操作的代价比交换操作大的话,可以采用二分查找法来减少比较操作的数目。该算法可以认为是插入排序的 一个变种,称为二分查找排序。
import java.util.Arrays;
public class InsertSort {
public static void main(String[] args) {
int [] a={1,2,5,4,3,7,6,10};
int [] array=insertSort(a);
System.out.println(Arrays.toString(array));
}
public static int [] insertSort(int [] array){
int temp=0;
for (int i=0;i<array.length;i++){
for (int j=i;j>0;j--){
if (array[j]<array[j-1]){
temp=array[j-1];
array[j-1]=array[j];
array[j]=temp;
}
else
break;
}
}
return array;
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IRCjTY9D-1603698615888)(java.assets/image-20200821133633943.png)]
4、快速排序
在待排序的n个元素序列中,任意选取一个元素(通常选第一个)作为基准,然后从右边开始选取比较,直到选取的元素比基准元素小,并交换位置,然后从左边开始选取比较,直到选取的元素比基准元素大,并交换位置。完成一轮后,从基准划分为高低两部分序列,从低序列开始与第一轮一样,循环完成排序,再对高序列完成排序,从而确定序列顺序。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QaUNQ5Zr-1603698615888)(java.assets/quickSort.gif)]
import java.util.Arrays;
public class QuickSort {
public static void main(String[] args) {
int [] a={1,2,3,4,9,5,7,6,10};
quickSort(a,0,a.length-1);
System.out.println(Arrays.toString(a));
}
//快速排序
public static void quickSort(int [] array,int left,int right){
//若左边索引大于右边的索引不合法,就用return结束方法
if (left>right){
return;
}
//定义基数
int base=array[left];
//定义变量指向最左边
int i=left;
//指向最右边
int j=right;
//当ij不相遇 进行索引
while (i!=j){
//从最右边开始向右索引检索比基数小的值 如果检索到比基数小的就停下
while (array[j]>=base&&i<j){
j--;//j向左边移动
}
while(array[i]<=base&&i<j){
i++;//i向右移动
}
// i j都停止
int temp=array[i];
array[i]=array[j];
array[j]=temp;
}
//如果while不循环 i j 已经相遇
//如果i j 相遇了就交换基准数这个位置和相遇位置的的元素
//吧相遇位置的的元素赋值给基准数这个位置的元素
array[left]=array[i];
//吧基准数赋值给相遇相遇位置的元素
array[i]=base;
//到这一步就需要把基准数递归了,左边的数字都比他小,右边的数字都比他大
//排基准数的左边
quickSort(array,left,i-1);
//右边
quickSort(array,j+1,right);
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QdZee7mG-1603698615889)(java.assets/image-20200821144123974.png)]
9.5、多维数组
多维数组(二维数组)
- 什么是二维数组
数组的数组叫二维数组。二维数组的每一个元素都是一个一维数组
- 语法格式
//方式一:动态初始化
数据类型 [][] 数组名=new 数据类型[二维数组的长度(行)][每个一维数组的长度];
//方式二
数据类型 [][] 数组名 = new 数据类型[二维数组的长度][];
// 二维数组中有3个一维数组。
注: int[][] arr = new int[][3];//非法
//方式三
数据类型 [][] 数组名={{元素},{元素1,元素2}.....};
数组本身是引用数据类型 数组元素可以是任何数据类型
二维数组遍历
用嵌套for循环
嵌套的 增强for循环
- 二维数组的长度
数组名.length 每一个一维数组的长度 数组名[索引值].length
二维数组遍历出来的一个元素都是一个一维数组
l利用二维数组打印一个杨慧三角
import java.util.Scanner;
public class Demo01 {
public static void main(String[] args) {
System.out.println("请输入杨慧三角的行数:");
int n=(new Scanner(System.in)).nextInt();
int [][] a=new int[n][n];
for (int i=0;i<a.length;i++)
for (int j=0;j<=i;j++){
if(i==0||j==i||j==0)
a[i][j]=1;
else
a[i][j]=a[i-1][j]+a[i-1][j-1];
}
for (int i=0;i<a.length;i++){
for (int j=0;j<=i;j++) {
System.out.printf("%-3d\t",a[i][j]);
}
System.out.println();
}
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-haxrmpoW-1603698615890)(java.assets/image-20200821103449581.png)]
10、面向对象
面向过程:当需要实现一个功能的时候,每一个具体的步骤都需要亲力亲为,详细处理每一个细节。
面向对象:当需要实现一个功能的时候,不关心具体的步骤,而是找一个已经具有该功能的人,来帮我做事。
public static void main(String[] args) {
int [] array={10,20,30,40,50};
//要求打印格式为:[10,20,30,40,50]
//使用面向过程
System.out.print("[");
for (int i=0;i<array.length;i++){
if (i==array.length-1){
System.out.println(array[i]+"]");
}
else
System.out.print(array[i]+", ");
}
//面向对象
//找一个jdk给我们提供的类Arrays
//其中有一个toString()方法,直接把数组用我们需要的格式打印
System.out.println(Arrays.toString(array));
}
它区别于面向过程的思想,强调的是通过调用对象的方法的行为来实现功能。
10.1、面向对象的思想举例
洗衣服:
-
面向对象:把衣服脱下来—>打开全自动洗衣机—>扔衣服---->按钮----->晾起来
-
面向过程:把衣服脱下来–>打开全自动洗衣机–>扔衣服–>按钮–>晾起来
-
区别:
- 面向过程:强调步骤。
- 面向对象:强调对象,这里的对象就是洗衣机。
特点
面向对象思想是一种更符合我们思考习惯的思想,它可以将复杂的事情简单化,并将我们从执行者变成了指挥者。
面向对象的语言中,包含了三大基本特征,即**封装
、继承
和多态
**。
1、类和对象
环顾周围,你会发现很多对象,比如桌子,椅子,同学,老师等。桌椅属于办公用品,师生都是人类。那么什么是类呢?什么是对象呢?
什么是类
- 类:是一组相关属性和行为的集合,可以看成是一类事物的模板,使用事物的属性和行为特征来描述该类事物
现实中,描述一类事物
- 属性:就是该事物的状态信息
- 行为:就是该类事物能够做什么
什么是对象
- 对象:是一类事物的具体表现,对象是类的实例,必然是具备该类事物的属性和行为
类和对象的关系
- 类是对一类事物的描述,是抽象的
- 对象是一类事物的实例。是具体的
- 类是对象的目标,对象是类的实体。
2、类的定义
事物与类的对比
现实世界 的一类事物:
- 属性:事物的状态信息
- 行为:事物能够做什么
java中用class描述事物也是如此
- 成员变量:对应事物的属性
- 成员方法:对应事物的行为
类的定义格式
权限修饰符 [class|interface|enum] ClassName{
//成员变量
//成员方法
}
- 定义类:就是定义类的成员,包括成员变量和成员方法。
- 成员变量:和以前定义变量几乎是一样的。只不过位置发生了改变。在类中,方法外。
- 成员方法:和以前定义方法几乎是一样的。只不过把static去掉,static的作用在面向对象后面课程中再详细讲解。
注意;
- 成员变量是直接定义在当前类中方法外的。
- 成员方法不要写
static
访问控制修饰符
Java中,可以使用访问控制符来保护对类、变量、方法和构造方法的访问。Java 支持 4 种不同的访问权限。
-
default (即默认,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。
-
private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)
-
public : 对所有类可见。使用对象:类、接口、变量、方法
-
protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。
修饰符 当前类 同一包内 子孙类(同一包) 子孙类(不同包) 其他包 public
Y Y Y Y Y protected
Y Y Y Y/N N default
Y Y Y N N private
Y N N N N
3、类的使用
通常情况下,一个类并不能直接使用,需要根据类创建一个对象,才能使用。
-
1.导包:也就是指出需要使用的类,在什么位置。
- import包名称.类名称;import cn.itcast.day86.demo81.student;
-
对于和当前类属于同—个包的情况,可以省略导包语句不写。
-
2.创建,
- 格式:类名称对象名= new类名称();student stu = new Student();
-
3.使用,分为两种情况:
- 使用成员变量:对象名.成员变量名
- 使用成员方法:对象名.成员方法名(参数)(也就是,想用谁,就用对象名点儿谁。)
注意事项:
如果成员变量没有进行赋值,那么将会有一个默认值,规则和数组一样。
成员变量和局部变量的区别
- 定义的位置不一样
- 局部变量:在方法内部
- 成员变量:在方法外,类中
- 作用域不同
- 局部变量:只有在方法中才能用
- 成员变量:整个类当中都可以用
- 默认值
- 局部变量:没有默认值
- 成员变量:和数组一样
10.2、类的内存图
一个类的内存图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EIXc6e7B-1603698615891)(java.assets/image-20200825082157052.png)]
两个类的内存图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qML0gncA-1603698615892)(java.assets/image-20200826074229027.png)]
两个类引用指向同一个对象的内存图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gq6J5Y3i-1603698615893)(java.assets/image-20200826074824235.png)]
10.3、使用对象类型作为方法的参数
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RsXFNulF-1603698615894)(java.assets/image-20200826075715183.png)]
10.4、封装
面向对象三大特性:封装、继承 多态
在面向对象程式设计方法中,封装(英语:Encapsulation)是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方法。
封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。
要访问该类的代码和数据,必须通过严格的接口控制。
封装最主要的功能在于我们能修改自己的实现代码,而不用修改那些调用我们代码的程序片段。
适当的封装可以让程式码更容易理解与维护,也加强了程式码的安全性。
封装的优点
- 良好的封装能够减少耦合。
- 类内部的结构可以自由修改。
- 可以对成员变量进行更精确的控制。
- 隐藏信息,实现细节。
实现Java封装的步骤
修改属性的可见性来限制对属性的访问(一般限制为private),例如:
public class Person { private String name; private int age; }
这段代码中,将 name 和 age 属性设置为私有的,只能本类才能访问,其他类都访问不了,如此就对信息进行了隐藏。
对每个值属性提供对外的公共方法访问,也就是创建一对赋取值方法,用于对私有属性的访问,例如:
public class Person{
private String name;
private int age;
public int getAge(){
return age;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age = age;
}
public void setName(String name){
this.name = name;
}
}
采用 this 关键字是为了解决实例变量(private String name)和局部变量(setName(String name)中的name变量)之间发生的同名的冲突。
重写和重载的区别
参数列表 | 必须修改 | 一定不能修改 |
---|---|---|
返回类型 | 可以修改 | 一定不能修改 |
异常 | 可以修改 | 可以减少或删除,一定不能抛出新的或者更广的异常 |
访问 | 可以修改 | 一定不能做更严格的限制(可以降低限制) |
日期和时间的格式化编码
时间模式字符串用来指定时间格式。在此模式中,所有的 ASCII 字母被保留为模式字母,定义如下:
字母 | 描述 | 示例 |
---|---|---|
G | 纪元标记 | AD |
y | 四位年份 | 2001 |
M | 月份 | July or 07 |
d | 一个月的日期 | 10 |
h | A.M./P.M. (1~12)格式小时 | 12 |
H | 一天中的小时 (0~23) | 22 |
m | 分钟数 | 30 |
s | 秒数 | 55 |
S | 毫秒数 | 234 |
E | 星期几 | Tuesday |
D | 一年中的日子 | 360 |
F | 一个月中第几周的周几 | 2 (second Wed. in July) |
w | 一年中第几周 | 40 |
W | 一个月中第几周 | 1 |
a | A.M./P.M. 标记 | PM |
k | 一天中的小时(1~24) | 24 |
K | A.M./P.M. (0~11)格式小时 | 10 |
z | 时区 | Eastern Standard Time |
’ | 文字定界符 | Delimiter |
" | 单引号 | ` |
使用printf格式化日期
printf 方法可以很轻松地格式化时间和日期。使用两个字母格式,它以 %t 开头并且以下面表格中的一个字母结尾。
转 换 符 | 说 明 | 示 例 |
---|---|---|
c | 包括全部日期和时间信息 | 星期六 十月 27 14:21:20 CST 2007 |
F | "年-月-日"格式 | 2007-10-27 |
D | "月/日/年"格式 | 10/27/07 |
r | "HH:MM:SS PM"格式(12时制) | 02:25:51 下午 |
T | "HH:MM:SS"格式(24时制) | 14:28:16 |
R | "HH:MM"格式(24时制) | 14:28 |
11、多线程
11.1、程序、进程、线程概念
程序:是为完成特定任务、用某种语言编写的一组指令的集合。
**进程:**是程序执行一次的过程
注解(Annotation)
(1)概述
Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。
Java 语言中的类、方法、变量、参数和包等都可以被标注。和 Javadoc 不同,Java 标注可以通过反射获取标注内容。在编译器生成类文件时,标注可以被嵌入到字节码中。Java 虚拟机可以保留标注内容,在运行时可以获取到标注内容 。 当然它也支持自定义 Java 标注。
(2)注解的作用
- 不是程序本身,可以对程序作出解释
- 可以被其他程序读取
- 还可以检查和约束程序
(3)注解的格式
注解是以“@注释名”在代码中存在的,还可以添加一些参数值
(4)内置注解
Java 定义了一套注解,共有 7 个,3 个在 java.lang 中,剩下 4 个在 java.lang.annotation 中。
作用在代码的注解是
- @Override - 检查该方法是否是重载方法。如果发现其父类,或者是引用的接口中并没有该方法时,会报编译错误。
- @Deprecated - 标记过时方法。如果使用该方法,会报编译警告。
- @SuppressWarnings - 指示编译器去忽略注解中声明的警告。
作用在其他注解的注解(也就是元注解)是
- @Retention - 标识这个注解怎么保存,是只在代码中,还是编入class文件中,或者是在运行时可以通过反射访问。
- @Documented - 标记这些注解是否包含在用户文档中。
- @Target - 标记这个注解应该是哪种 Java 成员。
- @Inherited - 标记这个注解是继承于哪个注解类(默认 注解并没有继承于任何子类)
(5)作用在代码的几个注解
public class Demo extends Object {
//这就是一个重写的注解,重写该方法
@Override
public String toString() {
return super.toString();
}
//表明该方法已经过时,不推荐使用,但是可以使用
@Deprecated
public static void test(){
System.out.println("hh");
}
//镇压警告,里面的参数由自己定义,还可以直接写在类上面
@SuppressWarnings("all")
public void test1(){
System.out.println("aa");
}
public static void main(String[] args) {
test();//过时的方法上面会有一个斜杠
}
}
1234567891011121314151617181920212223
(6)元注解
元注解的作用就是负责注解其他注解,java定义了四个标准的meta-annotation类型,他们被用来提供对其他annotation类型作说明。
这些类型和他们所支持的类在java.lang.annotation包中可以找到
import java.lang.annotation.*;
@MyAnnotation
public class Demo1 {
public void test(){
System.out.println("aa");
}
}
//表示注解可以用在什么地方
@Target(value = {ElementType.TYPE,ElementType.METHOD})
//表示注解在什么时候还有效,runtime>class>source
@Retention(value = RetentionPolicy.RUNTIME)
//表示是否将我们的注解生成在javadoc中
@Documented
//子类可以继承父类的注解
@Inherited
@interface MyAnnotation{
//通过interface来定义一个注解MyAnnotation
}
1234567891011121314151617181920212223
(7)自定义注解
使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口
public class Demo2 {
//注解可以显示赋值,如果没有默认值default的话,必须给注解赋值
@MyAnnotation1(name ="张三",age = 23)
public void test(){}
}
@Target(value = {ElementType.TYPE,ElementType.METHOD})
@Retention(value = RetentionPolicy.RUNTIME)
@interface MyAnnotation1{
String name() default "";//default代表默认值
int age();
int id() default -1;//默认值为-1代表不存在
}
泛型
(1)概述
是一种把类型明确的工作推迟到创建对象
或者调用方法的时候才去明确的特殊的类型。
参数化类型,把类型当作参数一样的传递。
(2)格式
<数据类型> 这里的数据类型只能是引用数据类型
JDK1.7之前 泛型前面后面都得写上,JDK1.7可以省略右半边不写
(3)好处
1.把运行时期的问题提前到了编译期间
-
避免了强制类型转换
3.优化了程序设计,解决了黄色警告线
注意:泛型只在编译期有效 但在运行期就擦除了4.泛型可以限定,我这个集合中存储什么样的引用数据类型
(4)举例
public class Demo1 {
public static void main(String[] args) {
ArrayList list2 = new ArrayList();
list2.add("aaaaa");
list2.add("bbbb");
list2.add("ccc");
list2.add("ddd");
Object obj = list2.get(0);
String string= (String) obj;
int i=string.length();
System.out.println(i);
//泛型可以避免向下转型
ArrayList<String> list3= new ArrayList();
list3.add("aaaaa");
list3.add("bbbb");
list3.add("ccc");
list3.add("ddd");
String s = list3.get(0);
System.out.println(s);
}
}
结果:
aaaaa
aaaaa
(5)泛型方法
泛型方法概述: 把泛型定义在方法上
定义格式: public <泛型类型> 返回类型 方法名(泛型类型 变量名)
public class MyTest2 {
public static void main(String[] args) {
MyClass<String> stringMyClass = new MyClass<>();
stringMyClass.setT("abc");
String t = stringMyClass.getT();
MyClass<Integer> integerMyClass = new MyClass<>();
integerMyClass.setT(100);
Integer t1 = integerMyClass.getT();
}
class MyClass<T> { //泛型<T> 我把泛型加在类上
T t;
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
}
}
(6)泛型接口
泛型接口概述: 把泛型定义在接口上
定义格式: public interface 接口名<泛型类型>
public class MyTest3 {
public static void main(String[] args) {
//接口上的泛型,在你创建该接口的子类对象时,必须要明确这个泛型,具体是什么数据类型
MyDemo2<Integer, String, String> integerStringStringMyDemo2 = new MyDemo2<>();
Collection<Integer> collection=new ArrayList<Integer>();
//匿名内部类 在创建接口的子类对象时,就必须明确接口上的泛型,到底是什么类型
new MyInterface<String,String,String>(){
@Override
public String show(String s, String s2) {
return null;
}
};
}
interface MyInterface<T,U,R> { //泛型接口
public R show(T t,U u);
}
class MyDemo2<T, U, R> implements MyInterface<T, U, R>{
@Override
public R show(T t, U u) {
return null;
}
}
}
Java反射
1、java反射机制概述
动态语言
-
是一类在运行时可以改变其结构的语言:列如新的函数、对象、甚至代码可以被引进,已有的函数可以被删除或是其他结构上的变化。通俗的讲就是在运行时代码可以根据某些条件改变自身结构。
主要语言有:Object-C、C#、javaScript、PHP Python等
静态语言
- 与动态语言相对应的,运行时结构不可变的语言。比如:java、C、C++
- java不是动态语言,但java可以称为“准动态语言”。即java有一定的动态性,我们可以利用反射机制获得类似动态语言的特性。Java的动态性让编程的变得更加灵活。