java基础总结笔记
java总结笔记
2021年1月26日
java软件工程师;
jdk:Java开发工具包;(下载下来,自带jvm)
jvm:java虚拟机;
window常用Dos命令:
- exit:退出当前Dos命令窗口;
- cls:清除屏幕;
- dir:列出当前目录下的所有子目录/子文件;
- cd:改变路径;
- cd .. 回到上级目录;
- cd \ 直接回到根目录;
- c: 回车 切换盘符;
Java语言的特点
简单性:Java语言不再支持多继承,c++支持多继承,多继承比较复杂;
c++有指针的概念,Java中屏蔽了;
Java语言底层是由c++实现的,不是c;
面向对象:
Java是纯面向对象的语言。
可移植性(跨平台):
Java程序一次编译,不做任何修改可以在window系统,或者Linux系统上运行。
windows和Linux内核肯定是不相同的,两个操作系统执行指令的原理是不相同的。
让Java程序运行在一台虚拟的计算机上,称作Java虚拟机(jvm)Java虚拟机再和底层的操作系统沟通
Java代码不和操作系统直接进行沟通。【java virtual machine:java虚拟机】
多线程:
健壮性:和垃圾回收机制相同,
自动垃圾回收机制,简称GC
Java运行过程中是自动回收产生得垃圾的,不需要程序员关心。
安全性:
Java的加载与执行[两个阶段]
1、编译阶段
- 编译阶段检查Java源程序是否符合Java语法
- 字节码文件不是纯粹的二进制文件,不能直接被操作系统使用
- Java编译阶段过程
编译阶段需在硬盘某个位置建一个.java的源文件(须符合Java语法规则),检查Java源文件是否符合Java语法规则,符合则生成.class文件
使用JDK中自带的javac.exe编译源文件
[javac在Dos命令窗口中使用(javac java源文件路径)
javac是Java的一个编译器工具]
一个.java文件可以通过javac编译生成多个.class文件,删除Java源文件不影响程序的执行。
编译结束之后可以将.class文件拷贝到其他的操作系统上执行[跨平台]
- .java 源文件
- .class 字节码文件 编译 验证源文件是否符合Java语法规范 编译成字节码文件
2、运行阶段(可以在其他操作系统中,跨平台)
- JDK安装之后自带两个命令/工具 javac.exe 、java.exe;javac.exe编译 java.exe运行
- java.exe 在Dos命令窗口中使用;【java 类名】
- 不要写成 java xx.class 是错误的
- java xx
- 运行阶段的过程
- Dos命令窗口输入 java xx
- java.exe启动Java虚拟机(jvm),java虚拟机启动类加载器classLeader
- classLeader去硬盘扫描xx.class文件,找到该文件并将字节码文件装载到jvm
- jvm将字节码文件解释成二进制文件
- 操作系统执行二进制和底层硬件平台进行交互
2021年1月27日
JDK包含JRE,JRE包含JVM
Java注释
- 单行注释
// 单行注释 - 多行注释
/*
多行注释
多行注释
*/ - javadoc注释
/**
*javadoc注释
*javadoc注释
*javadoc注释
*/
注意:javadoc注释是专业的注释,该注释信息会被javadoc.exe工具解析提取,并生成帮助文档。
对HelloWorld.java程序进行解释
- public
- class
- static
- void
- System.out.println(""); 向控制台输出消息
- 类体
- 方法体
- 类体中不能直接编写Java语句【除声明变量外】
- 方法体中可以编写多条Java语句
- 一个Java语句必须以“;”结束
- 主方法是程序入口,SUN规定的。
2021年1月30日
class 和 public class的区别
/* 一个Java源程序文件中可以定义多个class
* 一个Java源程序文件当中的public class 不是必须的
* 一个class会定义一个xxx.class字节码文件
* 一个Java源程序文件中定义公开的类的话,只能有一个,且必须与Java源文件名称一致。
* 每个class中都可以编写main方法,设置程序的入口,想执行B.class中的main方法
* - java B
*
*/ 注意:执行B.class,其中必须有main方法,没有则会出现运行阶段的错误
总结一:
1、java的加载与执行;
2、搭建Java开发环境
3、编写HelloWorld程序,编译并运行
4、环境变量path的配置及原理;
5、classpath的原理及配置;
6、Java中的注释
7、class和public class的区别
Java语言基础
java语言中的标识符:
1)java语言中的标识符:
1、 什么是标识符?
- java源程序中凡是程序员有权利自己命名的单词都是标识符
- 标识符在EditPlus中黑色高亮字体
- 标识符可以标识的元素* 类名* 方法名* 变量名* 接口名* 常量名...
2、标识符命名规则?【不按照这个规则,编译器会报错,这个语法规则】* 标识符只能由“字母,数字,下划线_,美元符号$”组成* 不能以数字开头* 严格区分大小写* 不能是关键字* 理论上无长度限制,但理论上不能过长3、标识符的命名规范? 【只是一种规范,不是语法,不遵守编译器不会报错,】* 最好见名知义public class UserService{public void login(String username,String password){}}* 遵守驼峰式命名方式SystemServiceUserServiceCustermerService* 类名,接口名首字母大写,后面每个单词首字母大写* 变量名,方法名,首字母小写,后面每个单词首字母大写* 常量名,全部大写
Java语言中的关键字:
Java语言中的字面值
关于字面值
* 字面值(在Java中叫做字面值,在C语言中,叫做常量)- 10、100- 3.14- false、true- "abc"- 'a'
* 字面值就是数据
* 字面值是Java源程序的组成部分之一,包括标识符和关键字都是Java源程序的组成部分。
* 数据在现实生活中是分门别类的,在编程语言中也是分类型的(数据类型)- 10、100 整型字面值- 3.14 浮点型字面值- false、true 布尔型字面值- "abc" 、"中国人" 字符串型字面值- 'A'、'人' 字符型字面值- 注意:Java中字符串型字面值必须使用""双引号括起来,双引号必须是半角的。Java中字符型字面值必须使用单''引号括起来,单引号必须是半角的。
总结二:
- 标识符
- 关键字
- 字面值
- 变量
- 数据类型
Java语言中的变量:
1、什么是变量?
* 变量本质上是内存中的一块空间,这块空间有“数据类型”、“名字”、“字面值”
* 变量包括三个部分:数据类型、名字、字面值【数据】
* 变量是内存中存储数据的最基本单元。2、数据类型的作用?
* 不同的数据拥有不同的类型,不同的数据类型底层会分配不同大小的存储空间。
* 数据类型是指导程序在运行阶段分配不同大小的存储空间。3、变量要求:变量中存储的具体的数据,必须和变量的"数据类型"相一致。4、定义/声明变量的语法格式:只要是合法的标识符即可;变量名遵循的规范:首字母小写,后面每个单词首字母大写;数据类型 变量名;int i; int age; int num;5、变量声明之后,如何赋值?格式:变量名 = 字面值;注意:字面值的数据类型必须和变量名声明的数据类型相一致例如:int i;i = 10;int i = 10;System.out.println(i); // 10int i = 100;System.out.println(i); // 100int i = 1000;System.out.println(i); // 10006、有了变量的概念之后,内存空间得到了重复利用。7、通常访问一个变量有两种方式:* 读取变量中的数据 get/获取* 修改变量中的数据 set/修改i = 10 // setSystem.out.println(i); // get
变量的作用域:
1、什么是变量的作用域?
变量的作用域是描述变量的有效范围
在什么范围内可以被访问,出了这个范围就不能被访问了
2、出了大括号就不认识了
变量的分类:
- 根据作用域的不同进行分类局部变量:方法体内声明【存放在栈内存中】成员变量:方法体外声明,类体内声明* 实例变量【存放在堆内存中】* 静态变量【存放在方法区内存中】- 在不同的作用域当中,变量名可以一样;在同一个作用域当中,变量名不能重名。
静态变量的说明图:
Java中的数据类型:
1、 数据类型的作用?
程序当中有很多数据,每个不同的数据,有不同的类型,数据的数据类型不同,占用的存储空间不同。
数据类型的作用:指导JVM在运行程序的时候,分配多大存储空间
2、Java中的数据类型包括:
基本数据类型有四大类八小种
第一类:整数型
byte,int,short,long
第二类:浮点型
float,double
第三类;布尔型
boolean
第四类:字符型
char
3、 关于基本数据类型:
4、字符串不属于基本数据类型 “abc” ,属于“引用数据类型”,字符型属于“基本数据类型”
- 字符串用双引号括起来"abc"
- 字符用单引号括起来’人’
5、八种基本数据类型所占的内存空间大小
基本数据类型 所占内存空间大小[单位:字节]------------------------------------------------byte 1short 2int 4long 8float(单精度浮点型) 4
double(双精度浮点型) 8boolean 1char 2
6、基本数据类型之间的转换:转换规则(六条基本规则)
1、 八种数据类型,除Boolean类型外,其他七种类型都可以相互转换2、 小容量向大容量转换:自动类型转换;容量从小到大
byte < short < int < long < float < double< char < 注意:任何浮点型不管占用多少字节容量都大于整数型char和short表示的种类数相同,但是char可以表示更大的正整数3、大容量向小容量转换,:强制类型转换,需要强制类型转换符;程序才能编译通过。
但是在运行阶段,有可能会损失精度,谨慎使用4、当整数型字面值没有超出byte,short,char的取值范围时,可以直接赋值给byte,short,char类型的变量5、 byte short char进行混合运算时,需要先转换成int类型再进行运算6、多种数据类型混合运算,先转换成容量最大的那种,再进行运算// 编译期只检查语法,运算期进行运算
7、计算机在任何情况下只识别二进制,例如:011101001010010010…
【现代计算机底层采用交流电的方式,只有接通,断开两种状态;接通1,断开0,只识别二进制】
8、什么是二进制
* 是一种数据的表示形式* 十进制是满十进一,二进制是满二进一例如:0 1 10 11 100 101 110 111 1000
8、字节:
1 byte = 8 bit【1个字节 = 8个比特位】一个比特位就是一个二进制位(一个0或者一个1)
1 KB = 1024 byte1 MB = 1024 KB1 GB = 1024 MB1 TB = 1024 GB1 TB = 1 * 1024 * 1024 * 1024 * 1024 * 8 【1T能存这么些1和0】
9、整数型当中的byte类型,占用1个字节,8个比特位,即8个二进制位。byte类型的取值范围是多少?
* Java中的数字类型,数字有正负之分,所以二进制位中有一个位叫做"符号位",并且这个二进制位在所有二进制位的最左边,0代表正,1代表负。* byte类型的最大值:01111111 (10000000[二进制] - 1)* byte类型的最大值:2的7次方减1 ;结果是: 127* byte类型最小值:-128【具体的怎么使用二进制,这个和原码,补码,反码相关】* byte类型的取值范围:-128 ~ 127* byte类型可以表示256个不同的数字【可以表示256个不同的二进制】
10、二进制和十进制的转换规则
- 二进制转十进制
- 十进制转二进制
11、计算机只认识二进制,那么如何表示现实生活中的文字?
* byte、short、int、long、float、double、boolean这七种数据类型,底层都是十进制数字,
十进制数字和二进制之间存在一种转换规则。容易表示。
但是char类型是现实生活中的文字,文字和二进制之间"默认"没有转换关系。
为了让计算机认识现实生活中的文字,人为的制定好“二进制”和“文字”之间的对应关系,
称为“字符编码”计算机最初只支持英文,最早的字符编码是“ASCII码”。
‘a’ ---->97【01100001】
‘A’ ---->65
‘0’ ---->48‘a’ --(按照ASCII码解码)–> 01100001
01100001 --(按照ASCII编码)–> ‘a’编码/解码按照同一套字典/对照表,进行编码解码不会出现乱码现象
当编码解码时采用的不是同一套对照表时,就会出现乱码现象【这是出现乱码的根本原因】
12、关于八种数据类型的默认值:
数据类型 默认值byte/short/int/long 0float double 0.0boolean false【在C语言中false是0,true是1】char \u000八种数据类型默认值向0看齐
13、 关于Java语言当中的整数型:
byte sort int long
1)、Java语言当中的“整数型字面值”,默认使用int类型处理,要让这个int类型当作“long类型”来处理,
后面加l\L建议使用大写的L;
2)、Java语言当中整数型字面值有三种表示形式:
十进制:是一种缺省默认的方式
八进制:在编写八进制整数型字面值的时候需要以0开始
十六进制:编写十六进制整数型字面值的时候需要以0x开始
// 456整数型字面值被当作int类型,占用4个字节;// x变量在声明的时候,被声明为long类型,占用8个字节;// int类型字面值456赋给long类型的x,存在类型转换// int类型是小容量// long类型是大容量// 小容量可以自动转换成大容量,称为自动类型转换机制;long x = 456;System.out.println(x);
基本数据类型
整数型(byte, short, int, long)
/*关于Java语言当中的整数型:数据类型 占用空间大小 取值范围 默认值-----------------------------------------------------------byte 1 -128 ~ 127 0sort 2 -32768 ~ 32767 0int 4 -2147483648 ~ 2147483647 0long 8 0L-----------------------------------------------------------1、Java语言当中的“整数型字面值”,默认使用int类型处理,要让这个int类型当作“long类型”来处理,后面加l\L建议使用大写的L;2、Java语言当中整数型字面值有三种表示形式:十进制:是一种缺省默认的方式八进制:在编写八进制整数型字面值的时候需要以0开始十六进制:编写十六进制整数型字面值的时候需要以0x开始
*/
public class DataTypeTest04
{public static void main(String[] args){int a = 10; // 十进制int b = 010; // 八进制 整数型字面值以0开头的后面的数字就是八进制int c = 0x10; // 十六进制 整数型字面值以0x开头的后面的数字就是十六进制System.out.println(a); // 10System.out.println(b); // 8System.out.println(c); // 16System.out.println(a + b + c); // 34 以十进制的形式输出// 456整数型字面值被当作int类型,占用4个字节;// x变量在声明的时候,被声明为long类型,占用8个字节;// int类型字面值456赋给long类型的x,存在类型转换// int类型是小容量// long类型是大容量// 小容量可以自动转换成大容量,称为自动类型转换机制;long x = 456;System.out.println(x);// 2147483647是int类型,占用4个字节;// y是long类型占用8个字节,自动类型转换long y = 2147483647;System.out.println(y);// 编译错误:过大的整数// 2147483648一上来就被当作int类型4个字节处理,但是字面值超出int类型范围// long z = 2147483648;// System.out.println(z);// 处理错误// 2147483648字面值一上来就当作long类型处理,字面值后面加L// 2147483648L是8个字节的long类型// z是long类型,因此一下程序不存在类型转换long z = 2147483648L;System.out.println(z);}
}
/*关于Java语言当中整数型byteshortint long原码,1100110011反码,1011001100(除符号位,按位取反)补码,1011001101(负数的补码:除符号位,按位取反再加1)正整数的补码与其原码相同*/public class DataTypeTest05
{public static void main(String[] args){// 100是long类型字面值// x是long类型字面值// 不存在类型转换long x = 100L;// 大容量向小容量转换,需要强制类型转换// 强制类型转换需要加“强制类型转换符”// 大容量向小容量强制类型转换会损失精度// 谨慎使用// 以下代码编译报错,大容量不能直接赋值给小容量,需要加强制类型转换符。// int y = x;// 强转原理// 原始数据:00000000 00000000 00000000 00000000 00000000 00000000 01100100// 强转之后的数据:00000000 00000000 00000000 01100100// 将左边的二进制砍掉【所用的数据强转都是一样的】int y = (int)x;System.out.println(y);// 原始数据: 00000000 00000000 00000000 00000000 100000000 00000000 00000000 00000000// 强转之后的数据:100000000 00000000 00000000 00000000// 计算机存储数据都是采用补码的形式存储数据,100000000 00000000 00000000 00000000以补码的形式存储在计算机中// 所以100000000 00000000 00000000 00000000现在是补码的形式// 将补码转换成原码就是最终结果long k = 2147483648L;int e = (int)k;System.out.println(e); // 损失精度严重,结果为负数【-2147483648】// 50是int类型字面值,b是byte类型字面值,显然是大容量转小容量,需要强制类型转换符// 但是在实际编译中,可以编译通过,只要在byte类型的取值范围中就可以byte b = 50; // 编译通过byte b1 = 127; // 编译通过byte b2 = 128; // 编译报错/*当一个整数型字面值没有超出 byte short char 的取值范围,可以直接赋值给byte short char 类型的变量这种机制SUN允许了,目的是方便程序员编程*/}
}
字符型(char)
/*
Java数据类型之数据类型:char
*/
public class DataTypeTest01
{public static void main(String[] args){// 定义一个char类型的变量,起名为c,赋值为‘a’char c = 'a';char x = '国';System.out.println(c);// 一个中文占用2个字节,一个char类型变量刚好2个字节// 所以Java中的char类型变量可以存储一个中文字符System.out.println(x);// 编译错误// ab是字符串,不能使用单引号括起来// char y = 'ab';// 类型不兼容,需要的char给出的是String// char z = "a";}
}
/*
关于八种数据类型的默认值:数据类型 默认值byte/short/int/long 0float double 0.0boolean false【在C语言中false是0,true是1】char \u000八种数据类型默认值向0看齐*/
public class DataTypeTest02
{// 必须加staticstatic int k = 1000; // 成员变量static int f; // 成员变量public static void main(String[] args){System.out.println(k);// 成员变量没有手动赋值的时候系统会默认赋值【局部变量不会默认赋值】(没有违背变量需要先声明,再赋值才能访问,只不过是系统默认赋值)System.out.println(f); // 0 /*必须声明并赋值才可以访问,没有赋值不能访问int i; // 局部变量System.out.println(i);*/}
}
/* 关于Java语言中的char类型:转义字符 \ 转义字符出现在特殊字符之前,会将特殊字符转义成普通字符\n 换行符\t 制表符\\ 普通的反斜杠\' 普通的单引号\" 普通的双引号*/
public class DataTypeTest03
{public static void main(String[] args){char c1 = 'n'; // 普通的nSystem.out.println(c1);// 反斜杠在Java语言中具有转义功能char c2 = '\n'; // 此处的\n不是字符串而是"换行符"、是char类型,【占一个字符】System.out.println(c2);// System.out.print()和System.out.println()的区别:// print()表示输出之后不换行,println()表示输出之后换行/*System.out.print("Hello");System.out.println("World!");System.out.println("Hello");System.out.println("World!");*/// 制表符tab:\t// tab和空格不同,体现的ASCII不一样char y = '\t';System.out.print('A');System.out.print(y);System.out.println('B');// 在控制台上输出一个普通的反斜杠字符“\”// 编译报错,反斜杠将后一个单引号转义成普通的单引号字符// char b = '\';// System.out.print(b);// 第一个反斜杠将后一个反斜杠转义成普通的反斜杠字符char a = '\\';System.out.println(a);// 在控制台上输出一个普通的单引号字符char c = '\''; // 转义字符将其后面的单引号字符转义成普通的单引号字符System.out.println(c);// 在控制台输出带英文双引号的HelloWorld!System.out.println("“HelloWorld!”"); // 中文的双引号System.out.println("\"HelloWorld!\""); // 英文的双引号// 命令:native2ascii.exe 将中文转换成unicode编码形式}
}
/*十进制:二进制:0 1 10 11 110 111 1110 1111 ...十六进制:0 1 2 3 4 5 6 7 8 9 a b c d e f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20满十六进一八进制:0 1 2 3 4 5 6 7 10 11 12 13 14 15 16 17 20 ...满八进一*/
浮点型(float)
/*关于浮点型数据类型:float : 单精度 4个字节double:双精度 8个字节(比较而言精度较高)double类型精度较低,不适合做财务,SUN给程序员准备了引用数据类型java.math.BigDecimalSE类库源码:C:\Program Files\Java\jdk-14.0.2\lib\src.zipSE类库字节码:例如:String.java 和 String.class 我们得(String[] args)中得String就是使用得String.class字节码文件在Java语言当中所有的浮点型字面值都被当作double类型来处理,要想该字面值当作float类型来处理,在字面值后加F\f即可注意:double和float在计算机中存储的时候都是近似值*/
public class DataTypeTest06
{public static void main(String[] args){// d是double类型的字面值// 3.0是double类型的字面值// 不存在类型转换double d = 3.0;// 编译报错// f是float类型的字面值// 5.1是double类型的字面值// 大容量向小容量转换要加强制类型转换符// float f = 5.1;// 解决方案:// 第一种方案:float f = (float)5.1; // 强制类型转换// 第二种方案:float f = 5.1F; // 没有类型转换}
}
布尔型(boolean)
/*Java语言当中数据类型:关于布尔型数据类型:boolean在Java语言当中Boolean只有两个值:true false 不像C语言可以用0和1表示假真在底层存储的时候boolean类型占用一个字节,因为实际存储的时候,true是1,false是0;boolean类型在实际开发中非常重要,常用在逻辑运算,条件控制语句当中*/
public class DataTypeTest07
{public static void main(String[] args){// 编译错误:不兼容的类型 int无法转换为boolean// boolean flag = 1;boolean loginSuccess = true;if(loginSuccess){ // if条件控制语句System.out.println("恭喜你!登录成功!!");}else{System.out.println("登录失败,用户名不存在,或者密码错误!!");}}
}
double
引用数据类型
类
接口
数组
字符串
…
总结三:
- 标识符
- 关键字
- 字面值
- 变量
- 数据类型
- 运算符
算数运算符
关系运算符
算数运算符
条件运算符
三元运算符
总结四:
控制语句:
选择结构:
- if;if…else;if … else if …
- switch
循环结构:for
while
do…while
控制循环语句:break
continue
2021/3/6
break:
1、break是Java语言的一个关键字,意为“中断/折断”
2、break;可以称为一个单独的语句
3、break用在switch语句中用来中止是switch语句的执行
4、break同样可以用在循环语句中,用来终止循环语句的执行
5、break用在for、while、do…while中用来跳出循环,终止当前循环执行
6、默认情况下break终止离他最近的循环。
练习题:
编写for循环输出1 ~ 100 中的所有素数,并每8个素数换一行[可以被自身及1整除的数,不能被其他数整除的数]
2 3 5 7 9 11 13 17 …实现思路:
7 / 1【不需要】
7 / 2
7 / 3
7 / 4
7 / 5
7 / 6
7 / 7【不需要】
知识点:
* for循环
* for循环的嵌套
* 标记
* break的使用
* 统计机制
- switch
引用数据类型:
String是典型的引用数据类型
特点:
1、可以在变量初始化的时候赋值为null,赋值为null表示这个引用类型变量中保存的地址为空;
2、引用数据类型和基本数据类型的区别:
int i1= 1;
int i2= 2;
i1、i2会在内存中存储两个1的值
String j1 = "hello";String j2 = "hello";这种只能在内存中存储一个hello值【两个变量用一块相同的内存地址】
2021/3/8
总结五:
Java语言基础:
- 标识符
控制语句:
选择控制语句:
if
/*java语言当中的条件控制语句\分支语句;属于选择结构;1、四种编写方式;第一种结构:if(布尔表达式){Java语句;Java语句;Java语句;...}第二种结构:if(布尔表达式){Java语句;Java语句;Java语句;...}else{Java语句;Java语句;...}第三种结构:if(布尔表达式){java语句;Java语句;...}else if(布尔表达式){Java语句;Java语句;...}else if(布尔表达式){Java语句;Java语句;...}...第四种编写方式:if(布尔表达式){java语句;Java语句;...}else if(布尔表达式){Java语句;Java语句;...}else if(布尔表达式){Java语句;Java语句;...}else{Java语句;...}2、重点:java语言当中的if语句,只要有一个分支执行,整个if语句结束3、注意:带有else的if语句,肯定有一个分支执行4、所有的"控制语句"都是可以嵌套使用的5、if语句中有一条Java语句,大括号可以省略不写if(true\false){一条Java语句;}if(true\false)一条java语句;*/
public class IfTest01
{public static void main(String[] args){// 需求:如果距离小于5公里,就去吃KFCdouble distance = 1;if (distance < 5){System.out.println("我们去kfc,吃开封菜!!");}// 需求:/* 成绩:成绩可能带有小数,且区间为[100-0][90-100] a[80-90) b[70-80) c[60-70) d[0-60) e// 瑕疵编写方式double score = 90;if (score >= 90){System.out.println('a');}else if (score >= 80){System.out.println('b');}else if (score >= 70){System.out.println('c');}else if (score >= 60){System.out.println('d');}else{System.out.println('e');}// 正确编写方式1double score = 59.5;score = -100;if ( score < 0 | score > 100 ){System.out.println("该考生的成绩是不合法的!");}else if ( score >= 90 ){System.out.println("该考生的成绩为A等级!");}else if ( score >= 80 ){System.out.println("该考生的成绩为B等级!");}else if ( score >= 70 ){System.out.println("该考生的成绩为C等级!");}else if ( score >= 60 ){System.out.println("该考生的成绩为D等级!");}else if ( score < 60 ){System.out.println("该考生的成绩为E等级!");}*/// 方式2double score = 59.5;char q = 'c';if ( score < 0 | score > 100 ){System.out.println("该考生的成绩是不合法的!");}else if ( score >= 90 ){q = 'A';}else if ( score >= 80 ){q = 'B';}else if ( score >= 70 ){q = 'C';}else if ( score >= 60 ){q = 'D';}else if ( score < 60 ){q = 'E';}System.out.println("该考生的成绩为"+q+"等级!");}
}
/*需求:年龄从键盘输入年龄的每个阶段,要求年龄在[0-150][ 0-5 ] 幼儿[ 6-10 ] 少年[ 11 - 18 ] 青少年[ 19 - 35 ] 青年[ 36 - 55 ] 中年[ 56 - 150 ] 老年
*/
public class IfTest02
{public static void main(String[] args){// 1、接收键盘输入:年龄【必须为数字】java.util.Scanner s = new java.util.Scanner(System.in);System.out.print("请输入测试人年龄:"); // 输入提示信息int age = s.nextInt(); // 停下来等待用户输入,输入之后自动接收,赋值给age变量System.out.println("测试人年龄为:"+age);// 2、根据需求,进行业务逻辑判断String str = "老年";if ( age < 0 | age > 150 ){str = "您输入的年龄不合法,年龄应该在[1-150]之间";}else if ( age >= 56 ){str = "老年";}else if ( age >= 36 ){str = "中年";}else if ( age >= 19 ){str = "青年";}else if ( age >= 11 ){str = "青少年";}else if ( age >= 6 ){str = "少年";}else if ( age >= 0 ){str = "幼年";}System.out.println("您的年龄阶段为:"+str);}
}
/* 判断当前的天气: 当外面下雨的时候: 带雨伞: 判断性别: 男士:带一把大黑伞 女士:带一把小花伞 当外面不下雨的时候: 判断外面温度: 当天气温度在30度以上: 判断性别: 男士:戴墨镜 女士:打遮阳伞 要求: 1、天气状况、温度、性别键盘键入;[weather temperature gender] 天气状况:1表示晴天、0表示雨天 温度直接使用数字表示 性别:1表示男,0表示女 2、要用嵌套*/public class IfTest03{ public static void main(String[] args){ // 创建键盘扫描对象 java.util.Scanner s = new java.util.Scanner(System.in); // 接收天气状况 System.out.print("请输入天气状况【雨天/晴天】:"); int weather = s.nextInt(); // 接收性别 System.out.print("请输入性别:"); int gender = s.nextInt(); if (weather == 0) { if (gender == 1) { System.out.println("下雨天男士带一把大黑伞"); }else if (gender == 0) { System.out.println("下雨天女士带一把小花伞"); }else{ System.out.println("您的性别是怎么回事?"); } }else if (weather == 1) { // 接收温度状况 System.out.print("请输入温度:"); int temperature = s.nextInt(); if (temperature >= 30){ if (gender == 1) { System.out.println("温度过高男士戴墨镜"); }else if(gender == 0) { System.out.println("温度过高女士抹防晒霜"); } } }else { System.out.println("您输入的天气状况不存在!!!"); } }}
/**/
public class IfTest04
{public static void main(String[] args){boolean gender = true;/*编译错误:12行,else缺少if;12行以上没有语法错误if (gender == false)System.out.println("男1");System.out.println("男2");else System.out.println("女");if语句中没有加大括号,if语句中有一条Java语句即上面的相当于if (gender == false){System.out.println("男1");}System.out.println("男2"); // 这条语句与if语句没有关系else // else缺少ifSystem.out.println("女");*/}
}
- if、if…else
- switch
循环控制语句:
for
/*1、for循环的语法结构: for(初始化表达式;布尔表达式;更新表达式){ 需要重复执行的代码片段【循环体】 }2、for循环的执行过程,执行原理 ***** 2.1初始化表达式、布尔表达式、更新表达式都不是必须的,但是两个分号是必须的 2.2初始化表达式最先执行,且仅仅执行一次 2.3布尔表达式的值只能是true或者false不能是其他值 2.4for循环执行原理:【逆时针旋转】 * 先执行初始化表达式,且仅执行一次 * 再执行布尔表达式: 布尔表达式为true 执行循环体 执行更新表达式 执行布尔表达式: 布尔表达式为true 执行循环体 执行更新表达式 布尔表达式为false 循环结束 布尔表达式为false 循环结束 3、循环结构: for... while... do...while... */public class ForTest01{ public static void main(String[] args){ // 输出1 ~ 10 十个数字 for (int j = 0; j <= 10; j += 1) // j = j + 1; j ++ { System.out.println("j----->" + j); } // 这里‘j’变量的作用域仅仅是整个for循环 for (int j = 0; j < 10; j ++) { System.out.println("j----->>" + j); } int j = 0; for (; j < 10; j++) { System.out.println("j=====>》" + j); // 输出0 ~ 9 } System.out.println("最后:" + j); // 10 }}
public class ForTest02{ public static void main(String[] args){ // 输出1~10中的奇数 for (int i = 1; i <= 10; i+=2) { System.out.println(i); } // 输出1~10中的偶数 for (int i = 2; i <= 10; i += 2) { System.out.println(i); } // for循环变形 for (int i = 1; i < 10; ) { System.out.println(i); // 1 2 3 4 5 6 7 8 9 i ++; } for (int i = 1; i < 10; ) { i ++; System.out.println(i); // 2 3 4 5 6 7 8 9 10 } }}
/*循环语句,条件判断语句嵌套使用:
*/
public class ForTest03
{public static void main(String[] args){// 求1 ~ 100的奇数// 第一种方案:for (int i = 1; i <= 100; i += 2){System.out.println(i);}// 第二种方案:for (int i = 1; i <= 100; i ++){if (i % 2 != 0) // 这个括号中加boolean类型{System.out.println(i);}}}
}
// 求1 ~ 100所有奇数的和public class ForTest04{ public static void main(String[] args){ // 定义一个变量【盒子】存放累加的数据 int sum = 0; for (int i = 1; i <= 100; i += 2) { sum += i; } // for循环结束,输出累加的结果 System.out.println("sum = "+ sum); // 第二种方式: // 清零 sum = 0; for (int i = 1; i <= 100; i++) { if (i % 2 != 0) { sum += i; } } System.out.println("sum==>"+sum); }}
/* for循环的嵌套使用*/public class ForTest06{ public static void main(String[] args){ // for循环的嵌套使用【最终输出10个0 1 2】 for (int i = 1; i <= 10; i++) // 共循环10次 { // 这是循环体,无论是什么均需要执行10次 for (int j = 0; j <3; j++)// 共循环三次 { System.out.println(j); } } System.out.println("======================================="); for (int i = 0; i < 10; i++) // 循环10次【循环输出0 1 2 3三十次】 { for (int j = 0; j < 3; j++) // 循环3次 { System.out.println("Java程序员起步!!-->for循环"); for (int k = 0; k < 4; k++) // 循环4次输出0 1 2 3 { System.out.println("k==>"+k); } } } }}
/* for循环嵌套*/public class ForTest07{ public static void main(String[] args){ for (int i = 1; i <= 5; i++) { System.out.println("开始"+i); for (int j = 1; j <= 5; j++) { System.out.println(j+"-----"+(i * j)); } System.out.println("结束"); } }}
/* for循环嵌套: 输出9*9乘法表 1*1=1 2*1=2 2*2=4 3*1=3 3*2=6 3*3=9 4*1=4 4*2=8 4*3=12 4*4=16 5*1=5 5*2=10 5*3=15 5*4=20 5*5=25 6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36 7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49 8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64 9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81# python实现99乘法表for i in range(1, 10): for j in range(1, i + 1): print("%d * %d = %d" % (i, j, i * j), end=" ") print("")*/public class ForTest08{ public static void main(String[] args){ for (int i = 1; i < 10; i++) { for (int j = 1; j < 10; j++) { System.out.println(i + "*" + j + "=" + (i*j)); } } /* 乘法表重复: 1*1=1 1*2=2 1*3=3 1*4=4 1*5=5 1*6=6 1*7=7 1*8=8 1*9=9 2*1=2 2*2=4 2*3=6 2*4=8 2*5=10 2*6=12 2*7=14 2*8=16 2*9=18 3*1=3 3*2=6 3*3=9 3*4=12 3*5=15 3*6=18 3*7=21 3*8=24 3*9=27 4*1=4 4*2=8 4*3=12 4*4=16 4*5=20 4*6=24 4*7=28 4*8=32 4*9=36 5*1=5 5*2=10 5*3=15 5*4=20 5*5=25 5*6=30 5*7=35 5*8=40 5*9=45 6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36 6*7=42 6*8=48 6*9=54 7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49 7*8=56 7*9=63 8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64 8*9=72 9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81 */ System.out.println("======================================="); for (int i = 1; i < 10; i++) { for (int j = 1; j <= i; j++) { System.out.print(i + "*" + j + "=" + (i*j) + " "); } // 每一行输出结束换行 System.out.println(); // 换行 // System.out.println("\n"); // 换行【空一行】 } /* 运行结果: 1*1=1 2*1=2 2*2=4 3*1=3 3*2=6 3*3=9 4*1=4 4*2=8 4*3=12 4*4=16 5*1=5 5*2=10 5*3=15 5*4=20 5*5=25 6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36 7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49 8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64 9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81 */ }}
/*编写for循环输出1 ~ 100 中的所有素数[可以被自身及1整除的数,不能被其他数整除的数]2 3 5 7 9 11 13 17 ...实现思路:7 / 1【不需要】7 / 2 7 / 37 / 47 / 57 / 67 / 7【不需要】知识点:for循环for循环的嵌套标记break的使用统计机制*/
public class ForTest09
{public static void main(String[] args){ /*// 1既不是素数,也不是合数for (int i = 2; i <= 1000; i++) // 外层for循环只负责取i值{boolean flag = true; // 默认将i看作素数【标记在开发中经常使用】for (int j = 2; j < i; j++) {if (0 == i % j){// 非素数flag = false;// 知道i不是素数,跳出循环,不加break效率低,一直往下除,直到除完为止break;} }if (flag){ System.out.print(i + " ");}// System.out.print(flag ? i + "是素数" : i + "不是素数" + " ");}*/// 加入统计机制【每8个数字换一行】/*// 对8求余数的写法int count = 0;for (int i = 2; i <= 100; i++){boolean flag = true;for (int j = 2; j < i; j++){if (i % j == 0){flag = false;break;}}if (flag){System.out.print(i + " ");count ++;if (count % 8 == 0){System.out.println();}}}*/// 对count清零的写法int count = 0;for (int i = 2; i <= 100; i++){boolean flag = true;for (int j = 2; j < i; j++){if (i % j == 0){flag = false;break;}}if (flag){System.out.print(i + " ");count ++;if (count == 8){System.out.println();count = 0; // 归零}}}}
}
/*升级版:要求输出1 ~ 100之间的素数,每八个输出一行
*/
while
/* 1、while循环的语法结构 while (布尔表达式){ 循环体; } 2、while循环的执行原理 先判断布尔表达式的结果: 布尔表达式为true: 执行循环体; 判断布尔表达式的结果: 为true: 执行循环体; ... 为false: 循环结束; 布尔表达式为false: 循环结束; 3、while循环的循环次数 */// 关系运算符在运行期才会得出结果public class WhileTest01{ public static void main(String[] args){ // 编译通过 /* int i = 10; int j = 5; // 程序未运行,不知道i > j 是true还是false while (i > j) // 关系运算符在运行期才会得出结果 { System.out.println("死循环"); } System.out.println("编译通过,关系运算符,在运行阶段才会得出结果,因此没有报错!"); */ // 编译报错 /* while (true) { System.out.println("死循环"); } System.out.println("编译报错,因为这条语句永远无法执行!"); // 错误: 无法访问的语句 */ }}
/* while循环输出1~10*/public class WhileTest02{ public static void main(String[] args){ int i = 1; while (i <= 10) { System.out.println(i); // i += 1; // i ++; i = i + 1; } System.out.println("====>"+i); // 11 System.out.println("========================================================="); int j = 10; while (j >= 0) { System.out.println(--j); // 9 8 7 6 5 4 3 2 1 0 -1 System.out.println("===>"+j); // 9 8 7 6 5 4 3 2 1 0 -1 } System.out.println("---->>>>"+j); // -1 }}
do…while()
/* do...while循环: 1、do...while循环的语法结构 do{ 循环体; }while(布尔表达式); // 最后有个分号,注意别丢了 2、do...while循环的执行原理 3、do...while循环的循环次数 * do...while循环的循环体至少循环一次【1~N次】 4、do...while循环的注意事项 * do...while循环最后有个分号,注意别丢了*/public class DoWhileTest01{ public static void main(String[] args){ int i = 10; do { System.out.println(i); } while (i > 100); // 输出10 System.out.println("====================================="); int j = 10; while (j > 100) { System.out.println(j); } // 没有输出 System.out.println("====================================="); int k = 1; do { System.out.println(k); // 1 2 3 4 5 6 7 8 9 10 k ++; } while (k <= 10); }}/* 总共三个循环语句: for while do...while*/
控制循环语句:
- break - continue
面向对象【Java语言的核心机制】
- 关键字- 字面值- 变量- 数据类型*** * 二进制 * 字符编码- 运算符- 控制语句*****- 方法***- 递归
面向过程和面向对象的区别【盖饭和蛋炒饭】
耦合:就是事物与事物之间的相关程度 - 面向过程: 主要关注点是:具体的实现过程,因果关系【集成显卡的开发思路】 * 优点:对于业务逻辑简单的程序,可以达到快速开发,前期投入较低 * 缺点:采用面向过程的方式开发,很难解决非常复杂的业务逻辑 面向过程的开发过程导致软件元素之间的“耦合度”非常高,其中一环出 问题整个系统都会收到影响;导致最终的软件扩展力差。另外由于没有"独立体" 的概念,导致无法达到组件复用。 - 面向对象: 主要关注点是: 主要关注对象【独立体】能完成哪些功能【独立显卡的开发思路】 * 优点:耦合度低,扩展力强,更容易解决现实世界中复杂的业务逻辑,复用性强 * 缺点:前期投入成本较高,需要进行独立体的抽取,大量的系统分析和设计 - c 是纯面向过程的、c++半面向对象、Java纯面向对象 C#是面向对象的、Javascript是基于对象的语言。 - 新出现的语言都是面向对象的,人认识事物是以面向对象的方式 - 面向对象更符合人的思维方式
面向对象的三大特征
- 封装
- 继承
- 多态所有面向对象得编程语言都有这三种特征面向对象的方式开发一个软件,生命周期当中【整个生命周期当中贯穿使用OO面向对象方式】- OOA面向对象的分析【analysis】- OOD面向对象的设计【design】- OOP面向对象的编程【programming】
类和对象的概念
什么是对象?
- 对象是现实世界存在的个体。是实际存在的。
什么是类?
- 类在现实生活中是不存在的,是一个模板,是一个概念。是人类大脑思考抽象的结果
- 类代表一类事物
- 在现实世界中,对象A和对象B具有共同特征,进行抽象总结出一个模板,这个模板
叫做类。
- 对象是现实生活中存在的个体,类是对象抽象出来具有共同特征的对象集合模板。
类—【实例化】–》对象
对象又被称为实例instance[实例]
对象—【抽象】–》类
- 一个类主要描述的信息?
一个类主要描述:状态【属性】 + 动作【方法】
状态信息:身高,年龄,性别
动作信息:吃、唱歌、跳舞 - 类 {
属性;// 描述对象的状态信息
方法;// 描述对象的动作信息
} - 注意:状态和动作具体到某个具体的对象上,有可能导致最后的结果不同
对象对象之间有共同特征,具体到对象之后,有数据的差异。
对象和类
/*对象的创建和使用:
*/
public class OOTest01
{public static void main(String[] args){int i = 0;// 通过一个类可以实例化N个对象// 实例化对象的语法 new 类名();// new是Java语言当中的运算符// new运算符的作用是创建对象,在jvm的堆内存区中开辟新的内存空间// 方法区内存:类加载的时候,.class字节码代码片段对被加载到该内存区// 栈内存区【局部变量】:方法代码片段执行的时候,会给该方法分配分配内存空间,在栈内存中压栈。// 堆内存区:new的对象在堆内存中存储// Student是一个引用数据类型// s是一个变量名// new Student()是一个学生对象// s是一个局部变量,在栈内存中存储// 什么是对象?new运算符在堆内存中开辟出的内存空间,叫做对象// 什么是引用?引用是一个变量,只不过这个变量保存了另一个Java对象的内存地址// 不能直接操作堆内存,不像C语言,Java没有指针的概念,// 要访问堆内存中的变量需要通过“引用”去访问堆内存中实例对象内部的实例变量Student s = new Student();// 访问实例变量的语法结构:// 读取数据:引用.变量名;// 修改数据:引用.变量名 = 值;/*// 读取数据:int stuNum = s.num;String stuName = s.name;String stuAddress = s.address;int stuAge = s.age;boolean stuSex = s.sex;System.out.println("学号:"+stuNum); // 0System.out.println("姓名:"+stuName); // nullSystem.out.println("年龄:"+stuAge); // 0System.out.println("性别:"+stuSex); // false*/System.out.println("学号:"+s.num); // 0System.out.println("姓名:"+s.name); // nullSystem.out.println("年龄:"+s.age); // 0System.out.println("性别:"+s.sex); // false// 修改数据:s.name = "jack";s.age = 10;s.num = 1527563998;s.sex = true;System.out.println("学号:"+s.num); // 0System.out.println("姓名:"+s.name); // nullSystem.out.println("年龄:"+s.age); // 0System.out.println("性别:"+s.sex); // false// 在实例化一个对象// Student 是数据类型// stu 是引用,同时也是局部变量// new Student() 是实例化的一个对象Student stu = new Student();// 编译报错// 因为num是实例变量,对象级别的变量,存储在Java对象内部,必须先有对象才能访问// 通过对象才能访问,不能通过“类名”访问// System.out.println(Student.num);}
}
/*局部变量在jvm中的栈内存中存储成员变量中的实例变量在堆内存中的Java对象内部存储
*/
// OOTest02.java
// 测试类
public class OOTest02
{public static void main(String[] args){// 实例化对象User u = new User();// 修改User对象内部实例化变量值u.no = 110;u.username = "jack"; // jack属于一个对象,属于String对象u.addr = new Address();// 得到一个User对象所在的城市// 在main方法当中目前只能看到一个引用“u”// 一切都只能是通过u来访问System.out.println(u.username + "居住在这个城市:" + u.addr.city);// 得到一个User对象住在哪个街道System.out.println(u.username + "居住在这个街道:" + u.addr.street);// 修改实例化变量的值u.addr.city = "西安";u.addr.street = "雁塔路";u.addr.zipCode = 1111111;System.out.println("城市:"+u.addr.city);System.out.println("街道:"+u.addr.street);System.out.println("邮编:"+u.addr.zipCode);}
}// User.java
// 用户类
public class User
{// 属性【成员变量之实例变量】// 用户编号// 基本数据类型中的int// no是一个实例变量int no;// 用户姓名// 引用数据类型中的String// username是一个实例变量,是一个引用String username;// 用户住址// Address自定义的引用数据类型// addr是一个实例变量,是一个引用Address addr;
}// OOTest03.java
public class OOTest03
{public static void main(String[] args){User u = new User();// 上一个版本// u.addr = new Address();Address a = new Address();u.addr = a;System.out.println("a.city:"+a.city);System.out.println("u.addr.city:"+u.addr.city);a.city = "天津";// u.addr.street = "长乐街";System.out.println(a.city); // 天津System.out.println(u.addr.city); // 天津}
}
OOTest02.java
OOTest03.java
// OOTest04.java
public class OOTest04
{public static void main(String[] args){// 创建一个丈夫对象Husband huangxiaoming = new Husband();huangxiaoming.name = "黄晓明";// 创建一个妻子对象Wife yangying = new Wife();yangying.name = "杨颖";// 结婚【可以通过妻子找到丈夫,可以通过丈夫找到妻子】huangxiaoming.w = yangying;yangying.h = huangxiaoming;System.out.println(huangxiaoming.w.name);System.out.println(yangying.name); // 采用这种方式访问,说明不了,黄晓明和杨颖之间的福夫妻关系}
}// Husband.java
// 丈夫类:
public class Husband
{// 姓名String name;// 丈夫对象中含有妻子引用Wife w;
}// Wife.java
// 妻子类:
public class Wife
{// 姓名String name;// 妻子对象中含有丈夫引用Husband h;
}
OOTest04.java
// OOTest05.java
// 测试程序
public class OOTest05
{public static void main(String[] args){Customer c = new Customer();System.out.println(c.id); // 0c = null;// c = null地址置为null没有引用指向Customer对象,垃圾回收// 编译不会报错,运行报错// 空指针异常,空引用访问实例相关的数据,会发生空指针异常// java.lang.NullPointerExceptionSystem.out.println(c.id);}
}// Customer.java
// Customer类
public class Customer
{// idint id;
}
// 测试程序【Student、Computer类的测试程序】
public class OOTest06
{public static void main(String[] args){// 创建对象Student stu1 = new Student();Computer c = new Computer();// 学生和电脑建立关联关系stu1.com = c;System.out.println(stu1+"正在使用这台电脑:"+stu1.com);}
}// 计算机类
public class Computer
{// 品牌String brand;// 型号String model;// 颜色String color;
}// Student是类,属于引用数据类型,这个类型名就是Student
// 不属于基本类型
// 学生类是一个模板
// 描述所有学生的共同特征【属性+方法】
public class Student
{// 属性【描述的对象的状态信息】// 属性通常使用变量定义// 类体中,方法体之外的变量,称为“成员变量”// 成员变量没有赋值,系统默认赋值,一切向“0”看齐// 所有学生都有学号// 每个学生的学号不同// 要访问学生的学号,需要先创建对象,通过对象去访问学生的学号信息,// 学号信息不能直接通过“类”去访问,只能通过“实例化的对象”访问,所以这种“成员变量”又叫做// “实例变量”,对象又被称作实例,实例变量又被称作:对象变量,【对象级别的变量】// 不创建对象name变量的内存空间是不存在的,只有创建了对象这个name变量的空间才会创建// 姓名String name;// 学号int num;// 年龄int age;// 地址String address;// 性别boolean sex;// 方法【描述的是对象的动作信息】// 学生有笔记本电脑Computer com;}
// 测试程序
public class OOTest07
{public static void main(String[] args){// 创建人类Ren jinChen = new Ren();// 不采用系统默认赋值// 手动赋值jinChen.name = "靳晨";jinChen.age = 100;jinChen.id = 12345678;jinChen.sex = false;// 创建House类House h = new House();// 建立房子和人的关系h.houseHolder = jinChen;// 输出房子主人的名字System.out.println("房子主人的名字:" + h.houseHolder.name);// 房子易主了,重新创建一个人的对象Ren liSi = new Ren();// 自定义liSi对象的属性liSi.name = "李四";liSi.age = 120;liSi.id = 119116;// 建立房子和新主人的关系h.houseHolder = liSi;// 输出房子新主人的名字,年龄System.out.println("名字、年龄" + h.houseHolder.name+" " + h.houseHolder.age);// 输出房子的主人的身份证号;System.out.println("房子的主人的身份证号:"+ h.houseHolder.id);}
}// 人类
public class Ren
{// 姓名String name;// 身份证号int id;// 年龄int age;// 性别boolean sex;
}// House类
public class House
{// 面积double area;// 主人Ren houseHolder;
}
// 在一个文件中
public class OOTest08
{public static void main(String[] args){// 创建对象Student stu1 = new Student();stu1.no = 12345;stu1.name = "小李";// 创建对象Computer com = new Computer();com.brand = "logitech";com.color = "灰色";// 建立学生和电脑之间得关系stu1.com1 = com;// 输出学生电脑得品牌System.out.println("学生电脑的品牌:" + stu1.com1.brand);// 学生1换电脑了stu1.com1 = new Computer();// 输出换的新电脑的品牌System.out.println(stu1.com1.brand); // null// 因为换的新电脑没有赋值,是默认值}
}class Computer
{// 品牌String brand;// 颜色String color;// 型号int model;
}class Student
{// 姓名String name;// 学号int no;// 有电脑// Student是一个类,Computer是一个类如何让两个类之间产生关系// 在学生类中有Computer com1这个属性Computer com1;
}
* 类的语法结构:
[修饰符列表] class 类名 {状态【属性】;动作【方法】;
}* 学生类,描述学生的共同特征:状态信息:姓名学号身份证号年龄身高体重动作信息:吃饭睡觉学习玩唱歌跳舞...
抽象类
/*
2021/3/20抽象类:1、什么是抽象类?类和类之间有共同特征,把这些共同特征提取出来,形成的就是抽象类2、抽象类是什么类型?抽象类也属于引用数据类型3、定义抽象类?语法:[修饰符列表] class abstract 类名{类体;}4、抽象类无法实例化,无法创建对象,所以抽象类是用来被子类继承的5、final和abstract不能联合使用,这两个关键字是对立的。6、抽象类的子类可以是抽象类7、抽象类无法实例化对象,但是抽象类有构造方法,这个构造方法是供子类使用的。子类的对象在创建的时候,它先去调用父类的构造方法8、抽象类关联到一个概念:抽象方法,抽象方法是没有实现的方法,没有方法体的方法public abstract void doSome();抽象方法的特点:特点一:没有方法体,以分号结尾特点二:前面修饰符列表中有abstract关键字修饰9、抽象类中不一定有抽象方法,可以有普通方法。抽象方法必须在抽象类中。*/public class AbstractTest01
{public static void main(String[] args){// 错误: Account是抽象的; 无法实例化// Account a = new Account();}
}// 银行账户类
abstract class Account
{// 普通方法public void withdraw(){}// 抽象方法public abstract void doSome();}// 抽象类的子类
// 信用卡类
// 抽象类无法创建对象,无法实例化,是用来被继承的
// 子类可以实例化对象,可以创建对象
/*
class CreditCard extends Account
{
}
*/// 抽象类的子类可以是抽象类吗?可以
abstract class CreditCard extends Account
{}
/*非抽象类继承抽象方法,必须将抽象方法实现*/
public class AbstractTest02
{public static void main(String[] args){}
}// 动物类(抽象类)
abstract class Animal
{// 抽象方法public abstract void move();
}// 子类(非抽象类)
class Bird extends Animal
{// 需要将从父类中继承过来的抽象方法重写/覆盖。或者也可以叫做实现。// 把抽象的方法实现了}
方法
/* 程序不使用方法: 代码未重复使用,只不过是相同的代码写了三遍[只不过没次参与求和的数据不同] Java语言当中应该有这样的机制 - 实现某个功能的代码只需要写一遍 - 实现这个功能只需要输入数字即可,就可以得到结果 这样代码就可以重复利用了,提高代码的复用性【这就是方法】 - 使用这个方法,称为调用,即“invoke”,*/public class MethodTest01{ public static void main(String[] args){ // 需求1:求两个int类型数字的和 int a = 100; int b = 100; int sum = a + b; System.out.println(a + "+" + b + "=" + sum); // 需求1:求两个int类型数字的和 int z = 110; int x = 119; int q = z + x; System.out.println(z + "+" + x + "=" + q); // 需求1:求两个int类型数字的和 int y = 114; int u = 120; int i = y + u; System.out.println(y + "+" + u + "=" + i); }}
/*以下程序使用方法这种机制- 方法Method在c语言当中叫做函数\Function- 方法定义在类体当中,一个类中可以定义多个方法,方法编写的位置没有先后顺序,可以随意。- 方法体当中不能再定义方法- 方法体当中的代码有先后顺序,执行自上而下依次执行
*/public class MethodTest02
{public static void main(String[] args){// 调用定义的方法求和MethodTest02.sumInt(10, 20); }// 定义方法public static void sumInt(int a, int b){int c = a + b;System.out.println(a + "+" + b + "=" + c);}
}
/* 关于Java语言当中的方法:1、定义方法,语法结构:[修饰符列表] 返回值类型 方法名(形式参数列表){方法体;}2、方法语法结构解释:2.1 修饰符列表:- 目前写成:"public static"- 可选项,不是必须的- 方法的修饰符列表中有static关键字,如何调用这个方法类名.方法名(实际参数列表)2.2 返回值:- 一个方法执行完成之后,返回最终执行结果,即会有某种类型的“数据”返回,这个“数据”就是返回值- 返回值的类型可以是Java语言当中的任意一种类型,也可以是引用数据类型byte short int long float double boolean char String void 等- 不是每个方法都需要有返回值,有可能这种方法执行完成之后不返回任何类型数据,但是,返回值类型位置必须编写:void 关键字- 指定的返回值不是void,则方法执行完成必须返回一个具体的该类型的数据否则编译器报错,只能是指定类型的数据- 如何编写返回值?return 值; 并且返回值的数据类型必须和方法中的返回值的数据类型一致,否则编译器报错。- 返回值类型是void,不能在方法体中编写return语句,但是,注意!可以编写“return;”这样的语句- 只要return语句执行,return所在的方法执行结束【注意不是jvm结束,是return所在的方法结束】2.3 形式参数列表【形参】- 形参是局部变量- 多个形参之间用逗号隔开- 形参的个数 0 ~ N 个- 形参中起决定作用的是形参的数据类型,形参的名字就是局部变量的名字- 形参列表和实参列表必须保持数量相同,类型对应相同2.4 方法如何调用?- 方法只定义不调用,方法不会执行- 语法规则:方法的修饰符列表中有“static”的类名.方法名(实参列表); <这是一条Java语句,表示调用某个类的某个方法,传递这样的实参>
*/
public class MethodTest03
{public static void main(String[] args){ // 这里的void是:"空白"的意思,即未指定返回值类型}/*public static 返回值类型 方法名(形参列表){ // “public static” :是修饰符列表}*/
}
// public 公开的// class 类// MethodTest04 方法名public class MethodTest04 // 表示定义一个公开的类,类名为MethodTest04,由于是公开的类,所以源文件名必须是:MethodTest04.java{ // 类体 // 类体中不能直接编写Java语句,除声明变量外 // 方法出现在类体中 // 方法 // public 公开的 // static 静态的 // void 表示方法执行结束之后不返回任何数据 // main是方法名:主方法 // (String[] args)形式参数列表,其中:String[]引用数据类型 ,args局部变量的变量名 // 所以以下只有args可以随意编写 // 主方法就是这样编写的,这是程序的入口,固定编写方式【SUN公司规定的】 public static void main(String[] args){ // 这里的程序一定会执行 // Java虚拟机负责调用主方法,是一个程序的入口位置 // 从这里开始执行程序 MethodTest04.sum(10, 20);// [实际上执行到这里main方法暂停,进入到sum方法执行,sum执行结束,main方法的这一行执行结束] // 一个方法可以被重复调用 int a = 100; MethodTest04.sum(a, 500); } // 自定义方法 // 不是程序的入口 // 方法作用:输出两个int类型变量的和,不返回结果,但是要求直接将结果输出到控制台 public static void sum(int x, int y){ System.out.println(x + "+" + y + "=" + (x + y)); }}
/* 方法的调用不一定要在main方法当中 只要程序可以执行到这里都可以在该位置调用*/public class MethodTest05{ public static void main(String[] args){ // 调用sum方法 MethodTest05.sum(10, 110); System.out.println("Hello World!!"); } public static void sum(int x, int y){ System.out.println(x + "+" + y + "=" + (x + y)); // 调用dosome方法 MethodTest05.doSome(); } public static void doSome(){ System.out.println("doSome!"); }}
public class MethodTest06
{public static void main(String[] args){// 对于所定义方法的修饰符列表中有static的方法// 可以省略"类名."来调用方法MethodTest06.doSome(); // 完整的方式doSome(); // 省略的方式// 调用其他类中【不是本类中】的方法A.doOther();}public static void doSome(){System.out.println("doSome!!!");}
}class A
{public static void doOther(){System.out.println("doOther!!!");}
}
public class MethodTest07{ public static void main(String[] args){ division(10, 2); // 这里没有接收这个方法的返回值 // 使用变量接收这个方法执行结束之后的返回值 // 变量的数据类型需要和返回值的数据类型相同,也可以自动类型转换。 int d = division(10, 3); System.out.println(d); System.out.println(division(10, 3)); // 直接输出 } // 定义一个方法:要求计算两个int类型变量的商, // 并将结果返回给调用者 public static int division(int a, int b){ /* int c = a / b; return c; */ return a / b; }}
/* 深入理解return语句: * 带有return关键字的Java语句如果执行,所在的方法执行结束 * 在"同一个作用域当中",return语句下面不能有任何代码,因为这些代码永远都执行不到, 因此会报错*/public class MethodTest08{ public static void main(String[] args){ int b = MethodTest08.m(); System.out.println(b); } /* // 编译器认为无法保证100%"return 1;"会执行; // 以下语句编译报错:因为a > 3 编译阶段不知道是true还是false有可能没有返回值 // 而指定了自定义类的返回值数据类型(必须有返回值),因此报错 public static int m(){ int a = 10; if (a > 3) { return 1; } }// 错误: 缺少返回语句 */ /* // 修改以上编译报错程序 public static int m() { int a = 10; if (a > 3) { return 1; }else{ return 0; } } */ /* // 以下代码等同于以上代码 public static int m() { int a = 10; if (a > 3) { return 1; // 这条语句执行,以下语句不再执行 // System.out.println("HelloWorld!!"); // 编译报错 错误: 无法访问的语句 } System.out.println("HelloWorld!!"); // 没有问题!!跳出了第一个return所在的作用域 return 0; // System.out.println("HelloWorld!!"); // 编译报错,无法访问的语句 } */ // 替代上面的冗余代码 public static int m(){ return 10 > 3 ? 1 : 0; }}
/* 在返回值类型是void的语句中使用return语句: return语句出现在返回值类型是void的方法当中主要是为了终止程序的执行*/public class MethodTest09{ public static void main(String[] args) { // System.out.println(m()); m(); } /* public static void m() { // return 10; // 编译报错,错误: 不兼容的类型: 意外的返回值 return; } */ public static void m(){ for (int i = 1; i <= 10; i ++){ if (i == 5){ // return; // 终止整个方法 最终不会输出"Hello World!!!" break; // 终止for循环 最终还会输出"Hello World!!!" } System.out.println("i---->"+i); } System.out.println("Hello World!!!"); }}
/* 方法在执行过程中,在jvm中是如何分配的,是如何变化的? 1、方法只定义,不调用是不会执行的,并且在jvm中也不会分配“运行所属”的内存空间。 只有在调用的时候才会分配运行所属的内存空间。 2、在jvm内存划分上有三块主要的内存区域【当然除了这三块,还有其他的内存区域】: * 方法区内存 * 堆内存 * 栈内存 3、关于栈数据结构: * 栈:stack,是一种数据结构 * 数据结构是一种数据存储的形态 * 数据结构是一门独立的学科,不属于任何语言的范畴,只不过在大多数编程语言中会使用到 * 常见的数据结构: - 数组 - 队列 - 栈 - 二叉树 - 链表 - 栈 - 哈希表\散列表 ... 4、方法代码片段存在哪里?方法执行过程中,从哪里分配内存? * 方法代码片段属于.class字节码文件的一部分,字节码文件在类加载的时候, 将其放在了方法区当中所以jvm中三块主要的内存空间中,方法区内存最先有数据。 存放了代码片段 * 代码片段虽然在方法区内存中只有一份,但是可以被重复调用。 每一次调用这个方法的时候,需要给该方法分配独立的活动场所, 这个活动场所在栈内存空间中分配 5、方法在调用的时候,会给该方法分配独立的内存空间,在栈中分配,此时发生压栈的动作 方法执行结束之后,发生弹栈的动作,给该方法分配的栈内存空间释放。 压栈:给该方法分配内存 弹栈:释放为该方法分配的内存空间 6、局部变量在方法体中声明,局部变量在运行阶段,内存在栈中分配。 7、注意:方法调用的时候,在参数传递的时候,实际上传递的是变量中保存的值 */public class MethodTest10{ public static void main(String[] args){ }}
/* 方法执行过程中的内存分析:1、局部变量在方法体中声明,局部变量在运行阶段,内存在栈中分配。2、注意:方法调用的时候,在参数传递的时候,实际上传递的是变量中保存的值
*/public class MethodTest11
{// 画图分析public static void main(String[] args){int i = 10;method(i);System.out.println("main--->"+i); // 10}public static void method(int i){i ++;System.out.println("method--->"+i); // 11}
}
方法重载
/*方法的重载机制:以下程序不使用方法重载机制:缺点:1、三个不同的方法虽然实现的功能不同,但都是求和的,且相似,功能相似的三个方法分别起了不同的方法名,对程序员来说需要记忆三个不同的方法名,才能完成调用【不方便】2、不美观方法的重载机制,解决了这些问题*/
public class OverloadTest01
{public static void main(String[] args){// 调用方法int result1 = sumInt(1, 2);System.out.println(result1);double result2 = sumDouble(1.0, 2.0);System.out.println(result1);long result3 = sumLong(1L, 2L);System.out.println(result1);}// 定义一个方法,可以计算两个int类型数据的和public static int sumInt(int a, int b){return a + b;}// 定义一个方法,可以计算两个double类型数据的和public static double sumDouble(double a, double b){return a + b;}// 定义一个方法,可以计算两个long类型数据的和public static long sumLong(long a, long b){return a + b;}
}
/*方法重载的使用:前提是:功能相似的时候
*/
public class OverloadTest02
{public static void main(String[] args){//调用不同的方法的时候就像使用同一个方法一样// 参数的类型不同对应调用不同的方法,调用方法不再依靠方法名了,依靠的是参数的类型不同// 不同的参数类型对应调用不同的方法System.out.println(sum(1, 2));System.out.println(sum(1.0, 2.0));System.out.println(sum(1L, 2L)); }// 以下程序使用方法重载机制public static int sum(int a, int b){System.out.println("intSum");return a + b;}public static long sum(long a, long b){System.out.println("longSum");return a + b;}public static double sum(double a, double b){System.out.println("doubleSum");return a + b;}
}
/*方法重载:1、方法重载又叫做:overload2、什么时候使用方法重载?方法功能相似的时候,尽可能让方法名相同3、什么条件满足的情况下构成方法重载?- 同一个类当中- 方法名不同- 参数列表不同* 参数类型不同* 参数数量不同* 参数类型顺序不同4、方法重载和什么有关系?和什么没有关系?***- 方法重载只和方法名+参数类型有关- 方法重载和返回值类型无关- 方法重载和修饰符列表无关*/public class OverloadTest03
{public static void main(String[] args){m1();m1(10);m2(2.0, 1);m2(1, 2.0);m3(11L);m3(10);}// 同一个类中,方法名一样,参数列表不同// 以下两个方法构成重载[参数列表数量不同]public static void m1(){}public static void m1(int a){}// 以下两个方法构成重载[参数列表顺序不同]public static void m2(double a, int b){}public static void m2(int a, double b){}// 以下两个方法构成重载[参数列表类型不同]public static void m3(long b){}public static void m3(int a){}// 以下两个方法不是方法重载是发生方法重复了;// 方法重载调用不同的方法起决定性作用的是参数类型,不是参数名/*public static void m4(int a, int b){}public static void m4(int b, int a){}*/// 方法重载和返回值类型没有关系// 以下程序编译报错// 错误: 已在类 OverloadTest03中定义了方法 m5()/*public static void m5(){}public static int m5(){return 1;}*/// 编译报错// 方法重载和修饰符列表无关/*void m6(){}public static void m6(){}*/
}
/*方法重载的应用
*/
public class OverloadTest04
{public static void main(String[] args){U.p(10);U.p("哈哈哈");U.p('a');U.p(false);}
}// 将U这个公开的类放在一个文件内
public class U
{public static void p(int a){System.out.println(a);}public static void p(byte a){System.out.println(a);}public static void p(short a){System.out.println(a);}public static void p(long a){System.out.println(a);}public static void p(double a){System.out.println(a);}public static void p(boolean a){System.out.println(a);}public static void p(char a){System.out.println(a);}public static void p(String a){System.out.println(a);}}
方法的递归调用
/* 关于方法的递归调用: 1、什么是递归调用? 方法自身调用自身 2、递归算法是很耗费栈内存的,递归可以不用的时候尽量不用 3、以下程序运行发生一个错误【不是异常】 以下错误无法挽回,一个结果:jvm停止工作 Exception in thread "main" java.lang.StackOverflowError 栈内存溢出错误 4、递归必须有一个结束条件,否则必定发生栈内存的溢出错误 5、递归即使有正确的结束条件,依然有可能发生栈内存溢出错误,因为递归的太深了*/public class RecursionTest01{ public static void main(String[] args){ System.out.println("main begin"); doSome(); // 这行代码不结束,下一行代码是不会执行的 System.out.println("main over"); // 不会执行 } public static void doSome(){ // System.out.println("doSome begin"); doSome(); // 这行代码不结束,下一行代码是不会执行的 // System.out.println("doSome over"); // 不会执行 }}
/* 不使用递归计算1~N的求和*/public class RecursionTest02{ public static void main(String[] args){ // 求1~4的和 /* int result = 0; for (int i = 1;; i++) { result += i; } System.out.println(result); */ // 直接调用方法即可 int retresult = sumInt(10); System.out.println(retresult); retresult = sumInt(20); System.out.println(retresult); } // 单独定义一个方法,求1~n的和 public static int sumInt(int n){ int result = 0; for (int i = 1; i < n; i++) { result += i; } return result; }}
/* 使用递归计算1~4的和 1 + 2 + 3 + 4 4 + 3 + 2 + 1 <---- n + (n - 1) + (n - 1 - 1)...*/public class RecursionTest03{ public static void main(String[] args){ int n = 4; int retValue = sum(n); System.out.println(retValue); } public static int sum(int n){ // 4 + 3 + 2 + 1 if (n == 1) { return 1; // 返回给下面的sum(2 - 1),是sum(2 - 1)调用的n == 1因此返回给它 } return n + sum(n - 1); }}/*n + sum(n - 1)4 + sum(3)4 + 3 + sum(2)4 + 3 + 2 + sum(1)4 + 3 + 2 + 1*/
/* 不使用递归计算N的阶乘: 5的阶乘: 5 * 4 * 3 * 2 * 1*//*public class RecursionTest04{ public static void main(String[] args){ int n = 5; int retresult = factorial(n); System.out.println(retresult); } public static int factorial(int n){ int result = 1; for (int i = n; i > 0; i--) { result *= i; } return result; }}// 递归方式:public class RecursionTest04{ public static void main(String[] args){ int n = 5; int retresult = factorial(n); System.out.println(retresult); } public static int factorial(int n){ if (n == 1) { return 1; } return n * factorial(n - 1); }}*/
Object类中的方法
object类中的toString()方法
/*1、SUN公司设计toString()方法的目的是什么? 通过调用这个方法可以将Java对象转换成字符串2、建议重写toString()方法 */public class Test01{ public static void main(String[] args){ // 通过有参构造方法创建对象 MyTime t1 = new MyTime(1998,12,16); // 调用toString()方法,返回值输出 String s1 = t1.toString(); System.out.println(s1); // 1998年12月16日 //直接调用toString()方法 System.out.println(t1.toString()); // 1998年12月16日 // 注意:输出引用的时候会自动调用引用的toString()方法 System.out.println(t1); // 1998年12月16日 }}class MyTime{ int year; int month; int day; public MyTime(){ } public MyTime(int year, int month, int day){ this.year = year; this.month = month; this.day = day; } // 重写toString()方法 public String toString(){ return this.year + "年" + this.month + "月" + this.day + "日"; }}
object类中的equals()方法
注意⚠️,Java中“==”判断的是两个对象的内存地址是否相等;equals()方法判断的是两个java对象是否相等。
/*关于Object类中的equals()方法:1、源代码:public boolean equals(Object obj) {return this == obj;}以上这个方法是Object类的默认实现2、SUN公司设equals()这个方法的目的是什么?以后编程过程中都要通过equals()方法判断两个对象是否相等判断两个Java对象是否相等3、判断两个Java对象是否相等不能使用“==”,因为“==”比较的是两个对象的内存地址4、Object类中的equals方法够用吗?不够,因为其返回的是“==”在Object类中判断两个Java对象是否相等,默认使用的“==”判断两个Java对象是否相等。而“==”判断的是两个Java对象的内存地址是否相等,所以Object类的equals方法,不够用需要子类重写equals()方法
*/ public class Test02
{public static void main(String[] args){// 判断两个基本数据类型是否相等,使用“==”int a = 100;int b = 100;System.out.println(a == b); // true// 判断两个Java对象是否相等// 创建MyTime对象MyTime t1 = new MyTime(1998,12,16);// 创建一个新的MyTime对象MyTime t2 = new MyTime(1998,12,16);// 测试使用“==”判断两个Java对象// t1 和 t2中保存的内存地址不一样,而“==”比较的是内存地址System.out.println(t1 == t2); // false// 重写equals方法之前(比较的是内存地址)// boolean flag = t1.equals(t2);// System.out.println(flag); // false// 重写equals方法之后(比较的是内容)boolean flag = t1.equals(t2);// 两个日期相等就是trueSystem.out.println(flag); // true// 再创建一个对象MyTime t3 = new MyTime(1998,12,26);// 两个日期不相等就是falseSystem.out.println(t1.equals(t3)); // false// 这个程序有bug吗?效率怎么样?低(如何改造)MyTime t4 = null;System.out.println(t1.equals(t4)); // false}
}class MyTime
{ // 属性int year;int month;int day;// 构造方法public MyTime(){}public MyTime(int year, int month, int day){this.year = year;this.month = month;this.day = day;}// 重写equals方法// 怎么重写:相同的返回值类型,相同的方法名,相同的形式参数列表/*public boolean equals(Object obj){// 获取第一个日期的年月日(这里的this指的是t1,因为是t1调用的equals()方法,传进来的参数形参obj对应的是t2这个实参)int year1 = this.year;int month1 = this.month;int day1 = this.day;// 获取第二个日期的年月日if (obj instanceof MyTime)// instanceof它的作用是测试它左边的对象是否是它右边的类的实例,返回 boolean 的数据类型。{MyTime t = (MyTime)obj; // 向下转型,强制类型转换int year2 = t.year;int month2 = t.month;int day2 = t.day;if (year1 == year2 && month1 == month2 && day1 == day2){return true;} }return false;}*//*// 改良equals方法public boolean equals(Object obj){// 如果obj是空直接返回falseif (obj == null){return false;}// 如果obj不是MyTime引用类型,直接返回falseif (! (obj instanceof MyTime)){return false;}// 意思是this和obj的内存地址相同// 内存地址相同指向的堆内存中的对象相同,是同一个if (this == obj){return true;}// 程序执行到此处,说明obj不是null是MyTime类型// 可以进行向下转型MyTime t = (MyTime)obj; // 向下转型,强制类型转换if (this.year == t.year && this.month == t.month && this.day == t.day){return true;}return false;}*//*// 再次改良public boolean equals(Object obj){// 如果obj是空直接返回falseif (obj == null){return false;}// 如果obj不是MyTime引用类型,直接返回falseif (! (obj instanceof MyTime)){return false;}// 意思是this和obj的内存地址相同// 内存地址相同指向的堆内存中的对象相同,是同一个if (this == obj){return true;}// 程序执行到此处,说明obj不是null是MyTime类型// 可以进行向下转型MyTime t = (MyTime)obj; // 向下转型,强制类型转换return this.year == t.year && this.month == t.month && this.day == t.day;// && 短路与,相等就是true,不相等就是false}*/public boolean equals(Object obj){if (obj == null || ! (obj instanceof MyTime)){return false;}if (this == obj){return true;}// 可以进行向下转型,强制类型转换 (obj是Object类型,里面没有MyTime02中的属性,需要转成MyTime02// 里面才有需要的属性)MyTime t = (MyTime) obj; // 向下转型,强制类型转换return this.year == t.year && this.month == t.month && this.day == t.day;}}
toString和equals
/* java语言当中的String有没有重写toString方法,和equals方法? 只要是类就有构造方法,只要是类就有equals方法,只要是类就有toString方法 总结: 1、String类已经重写了equals方法,比较两个字符串不能使用“==”, 必须使用equals方法,equals是通用的。 2、String类重写了toString方法*/public class Test03{ public static void main(String[] args){ // 大部分情况下使用这种方式创建字符串对象 String s1 = "hello"; String s2 = "abc"; // String实际上也是一个类,既然是类就存在构造方法 String s3 = new String("Test01"); String s4 = new String("Test01"); // new两次,两个内存地址,s3的内存地址和s4的内存地址不相同 // System.out.println(s3 == s4); // false // “==”判断的是内存地址,不是内容 // 比较两个字符串能否使用“==”? // 不能,“==”比较的是两个对象的内存地址 System.out.println(s3.equals(s4)); // true // String类有没有重写toString方法 // 重写了toString方法 String s5 = new String("超级无敌"); // 没有重写toString方法,输出结果:java.lang.String@十六进制位的地址 // 经过测试,已经重写了toString方法 System.out.println(s5.toString()); // 超级无敌 System.out.println(s5); // 当输出引用的时候,会自动调用这个引用的toString方法 }}
示例1:重写equals()方法
public class Test04
{public static void main(String[] args){// 创建对象Student s2 = new Student(2008811566, "实验幼儿园");Student s3 = new Student(2008811566, "实验幼儿园");System.out.println(s2.equals(s3)); // true}
}class Student
{int no;String school;// 构造方法public Student(){}public Student(int no, String school){this.no = no;this.school = school;}// 重写toString方法public String toString(){return "学号:" + no + ", 学校:" + school; }// 重写equals方法// 需求:当一个学生的学号,学校相同时,代表同一个学生public boolean equals(Object o){if (o == null || ! (o instanceof Student)){return false;}if (this == o){return true;}Student s1 = (Student)o; // 向下转型,强制类型转换/*if (this.no == s1.no && this.school.equals(s1.school)){return true;}*/return this.no == s1.no && this.school.equals(s1.school);return false;}
}
示例2:重写equals()方法
public class Test05
{public static void main(String[] args){User u1 = new User("zhangsan", new Address(1111, "西安", "雁塔路,55号"));User u2 = new User("zhangsan", new Address(1111, "西安", "雁塔路,55号"));System.out.println(u1 == u2); // falseSystem.out.println(u1.equals(u2)); // true}
}class User
{String name;Address addr;public User(){}public User(String name, Address addr){this.name = name;this.addr = addr;}// 重写equals方法public boolean equals(Object obj){if (obj == null || !(obj instanceof User))return false;if (obj == this)return true;User u = (User)obj; /*obj是Object类型,里面没有name,addr属性,需要对其进行转型转成User类型,里面才有需要的属性*/return this.name.equals(u.name) && this.addr.equals(u.addr);// 后面的调用Address的equals方法,因此需要重写Address里的equals方法}
}class Address
{ int zipCode;String city;String street;public Address(){}public Address(int zipCode, String city, String street){this.zipCode = zipCode;this.city = city;this.street = street;}// 重写equals方法public boolean equals(Object obj){if (obj == null || ! (obj instanceof Address))return false;if (obj == this)return true;Address a = (Address)obj;return a.zipCode == this.zipCode && a.city.equals(this.city) && a.street.equals(this.street);// 这里调用的String里的equals方法}
}
object类中的finalize方法:
/*关于Object类中的finalize方法: 1、finalize()方法在Object类中的源代码: @Deprecated(since="9") // deprecated表示这个方法已经过时 protected void finalize() throws Throwable { } 2、这个方法不需要程序员来调用,jvm中的垃圾回收器会调用 不像equals() toString() 需要程序员自己调用,finalize()方法会在相应时机自动调用(GC调用) 3、finalize()方法的调用时机? 当一个Java对象即将被垃圾回收器回收掉时,垃圾回收器负责调用finalize()方法 4、finalize方法是SUN公司位Java程序员准备的一个时机,一个垃圾销毁时机, 如果希望在垃圾销毁时机执行一段代码,把这段代码放进finalize方法体中即可。 5、静态代码块的作用? static { ... } 静态代码块在类加载时机执行,且只执行一次 这是SUN公司准备的类加载时机 finalize()方法也是SUN准备的一个时机 这个时机是垃圾回收时机。 6、Java中的垃圾回收器不是轻易启动的, 时间没到,垃圾太少,种种条件下, 有可能启动也有可能不启动。*/public class Test06{ public static void main(String[] args){ /*Person p = new Person(); p = null;*/ // 多造点垃圾让他回收 for (int i = 0; i < 1000000 ; i++) { Person p = new Person(); p = null; } }}// 项目开发过程中有这样的需求:所有对象在jvm中被释放的时候,记录一下释放的时间class Person{ // 重写finalize方法 // Person对象被垃圾回收器回收的时候,垃圾回收器负责调用 protected void finalize() throws Throwable { System.out.println(this + "即将要被回收掉了,是GC调用的!!"); }}
Object类中的hashCode()方法:
/*hashCode()方法: 1、源码: public native int hashCode(); 带有native关键字,底层调用C++程序,不是抽象方法 2、hashCode()返回的是哈希码 实际上就是一个Java对象的内存地址,经过哈希算法,得出的一个值 所以hashCode()方法的执行结果可以等同看作,Java对象的内存地址*/public class Test07{ public static void main(String[] args){ Object o = new Object(); int hashCodeValue = o.hashCode(); System.out.println(hashCodeValue); // 对象内存地址通过哈希算法转换得到的一个值,可以等同看作内存地址 }}
运算符
/* 关于Java语言当中的运算符之:算数运算符 + 求和 - 相减 * 乘 / 商 % 求余数【取模】 ++ 自加1 -- 自减1 注意:一个表达式中有多个运算符,运算符有优先级,不确定时加小括号,优先级得到提升。 */public class OperaterTest01{ public static void main(String[] args){ int i = 10; int j = 3; System.out.println(i + j); // 10 System.out.println(i - j); // 7 System.out.println(i * j); // 30 System.out.println(i / j); // 3 System.out.println(i % j); // 1 // 小结:++ 可以放在变量前,也可以放在变量后,只要运算结束,该变量必定自加1操作 // ++ 放在变量后,先进行赋值运算,赋值运算结束,再进行++运算。 int a = 100; int b = a ++; System.out.println(a); // 101 System.out.println(b); // 100 // ++ 出现在变量之前 // 规则:先进行自加1运算,再进行赋值运算 int m = 20; int n = ++ m; System.out.println(m); // 21 System.out.println(n); // 21 int mm = 100; System.out.println(mm++); // 100 System.out.println(mm); // 101 int s = 50; System.out.println(++s); // 51 System.out.println(s); // 51 }}
/* 关于Java中的关系运算符: > >= < <= == != 注意: 关系运算符运算的结果都是布尔类型:true false 关系运算符,比较原理: int a = 10; int b = 10; a==b 比较的是a和b中保存的10这个值之间的比较 */ public class OperaterTest02{ public static void main(String[] args){ int a = 10; int b = 10; 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(a==b); // true System.out.println(a!=b); // false }}
/* 关于Java语言当中的逻辑运算符: & 逻辑与 【两边的算子都为true,结果为true】 | 逻辑或 【两边的算子一边为true,结果为true】 ! 逻辑非 【!false 为 真;!true 为 假;是单目运算符】 ^ 逻辑异或 【两边的算子只要是不一样,结果就为真】 && 短路与 || 短路或 1、逻辑运算符两边的算子都是布尔类型的,最后的结果也是布尔类型的 2、短路与和逻辑与最终的运算结果一样,只不过短路与存在短路现象 3、短路或和逻辑与最终的运算结果一样,只不过短路或存在短路现象 4、什么情况下发生短路现象? 5、什么情况下使用短路与,什么情况下使用短路或运算符?*/public class OperatorTest03{ public static void main(String[] args){ System.out.println(5 > 1 & 5 > 4); // true System.out.println(true | true); // true System.out.println(true | false); // true System.out.println(false | false); // false System.out.println(!false); // true System.out.println(!true); // false System.out.println(true ^ true); // false System.out.println(true ^ false); // true System.out.println(false ^ false); // false // 短路与和逻辑与的区别 /* int x = 10; int y = 5; System.out.println(x < y & ++x < y); // false System.out.println(x); // 11 */ int x = 10; int y = 5; // 短路与 // x < y 为false,整个表达式的结果为false // 短路与不再往下执行了,这种现象称为短路现象 // 短路与才有短路现象,逻辑与没有短路现象 System.out.println(x < y && ++x < y); // false System.out.println(x); // 10 /* 从某个角度而言,短路与更智能,由于后面的表达式可能不执行,执行效率较高, 短路与比逻辑与更长用 但是在某些特殊的业务逻辑当中,要求运算符两边的算子都要执行,这时候只能使用逻辑与 短路与可能导致右边的算子不执行 */ /* 什么情况下发生短路与? 左边算子为false 什么情况下发生短路或? 第一个表达式运算结果为true */ }}
/* 关于Java语言当中的赋值运算符: 基本赋值运算符: = 扩展的赋值运算符: += -= *= /= %= 1、赋值类运算符的优先级:先执行等号右边的,将执行结果赋值给等号左边的变量。 2、注意以下代码: byte i = 10; i += 5; //等同于 (byte)(i + 5); long z = 10L; int y = 5; y += z; // 等同于 (int)(y + z); 3、重要结论:扩展类赋值运算符不改变运算结果的类型,假如变量最初是byte类型 最终该变量也是 byte类型。在底层运算的时候添加了强制类型转换,只不过我们看不见。 */public class OperatorTest04{ public static void main(String[] args){ /* byte b = 10; b += 5; System.out.println(b); // 15 */ byte b = 10; // b = 10 + 5; // 可以 // 编译报错 // 编译阶段只检查语法,不运行程序,b是byte类型,b + 5是int类型, // 大容量向小容量转换,强制类型转换 // b = b + 5; // 纠正 b = (byte)(b + 5); System.out.println(b); byte x = 10; x += 5; // x += 5其实不等同于 x = x + 5;等同于x = (byte)(x + 5); System.out.println(x); // 15 // 【由以上例子可以说明】以下程序编译正确 byte z = 0; z += 128; // 等同于:z = (byte)(z + 128);虽然超出byte类型的取值范围但是其等同前面 System.out.println(z); // -128 损失精度 }}
/* 关于Java语言当中的“+”运算符: 1、“+”运算符有两个作用: * 加法运算,求和 * 字符串连接运算 2、当“+”运算符两边都是数字,执行加法运算; 3、只要一边是字符串则执行字符串连接运算;并且连接运算之后的结果也是字符串å 数字 + 数字 ――――――》数字【加法运算】 字符串 + ?? ――――――》 字符串【字符串连接运算】 4、一个表达式中可以添加多个“+”,在没有添加小括号的前提下,遵循从左至右依次执行*/public class OperatorTest05{ public static void main(String[] args){ System.out.println(10 + 20 + "30"); // "3030" 第一个加号是求和,第二个加号是字符串连接 System.out.println(10 + ( 20 + "30")); // "102030" // 要求在控制台输出"10 + 20 = 30" int a = 10; int b = 20; System.out.println("10 + 20 =" + a + b); // "10 + 20 =1020" 字符串连接,从左至右 // 注意:动态输出 System.out.println("10 + 20 =" + (a + b)); // "10 + 20 =30" System.out.println(a + "+" + b + "=" + (a + b)); // 动态拼接 "10 + 20 =30" // String不是基本数据类型,是引用数据类型 String s = "abc"; // 编译错误:类型不兼容 // String ss = 10; String username = "zhangsan"; System.out.println("欢迎"+username+"回来!"); }}
/*关于Java语言当中的三目运算符/三元运算符:1、语法规则:布尔表达式 ? 表达式1 : 表达式22、三元运算符的执行原理:* 布尔表达式为true,选择表达式1为整个表达式的执行结果* 布尔表达式为false,选择表达式2为整个表达式的执行结果*/
public class OperatorTest06
{public static void main(String[] args){// 编译错误,不是一个完整的Java语句// 10;// 编译错误,不是一个完整的Java语句// '男';// 布尔类型变量boolean sex = false;//分析以下程序是否编译通过// 编译报错:不是一个完整的Java语句// sex ? '男' : '女';char c = sex ? '男' : '女';System.out.println(c); //女sex = true;c = sex ? '男':'女';System.out.println(c); //男// 编译报错// 语法错误:运行结果可能是String,也可能是char类型,不能用char来接收结果/*sex = false;char c1 = sex ? "男":'女';*/System.out.println(sex ? "男":'女'); // 男 可以String s = sex ? "男的":"女的"; // 可以System.out.println(s); // 男的}
}
5、数据类型
* 基本数据类型
byte
short
int
long
double
float
char
boolean
* 引用数据类型
System.class SUN公司提供的
String.class SUN公司提供的
Student.class 程序员自定义的
Customer.class 程序员自定义的
…
总结:
1、jvm【Java虚拟机】包括三块主要的内存空间:方法区内存、堆内存、栈内存;
2、方法区内存、堆内存各有一个,栈内存是一个线程一个栈内存
3、方法调用的时候,该方法所需要的内存空间,在栈中分配,称为压栈;方法执
行结束,该方法所属的内存空间释放,称为弹栈
4、栈中主要存储的是方法体中的局部变量
5、方法的代码片段已经整个类的代码片段都存放在方法区内存中,在类加载的时候这些代码载入
6、在程序执行过程中new出的对象,存放在堆内存中,对象内部有实例对象,因此实例对象存储在
堆内存中;
7、变量分类
- 局部变量:方法体内声明
栈内存中】- 成员变量:方法体外声明,类体内声明
- 实例变量
【存放在堆内存中】 - 静态变量
【存放在方法区内存中】
8、静态变量存放在方法区内存中
9、三块内存中,变化最频繁的是栈内存、最先有数据的是方法区内存、垃圾回收机制主要针对的是堆内存
10、垃圾回收器【自动垃圾回收机制、GC机制(garbage collection)】什么时候会考虑将Java对象的内存回收
- 实例变量
- 成员变量:方法体外声明,类体内声明
- 当Java对象的数据称为垃圾数据的时候,会被垃圾回收器回收
- 什么时候Java对象的数据会变成垃圾数据?
没有更多的引用指向它的时候
这个对象无法被访问,因为访问对象需要通过引用的方式访问
11、空指针异常,空引用访问实例相关的数据,会发生空指针异常
java.lang.NullPointerException
什么是实例相关的数据?
这种数据访问的时候必须有对象的参与,即实例相关的数据
- 什么时候Java对象的数据会变成垃圾数据?
关于Java的集成开发环境【集成开发环境:IDE】
1、* 没有IDE
- 需要安装jdk,需要配置环境变量,需要手动将Java源文件编译为.class字节码文件,
编写Java源文件没有错误提示
* 现在比较厉害的IDE
- eclipse
- intelij IDEA
- myeclipse
- NetBeans
- JBuilder
2、eclipse使用
* workspace:工作区
* 每个eclipse可以开启多个会话,每个会话对应不同的工作区
* .metadata文件夹:存储着当前eclipse的工作状态【比如自己设置的布局,存储】
* .metadata文件夹删除之后,再次进入是一个新的工作状态,但是会发现eclipse上的项目丢失了,
这里只是丢失的eclipse上的项目,硬盘上的项目没有丢失
* 窗口不小心关闭window ---》showview ---> Other ---> 输入自己需要找的窗口名称
* eclipse为Java程序员准备了对应不同开发的布局方式- 企业级开发:Java EE开发的专用布局 ---》java Enterprise- 普通Java开发:JavaSE 开发的专用布局 ---》Java
* 重点窗口介绍- Package Explore:可以看到Java源文件【Project Explore/Navigator】
* 工作区workspace中最基本的单元是:Project[工程/项目]
* Java运行环境jre的配置,可以使用eclipse自带的,也可以使用程序员自己安装的jre
*Project layout:工程目录布局- 多数情况下使用两个独立的文件夹存储源码(src)和字节码文件(bin)* 在src下新建软件包:package机制
- 在src目录上右键new -- package
- 给package起名 * 在package下创建一个Java类
- 在包上右键class* 显示行号
Java源程序左侧栏右键,选择Show Line Numbers
- eclipse中常用的快捷键
- Alt + / : 自动补全
- Ctrl + D :删除一行
- Ctrl + 1:提示错误信息【红色是错误,黄色是警告】
Ctrl + Alt + down
注意:eclipse中的Java源文件有时候不保存是不会编译的,时刻记住:Ctrl + S保存
包package 是Java语法中的一部分
java基础总结笔记相关推荐
- Java基础复习笔记系列 九 网络编程
Java基础复习笔记系列之 网络编程 学习资料参考: 1.http://www.icoolxue.com/ 2. 1.网络编程的基础概念. TCP/IP协议:Socket编程:IP地址. 中国和美国之 ...
- java基础巩固笔记(6)-注解
2019独角兽企业重金招聘Python工程师标准>>> java基础巩固笔记(6)-注解 标签: java [TOC] 注解(Annotation),也叫元数据.一种代码级别的说明. ...
- 【Java基础学习笔记】- Day11 - 第四章 引用类型用法总结
Java基础学习笔记 - Day11 - 第四章 引用类型用法总结 Java基础学习笔记 - Day11 - 第四章 引用类型用法总结 4.1 class作为成员变量 4.2 interface作为成 ...
- java基础巩固笔记(5)-多线程之线程并发库
2019独角兽企业重金招聘Python工程师标准>>> java基础巩固笔记(5)-多线程之线程并发库 标签: java [TOC] 本文主要概述java.util.concurre ...
- Java基础复习笔记系列 七 IO操作
Java基础复习笔记系列之 IO操作 我们说的出入,都是站在程序的角度来说的.FileInputStream是读入数据.?????? 1.流是什么东西? 这章的理解的关键是:形象思维.一个管道插入了一 ...
- Java中大数据数组,Java基础学习笔记之数组详解
摘要:这篇Java开发技术栏目下的"Java基础学习笔记之数组详解",介绍的技术点是"java基础学习笔记.基础学习笔记.Java基础.数组详解.学习笔记.Java&qu ...
- Java基础知识笔记-11_2-Swing用户界面组件
Java基础知识笔记-11_2-Swing用户界面组件 这章教程两个版本,一个语法是非lambda表达式版本,另一个是lambda表达式版本 非lambda表达式版本 1 Java Swing概述 J ...
- 尚学堂JAVA基础学习笔记_2/2
尚学堂JAVA基础学习笔记_2/2 文章目录 尚学堂JAVA基础学习笔记_2/2 写在前面 第10章 IO技术 1. IO入门 2. IO的API 3. 装饰流 4. IO实战 5. CommonsI ...
- 51自学网-Java基础视频教程-笔记 最后修改于2020/9/9
Java基础视频教程笔记 简介 正文 ==JVM Java Virtual Machine== 栈区 Stack Segment 堆区 Heap Segment 静态区 Data Segment 代码 ...
- Java基础入门笔记2
Java基础入门笔记2 一. 为什么把程序出错叫做"BUG"? 1. 原因是臭虫或者虫子,现在用来指代电脑系统或者程序中隐藏的一些漏洞或者一些问题,所以现在程序出问题就叫" ...
最新文章
- Python之字符串格式化(format)
- SAP中批量更改凭证行项目方法
- python删除指定文件夹下文件和文件夹的方法
- Linux/unix 查看端口占用
- 《Python Cookbook 3rd》笔记(1.15):通过某个字段将记录分组
- Mybatis 动态传入表名 字段名 的解决办法
- html里meta标签,HTML中的meta标签详解
- 通用性好的win2003序列号: (推荐先用这个里面的)
- docker在centos7.x系统配置私有库
- C#中的HashTable 和Dictionary对象
- VirtualBox虚拟机压缩减少体积
- 批处理删除指定文件或文件夹
- JAVA实现 - 问题 G: 超大型 LED 显示屏
- Python实战(07):使用selenium刷访问量
- Ae 效果详解:CC Grid Wipe
- fail can only be invoked by user TAP gesture.
- D 语言编写CGI程序
- c语言第六章数组题库及详解答案,C语言第六章数组习题答案.doc
- [bzoj] 1597 土地购买 || 斜率优化dp
- 计算机硬件希沃课件,希沃白板的课件能转换成ppt吗?如何转换?