注释
注释概述:用于解释说明程序的文字
Java中注释分类格式
单行注释 格式://注释文字
多行注释 格式:/* 注释文字 */
文档注释 格式:/** 注释文字 */
养成先写注释后写代码的习惯
单行注释可以嵌套,多行注释不能嵌套
关键字
关键字概述:被java语言赋予特定含义的单词
关键字特点:组成关键字的字母全部小写
关键字注意事项:goto和const作为保留字存在,目前并不使用
标识符
标识符概述:就是给类,接口,方法,变量等起名字时使用的字符序列
组成规程:英文大小写字母、数字字符、$和_
注意事项:不能以数字开头、不能是Java中的关键字、区分大小写
示例
包(其实就是文件夹,用于解决相同类名问题)
举例
包名要求全部小写,一般是公司的域名倒着写
com.heima.包的作用
类或者接口
一个单词和多个单词分别举例
如果是一个单词,要求首字母大写,如果是多个单词,要求每个单词首字母大写(驼峰命名)
方法和变量
一个单词和多个单词分别举例
如果是一个单词,每个字母都小写,如果是多个单词,从第二个单词开始首字母大写
常量
一个单词和多个单词分别举例
如果是一个单词,所有字母大写,如果是多个单词也是所有字母大写,但是用_分开
MAX
MAX_VALUE
常量
什么是常量?在程序执行的过程中其值不可以发生改变
Java中常量的分类?字面值常量、自定义常量(面向对象部分讲)
字面值常量的分类
class Demo1_Constant {
public static void main(String[] args) {
/*
字符串常量 用双引号括起来的内容
整数常量 所有整数
小数常量 所有小数
字符常量 用单引号括起来的内容,里面只能放单个数字,单个字母或单个符号
布尔常量 较为特殊,只有true和false
空常量 null(数组部分讲解)
*/
System.out.println("abc"); //字符串常量
System.out.println(123); //整数常量
System.out.println(12.3); //小数常量
System.out.println('1'); //''中必须放的是单个字符,10代表的是1字符和0字符
//System.out.println(''); //''中什么也不放,也是不可以的,因为代表不了任何字符
System.out.println(' '); //代表空格字符
System.out.println(true); //boolean类只有两个字符,true和false
}
}
进制
1byte = 8bit
1k = 1024b
1m = 1024k
1g= 1024m
1t = 1024g
二进制的数据表现形式:由0,1组成,以0b(b可以大写也可以小写)开头
八进制的数据表现形式:以0开头
默认为是十进制
十六进制的数据表现形式:以0x开头
实例
0b100
0100
100
0x100
进制转换2.jpg
原码反码补码
原码:就是二进制定点表示法,即最高位为符号位,“0”表示正,“1”表示负,其余位表示数值的大小。
通过一个字节,也就是8个二进制位表示+7和-7
0(符号位) 0000111
1(符号位) 0000111
反码:正数的反码与其原码相同;负数的反码是对其原码逐位取反,但符号位除外。
补码:正数的补码与其原码相同;负数的补码是在其反码的末位加1。
变量
什么是变量?在程序执行的过程中,在某个范围内其值可以发生改变的量
变量的定义格式 数据类型 变量名(合法的标识符) = 变量值
为什么要定义变量? 用来不断的存放同一类型的常量,并可以重复使用
数据类型
为什么有数据类型?Java语言是强类型语言,对于每一种数据都定义了明确的具体数据类型,在内存中分配了不同大小的内存空间
数据类型的分类:基本数据类型、引用数据类型(面向对象部分讲解)
基本数据类型分类(4类8种)
整数型
byte 占一个字节 -128到127
short 占两个字节 -2^15 ~ 2^15-1
int 占四个字节 -2^31 ~ 2^31-1
long 占八个字节 -2^63 ~ 2^63-1
浮点型
float 占四个字节 -3.403E38~3.403E38 单精度
double 占八个字节 -1.798E308~1.798E308 双精度
字符型
char 占两个字节 0~65535
布尔型
boolean理论上是占八分之一字节,因为一个开关就可以决定是true和false了,但是java中boolean类型没有明确指定大小
class Demo1_DataType {
public static void main(String[] args) {
//整数类型
byte b =10; //占一个字节
short s = 20; //占两个字节
int i = 30; //占四个字节,整数默认是int类型
long x = 8888888888L; //占八个字节,如果long类型后面加L进行标识最好加大L,因为小l太像数字1了。
System.out.println(b);
System.out.println(s);
System.out.println(i);
System.out.println(x);
//浮点类型
float f = 12.3F; //占四个字节
double d = 33.4; //占八个字节 小数默认的数据类型是double,double类型后面也可以用D或者d标识,但是一般不加
System.out.println(f);
System.out.println(d);
//字符类型
char c = 'a'; //占两个字节
System.out.println(c);
//布尔类型
boolean b1 = true;
boolean b2 = false;
System.out.println(b1);
System.out.println(b2);
}
}
使用变量的注意事项:
1.作用域问题:同一个区域不能使用相同的变量名
2.初始化值的问题:局部变量在使用之前必须赋值
3.一条语句可以定义几个变量 int a,b,c,...;
类型转换
类型转换1.jpg类型转换2.jpg
1.隐式转换
从小到大,可以隐式转换,数据类型将自动提升。
2.强制转换
从大到小(如果你明确知道数据是可以用该数据类型来表示的,可以用强制转换)
int a = 10
byte b = 20
b = (byte)(a+b)
1.a + b会首先将b转化为int类型再相加,这是隐式转换
2.(byte)(a+b)会将a+b的结果(是int型)强制转化为byte型,这是强制转换
3.如果强制转换超出了被赋值的数据类型的取值范围,得到的结果会与你期望的结果不同。
class Demo3_DataTypeConversion {
public static void main(String[] args) {
/*00000000 00000000 00000000 10000010 130的二进制
10000010 -126的补码
10000001 -126反码
11111110 -126原码
*/
byte b = (byte)(126 + 4);
System.out.println(b);
/*00000000 00000000 00000001 00101100 300的二进制
00101100 44原码
*/
byte b2 = (byte)(300);
System.out.println(b2);
}
}
面试题
class Test1_DataTypeConversion {
public static void main(String[] args) {
//面试题:看下面程序是否有问题,如果有问题,请指出并说明理由。
byte b1 =3;
byte b2 =4;
//byte b3 = b1 + b2;
//System.out.println(b3);
/*
从两方面
1.byte与byte(或short,char)进行运算的时候会提升为int,两个int类型相加的结果也是int类型
2.b1和b2是两个变量,变量储存的值是变化的,在编译的时候无法判断里面具体的值,相加有可能会超出byte的取值范围
*/
byte b4 = 3 + 4; //java编译器有常量优化机制
System.out.println(b4);
}
}
long和float的取值范围谁大谁小
进行混合运算的时候,byte,short,char不会相互转化,都会自动类型提升为int类型,其他类型进行混合运算的是小的数据类型提升为大的
byte,short,char >> int >> long >> float >> double
class Test2_DataTypeConversion {
public static void main(String[] args) {
float f = 12.3f;//4个字节
long x = 12345;//8个字节
//f = x; //隐式转换
//System.out.println(f);
x = (long)f; //强制转化
System.out.println(x);
/*
float占4个字节
IEEE 754
4个字节是32个二进制位
1位是符号位
8位是指数位
00000000 - 11111111
0到255
0代表0
255代表无穷
1 ~ 254
减去127
-126 ~ 127
23位代表尾数位
*/
}
}
1.它们底层的储存结构不同
2.float表示的数据范围比long的范围要大
long:2^63-1
float: 3.4 * 10^38 > 2 * 10^38 > 2 * 8^38 = 2 * 2^3 ^38 = 2 * 2^114 >2^63-1
class Demo4_DataTypeConversion {
public static void main(String[] args) {
System.out.println('a' + 1); //98,因为有ASCII码表,a字符对应的是int类型的97
System.out.println((char)('a'+1));
// '0' 48 'A' 65 'a' 97
System.out.println("hello"+'a'+1); //任何数据类型用+与字符串相连接都会产生新的字符串
System.out.println('a'+1+"hello");
System.out.println(" 5 + 5 = " + (5 + 5));
}
}
char数据类型
class Demo5_char {
public static void main(String[] args) {
char c = 'a';
System.out.println(c);
byte b = 100;
char c1 = 97; //0 ~ 65535
System.out.println(c1);
char c2 = 3;
char c3 = 4;
char c4 = 5;
char c5 = 6;
System.out.println(c2);
System.out.println(c3);
System.out.println(c4);
System.out.println(c5);
//char类型可以储存中文
char c6 = '中';
System.out.println(c6);
}
}
Java语言中的字符char可以储存一个中文汉字吗?为什么呢?
可以。因为Java语言采用的是Unicode编码。 Unicode编码中的每个字符占用两个字节。中文也是占的两个字节,所以Java中的字符可以储存一个中文汉字
算术运算符
什么是运算符?就是对常量和变量进行操作的符号
运算符的分类:算数运算符、赋值运算符、比较(关系或条件)运算符、逻辑运算符、位运算符、三目(元)运算符
算数运算符有哪些:+,-,*,/,%,++,--
class Demo1_Operator {
public static void main(String[] args) {
/*
a:+号在java中有三种作用,代表正号,做加法运算,字符串的连接符
b:整数相除只能得到整数。如果想得到小数,必须把数据变化为浮点数类型
c:/获取的是除法操作的商,%获取的是除法操作的余数
%运算符
当左边的绝对值小于右边的绝对值时,结果是左边
当左边的绝对值等于右边或者右边的倍数时,结果是0
当左边的绝对值大于右边的绝对值时,结果时余数
%运算符结果的符号只和左边有关系,与右边无关
任何一个正整数%2结果不是0就是1可以用来当作切换条件
*/
System.out.println(10 / 3); //整数相除结果只能时整数
System.out.println(10 / 3.0); //如果想得到小数,把其中一个数变成小数,另一个数在运算的时候会自动类型提升
System.out.println(13 % -5); //结果是3
}
}
++--运算符
a:单独使用:
放在操作数的前面和后面效果一样
b:参与运算使用:
放在操作数的前面,先自增或自减,然后再参与运算。
放在操作数的后面,先参与运算,再自增或自减。
实例
byte b = 10
b++ //底层会帮着实现b = (byte)(b+1)
b = b + 1 //会报错,右边会提升为int类型后在相加,赋给左边的byte类型的b会报错
赋值运算符
把右边的值赋值给左边的变量,左边必须是变量。
有以下赋值运算符
=
+=
-=
/=
%=
*=
short s=1;s=s+1;会报错,会提升为int,然后赋给short类型时会报错
short s=1;s+=1;不会报错 底层会自动实现s = (short)(s + 1)
class test {
public static void main(String[] args) {
int i = -1;
System.out.println(Integer.toBinaryString(i));
i >>>= 10;
System.out.println(Integer.toBinaryString(i));
long l = -1;
System.out.println(Long.toBinaryString(l));
l >>>= 10;
System.out.println(Long.toBinaryString(l));
short s = -1;
System.out.println(Integer.toBinaryString(s));
s >>>= 10;
System.out.println(Integer.toBinaryString(s));
byte b = -1;
System.out.println(Integer.toBinaryString(b));
b >>>= 10;
System.out.println(Integer.toBinaryString(b));
b = -1;
System.out.println(Integer.toBinaryString(b));
System.out.println(Integer.toBinaryString(b>>>10));
}
}
关系运算符(比较运算符,条件运算符)
==,!=,>,>=,<,<=
结果是boolean类型
==号不能写成=号,一个是比较,一个是赋值。
逻辑运算符
逻辑运算符有哪些
* &,|,^,!
* &&,||
- &逻辑与:有false则false。
- |逻辑或:有true则true。
- ^逻辑异或:相同为false,不同为true。
- !逻辑非:非false则true,非true则false。
&&和&的区别?
- a:最终结果一样。
- b:&&具有短路效果。左边是false,右边不执行。
- c:&是无论左边是false还是true,右边都会执行。
||和|的区别?
- a:最终结果一样。
- b:||具有短路效果。左边是true,右边不执行。
- c:|是无论左边是false还是true,右边都会执行。
位运算符
- A:位运算符有哪些
- &,|,^,~ ,>>,>>>,<<
- &,|,^,~ 的用法
- &:有0则0
- |:有1则1
- ^:相同则0,不同则1
- ~:按位取反
class test {
public static void main(String[] args) {
System.out.println(~6);
/*
00000000 00000000 00000000 00000110 6的原码反码补码都是本身
11111111 11111111 11111111 11111001 对6取反
- 00000000 00000000 00000000 00000001
---------------------------------------------------
11111111 11111111 11111111 11111000 反码
10000000 00000000 00000000 00000111 原码(-7)
*/
}
}
位异或运算符的特点及面试题
-
位异或运算符的特点
- ^的特点:一个数据对另一个数据位异或两次,该数本身不变。
class test {
public static void main(String[] args) {
int x = 10;
int y = 5;
//交换x和y
//不需要定义第三方变量,有弊端,有可能会超过int的取值范围
/*x = x + y; //10 + 5 = 15
y = x - y; //15 - 5 = 10
x = x - y; //15 - 10 = 5
System.out.println("x = " + x + ",y = " + y);*/
//不需要第三方变量,通过^来做
x = x ^ y; // 10 ^ 5
y = x ^ y; // 10 ^ 5 ^ 5 y = 10
x = x ^ y; // 10 ^ 5 ^ 10 x = 5
System.out.println("x = " + x + ",y = " + y);
}
}
位运算符2
class test {
public static void main(String[] args) {
/*
* <<:左移 左边最高位丢弃,右边补齐0
* >>:右移 最高位是0,左边补齐0;最高为是1,左边补齐1
* >>>:无符号右移 无论最高位是0还是1,左边补齐0
* 最有效率的算出2 * 8的结果
*/
//左移,向左移动几位就是乘以2的几次幂
System.out.println(12 << 1); //24
System.out.println(12 << 2); //48
/*
00000000 00000000 00000000 00001100 12的补码
(0)00000000 00000000 00000000 00011000 24的补码
(00)00000000 00000000 00000000 00110000 48的补码
*/
//右移,向右移动几位就是处以2的几次幂
System.out.println(12 >> 1);
System.out.println(12 >> 2);
//* 最有效率的算出2 * 8的结果
System.out.println(2 << 3);
}
}
三元运算符
class test {
public static void main(String[] args) {
/*三元运算符的格式
*(关系表达式) ? 表达式1 : 表达式2;
为true表达式1,为false表达式2
*/
int x = 10;
int y = 5;
int z;
z = (x > y) ? x : y;
System.out.println("z = " + z);
}
}
键盘录入的基本格式
/*如何实现键盘录入呢?
* 先照格式来。
* a:导包
* 格式:
* import java.util.Scanner;
* 位置:
* 在class上面。
* b:创建键盘录入对象
* 格式:
* Scanner sc = new Scanner(System.in);
* c:通过对象获取数据
* 格式:
* int x = sc.nextInt();
*/
import java.util.Scanner; //导入包中的类Scanner
class test {
public static void main(String[] args) {
//录入两个整数
Scanner sc = new Scanner(System.in); //创建键盘录入对象
System.out.println("请输入第一个整数:");
int x = sc.nextInt(); //将键盘录入的数据储存在x中
System.out.println(x);
System.out.println("请输入第二个整数:");
int y = sc.nextInt(); //将键盘录入的数据储存在y中
System.out.println(y);
}
}
顺序结构语句
- A:什么是流程控制语句
- 流程控制语句:可以控制程序的执行流程。
- B:流程控制语句的分类
- 顺序结构
- 选择结构
- 循环结构
- C:顺序结构语句执行流程:
- 从上往下,依次执行。
选择结构if语句格式1及其使用
- A:选择结构的分类
- if语句
- switch语句
- B:if语句有几种格式
- 格式1
- 格式2
- 格式3
- C:if语句的格式1
if(比较表达式) {
语句体;
}
- D:执行流程:
- 先计算比较表达式的值,看其返回值是true还是false。
- 如果是true,就执行语句体;
- 如果是false,就不执行语句体;
选择结构if语句注意事项
- a:比较表达式无论简单还是复杂,结果必须是boolean类型
- b:if语句控制的语句体如果是一条语句,大括号可以省略;
* 如果是多条语句,就不能省略。建议永远不要省略。 - c:一般来说:有左大括号就没有分号,有分号就没有左大括号
选择结构if语句格式2及其使用
- A:if语句的格式2
if(比较表达式) {
语句体1;
}else {
语句体2;
}
- B:执行流程:
- 首先计算比较表达式的值,看其返回值是true还是false。
- 如果是true,就执行语句体1;
- 如果是false,就执行语句体2;
- 注意事项:else后面是没有比较表达式的,只有if后面有。
if语句的格式2和三元的相互转换问题
- A:案例演示
- if语句和三元运算符完成同一个效果
- B:案例演示
-
if语句和三元运算符的区别
-
三元运算符实现的,都可以采用if语句实现。反之不成立。
-
什么时候if语句实现不能用三元改进呢?
- 当if语句控制的操作是一个输出语句的时候就不能。
- 为什么呢?因为三元运算符是一个运算符,运算符操作完毕就应该有一个结果,而不是一个输出。
-
选择结构if语句格式3
- A:if语句的格式3:
if(比较表达式1) {
语句体1;
}else if(比较表达式2) {
语句体2;
}else if(比较表达式3) {
语句体3;
}
...
else {
语句体n+1;
}
- B:执行流程:
-
首先计算比较表达式1看其返回值是true还是false,
-
如果是true,就执行语句体1,if语句结束。
-
如果是false,接着计算比较表达式2看其返回值是true还是false,
-
如果是true,就执行语句体2,if语句结束。
-
如果是false,接着计算比较表达式3看其返回值是true还是false,
-
如果都是false,就执行语句体n+1。
-
import java.util.Scanner;
class test {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个整数:");
int x = sc.nextInt();
int y;
if (x >= 3) {
y = 2 * x + 1;
}else if (x > -1 && x < 3) {
y = 2 * x;
}else if (x <= -1) { //else{ 或者 else if{
y = 2 * x - 1;
}
//要么初始化y,要么判断语句以else结尾(这样可以包含所有情况,即y总能被赋值)
//即使程序逻辑上包含了所有的情况,判断语句最后是if的话,程序也会报错。
System.out.println(y);
}
}
class test {
public static void main(String[] args) {
int a = 40;
int b = 50;
int c =30;
if (a > b) {
if (a > c) {
System.out.println(a + "是最大值");
}else {
System.out.println(c + "是最大值");
}
}else {
if (b > c) {
System.out.println(b + "是最大值");
}else {
System.out.println(c + "是最大值");
}
}
}
}
选择结构switch语句的格式
- A:switch语句的格式
switch(表达式) { //基本数据类型可以接收byte,short,char,int
case 值1: //引用数据类型可以接收枚举(JDK1.5)和String字符串(JDK1.7)
语句体1;
break;
case 值2:
语句体2;
break;
…
default:
语句体n+1;
break;
}
- B:switch语句的格式解释
- C:面试题
- byte可以作为switch的表达式吗?
- long可以作为switch的表达式吗?
- String可以作为switch的表达式吗?
- C:执行流程
- 先计算表达式的值
- 然后和case后面的匹配,如果有就执行对应的语句,否则执行default控制的语句
class test {
public static void main(String[] args) {
String name = "123";
String grade = "FG";
switch (grade) {
case "A":
System.out.println(name + "等级是" + grade);
break;
case "B":
System.out.println(name + "等级是" + grade);
break;
case "C":
System.out.println(name + "等级是" + grade);
break;
case "D":
System.out.println(name + "等级是" + grade);
break;
case "E":
System.out.println(name + "等级是" + grade);
break;
default:
System.out.println("找不到等级");
break;
}
}
}
选择结构switch语句的注意事项
- a:case后面只能是常量,不能是变量,而且,多个case后面的值不能出现相同的
- b:default可以省略吗?
- 可以省略,但是不建议,因为它的作用是对不正确的情况给出提示。
- 特殊情况:
- case就可以把值固定。
- A,B,C,D
- c:break可以省略吗?
- 最后一个可以省略,其他最好不要省略
- 会出现一个现象:case穿透。
- 最终我们建议不要省略
- d:default一定要在最后吗?
- 不是,可以在任意位置。但是建议在最后。
- e:switch语句的结束条件
- a:遇到break就结束了
- b:执行到switch的右大括号就结束了
循环结构概述和for语句的格式及其使用
- A:循环结构的分类
- for,while,do...while
- B:循环结构for语句的格式:
for(初始化表达式;条件表达式;循环后的操作表达式) {
循环体;
}
- C执行流程:
- a:执行初始化语句
- b:执行判断条件语句,看其返回值是true还是false
- 如果是true,就继续执行
- 如果是false,就结束循环
- c:执行循环体语句;
- d:执行循环后的操作表达式
- e:回到b继续。
- 注意事项
- a:判断条件语句无论简单还是复杂结果是boolean类型。
- b:循环体语句如果是一条语句,大括号可以省略;如果是多条语句,大括号不能省略。建议永远不要省略。
- c:一般来说:有左大括号就没有分号,有分号就没有左大括号
//需求:在控制台输出所有的”水仙花数”。所谓的水仙花数是指一个三位数,其各位数字的立方和等于该数本身。
class Test3_Flower {
public static void main(String[] args) {
for (int i = 100;i <=999 ;i++ ) {
int ge = i % 10; //获取100到999之间的数
int shi = i / 10 % 10; //123 % 10
int bai = i / 10 / 10 % 10; //1 % 10
if (ge * ge * ge + shi * shi * shi + bai * bai * bai == i) {
System.out.println(i);
}
}
}
}
循环结构while语句的格式和基本使用
- A:循环结构while语句的格式:
while循环的基本格式: while(判断条件语句) { 循环体语句; } 完整格式: 初始化语句; while(判断条件语句) { 循环体语句; 控制条件语句; }
- B:执行流程:
- a:执行初始化语句
- b:执行判断条件语句,看其返回值是true还是false
- 如果是true,就继续执行
- 如果是false,就结束循环
- c:执行循环体语句;
- d:执行控制条件语句
- e:回到b继续。
循环结构do...while语句的格式和基本使用
- A:循环结构do...while语句的格式:
do {
循环体语句;
}while(判断条件语句);
完整格式;
初始化语句;
do {
循环体语句;
控制条件语句;
}while(判断条件语句);
- B:执行流程:
- a:执行初始化语句
- b:执行循环体语句;
- c:执行控制条件语句
- d:执行判断条件语句,看其返回值是true还是false
- 如果是true,就继续执行
- 如果是false,就结束循环
- e:回到b继续。
- A:案例演示
- 三种循环语句的区别:
- do...while循环至少执行一次循环体。
- 而for,while循环必须先判断条件是否成立,然后决定是否执行循环体语句。
- B:案例演示
- for循环和while循环的区别:
- A:如果你想在循环结束后,继续使用控制条件的那个变量,用while循环,否则用for循环。不知道用谁就用for循环。因为变量及早的从内存中消失,可以提高内存的使用效率。(for语句执行后变量会被释放,不能再使用)(while语句执行后,初始化变量还可以继续使用)
- for循环和while循环的区别:
死循环
- A:一定要注意控制条件语句控制的那个变量的问题,不要弄丢了,否则就容易死循环。
- B:两种最简单的死循环格式
- while(true){...}
- for(;;){...}
//九九乘法表
class Demo3_For99 {
public static void main(String[] args) {
for (int i = 1;i <= 9;i++ ) {
for (int j = 1;j <= i ;j++ ) {
System.out.print(j + "*" + i + "=" + (j * i) + '\t' ); //'\t'和"\t"皆可以
}
System.out.println();
}
System.out.println("\""); //转义双引号
System.out.println('\''); //转义双引号
System.out.println('"');
System.out.println("'");
}
}
注意:
'\x' x表示任意,\是转义符号,这种做法叫转移字符。
'\t' tab键的位置
'\r' 回车
'\n' 换行
'\"'
'\''
控制跳转语句
- break的使用场景
- 只能在switch和循环中 (跳出循环)
- continue的使用场景
- 只能在循环中(终止本次循环,继续下次循环)
class Demo3_Mark {
public static void main(String[] args) {
a: for (int i = 1;i <= 10 ;i++ ) {
System.out.println("i = " + i);
for (int j = 1;j <= 10 ;j++ ) {
System.out.println("j = " + j);
break a;
}
}
System.out.println("Hello World!");
System.out.println("大家好");
http://www.heima.com
//上一行表示的是一个叫http的标号和一个注释
System.out.println("才是真的好");
}
}
- 标号:标记某个循环对其控制
- 标号组成规则:其实就是合法的标识符
*
for(int x=1; x<=10; x++) {
if(x%3==0) {
//在此处填写代码
}
System.out.println(“Java基础班”);
}
//我想在控制台输出2次:“Java基础班“ break;
//我想在控制台输出7次:“Java基础班“ continue;
//我想在控制台输出13次:“Java基础班“ System.out.println(“Java基础班”);
- A:return的作用
- 返回
- 其实它的作用不是结束循环的,而是结束方法的。
- B:案例演示
- return和break以及continue的区别?
- return是结束方法
- break是跳出循环
- continue是终止本次循环继续下次循环
方法概述
- A:为什么要有方法
- 提高代码的复用性
- B:什么是方法
- 完成特定功能的代码块。
- C:方法的格式
修饰符 返回值类型 方法名(参数类型 参数名1,参数类型 参数名2...) {
方法体语句;
return 返回值;
}
- D:方法的格式说明
- 修饰符:目前就用 public static。后面我们再详细的讲解其他的修饰符。
- 返回值类型:就是功能结果的数据类型。
- 方法名:符合命名规则即可,方便我们的调用。
- 参数:
- 实际参数:就是实际参与运算的。
- 形式参数;就是方法定义上的,用于接收实际参数的。
- 参数类型:就是参数的数据类型
- 参数名:就是变量名
- 方法体语句:就是完成功能的代码。
- return:结束方法的。
- 返回值:就是功能的结果,由return带给调用者。
//方法的例子
class Demo2_Sum {
public static void main(String[] args) {
int sum = add(10,20); //1.调用add方法,将10和20分别传递给a和b
System.out.println(sum); //5.将方法的结果返回给sum
}
public static int add(int a,int b) { //2.赋值a = 10,b = 20
int sum = a +b; //3.执行语句把a和b相加赋值给sum
return sum; //4.通过return将sum的结果返回
}
}
方法的注意事项
- A:方法调用(有具体返回值)
- a:单独调用,一般来说没有意义,所以不推荐。
- b:输出调用,但是不够好。因为我们可能需要针对结果进行进一步的操作。
- c:赋值调用,推荐方案。
- B:案例演示
- a:方法不调用不执行
- b:方法与方法是平级关系,不能嵌套定义
- c:方法定义的时候参数之间用逗号隔开
- d:方法调用的时候不用传递数据类型
- e:如果方法有明确的返回值,一定要有return带回一个值
import java.util.Scanner;
/*
A:案例演示
* 需求:根据键盘录入的行数和列数,在控制台输出星形
* B:方法调用:(无返回值,void)
* 单独调用
* 输出调用(错误)
* 赋值调用(错误)
*/
class Demo3_method {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入行数");
int row = sc.nextInt();
System.out.println("请输入列数");
int column = sc.nextInt();
print(row, column); //返回值是void方法只能单独调用
}
public static void print(int a, int b) {
for (int i = 1;i <= a ;i++ ) {
for (int j = 1;j <= b ;j++ ) {
System.out.print("*");
}
System.out.println();
}
return ; //如果返回值类型是void,return可以省略,即使省略系统也会默认给加上,形式就是return;
}
}
方法重载概述
A:方法重载概述
* 求和案例
* 2个整数
* 3个整数
* 4个整数
- B:方法重载:
-
在同一个类中,方法名相同,参数列表不同。与返回值类型无关。
-
参数列表不同:
- A:参数个数不同
- B:参数类型不同
- C:参数的顺序不同(算重载,但是在开发中不用)
-
class Demo4_Overload {
public static void main(String[] args) {
double sum1 = add(10, 20);
System.out.println(sum1);
int sum2 = add(10, 20,30);
System.out.println(sum2);
double sum3 = add(12.3,13.4);
System.out.println(sum3);
double sum4 = add(10, 20.1);
System.out.println(sum1);
double sum5 = add(12.3,13);
System.out.println(sum5);
}
public static double add(int a,int b) {
System.out.println(1);
return a + b;
}
public static int add(int a,int b,int c) {
System.out.println(2);
return a + b + c;
}
public static double add(double a,double b) {
System.out.println(3);
return a + b;
}
public static double add(int a,double b) {
System.out.println(4);
return a + b;
}
public static double add(double a,int b) {
System.out.println(5);
return a + b;
}
}
数组概述
为什么要有数组?为了储存同种数据类型的多个值
数组概念
- 数组是储存同一种数据类型多个元素的集合。也可以看成是一个容器。
- 数组既可以储存基本数据类型,也可以储存引用数据类型。
数组定义格式
//数据类型[] 数组名 = new 数据类型[数组的长度];
int[] arr = new int[5]; //可以存储五个int类型的数据
/*
左边:
int:数据类型
[]:代表数组,几个中括号就代表几维数组
arr:合法的标识符
右边:
new:创建新的实体或对象
int:数据类型
[]:代表的数组
5:代表数组的长度
*/
数组的初始化动态初始化
什么是数组的初始化?
- 就是为数组开辟连续的内存空间,并为每个数组元素赋予值。
如何对数组进行初始化
- 动态初始化: 只指定长度,由系统给出初始化值
- int[] arr = new int[5];
- 静态初始化:给出初始化值,由系统决定长度
动态初始化的格式
//数据类型[] 数组名 = new 数据类型[数组的长度];
int[] arr = new int[5]; //动态初始化,在内存中开辟连续的5块空间
动态初始化的默认初始值
整数类型:byte,short,int,long默认初始化都是0
浮点类型:float,double默认初始化值都是0.0
布尔类型:boolean默认初始化值false
字符类型:char默认初始化值'\u0000'
char在内存中占的两个字节,是16个二进制位
\u0000,每一个0其实代表的是16进制的0,那么四个0就是代表16个二进制位
打印数组输出是[I@19bb25a
[代表是数组,几个是代表几维
I代表是int类型
@是固定的
19bb25a代表的是十六进制的地址值
Java中的内存分配以及栈和堆的区别
栈:储存局部变量
局部变量:定义在方法声明上和方法中的变量
堆:储存new出来的数组或对象
方法区:面向对象部分讲解
本地方法区:和系统相关
寄存器:给CPU使用
栈和堆.jpg
一个数组内存图.png
两个数组内存图.png
三个引用两个数组.png
静态初始化
/*
* 静态初始化的格式:
* 格式:数据类型[] 数组名 = new 数据类型[]{元素1,元素2,...};
* 简化格式:数据类型[] 数组名 = {元素1,元素2,...};
*/
class Demo6_Array {
public static void main(String[] args) {
//int[] arr = new int[5]{11,22,33,44,55}; //不允许动静结合
//int[] arr2 = {11,22,33,44,55}; //静态初始化的简写形式
int[] arr; //声明数组引用
arr = new int[]{11,22,33,44,55};
int[] arr2;
arr2 = {11,22,33,44,55}; //这样会报错,简写形式声明和赋值在同一行
}
}
数组的静态初始化.png
越界和空指针
/*
a:ArrayIndexOutOfBoundsException:数组索引越界异常
原因:你访问了不存在的索引。
b:NullPointerException:空指针异常
原因:数组已经不在指向堆内存了。而你还用数组名区访问元素
int[] arr = {1,2,3};
arr = null;
System.out.println(arr[0]);
*/
class Demo7_Exception {
public static void main(String[] args) {
int[] arr = new int[5];
System.out.println(arr[-1]); //当访问数组中不存在的索引,会出现索引越界异常
arr = null;
System.out.println(arr[0]); //当数组引用赋值为null,再去调用数组中的元素就会出现空指针异常
}
}
数组遍历
/*
数组遍历:就是依次输出数组中的每一个元素。
数组的属性:arr.length数组的长度
数组的最大索引:arr.length - 1
*/
class Demo8_Array {
public static void main(String[] args) {
int [] arr = {11,22,33,44,55};
for (int i = 0;i < arr.length ;i++ ) {
System.out.println(arr[i]);
}
//arr.length 代表的是数组的长度
System.out.println(arr.length);
int [] arr2 = {3,4,5};
print(arr2);
}
/*
写一个方法,实现数组的遍历
1,返回值类型void
2, 参数列表int[] arr
*/
public static void print(int[] arr) {
for (int i = 0;i < arr.length ;i++ ) {
System.out.print(arr[i] + " ");
}
}
}
数组取最大值
/*
数组获取最值(获取数组中的最大值最小值)
*/
class Demo9_Array {
public static void main(String[] args) {
int[] arr = {33,11,22,99,44,55};
int max = getMax(arr);
System.out.println(max);
}
/*
获取数组中的最大值
1,返回值类型int
2,参数列表int[] arr
*/
public static int getMax(int[] arr) {
int max = arr[0];
for (int i = 1;i < arr.length ;i++ ) {
if(max < arr[i]) {
max = arr[i];
}
}
return max;
}
}
数组反转
//数组元素反转
class Demo10_Array {
public static void main(String[] args) {
int[] arr = {11,22,33,44,55};
reverseArray(arr);
print(arr);
}
/*
数组元素反转
1,明确返回值类型void
2,明确参数列表int[] arr
*/
public static void reverseArray(int[] arr) {
for (int i = 0;i < arr.length / 2 ; i++) {
int temp = arr[i];
arr[i] = arr[arr.length-1-i];
arr[arr.length-1-i] = temp;
}
}
/*
数组遍历
1,明确返回值类型void
2,明确参数列表int[] arr
*/
public static void print(int[] arr) {
for (int i = 0;i < arr.length ;i++ ) {
System.out.print(arr[i] + " ");
}
}
}
数组查表法
/*
数组查表法(根据键盘录入的索引,查找对应星期)
*/
import java.util.Scanner;
class Demo11_Array {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入对应的星期范围在1-7");
int week = sc.nextInt();
System.out.println("星期"+getWeek(week));
}
/*
根据索引返回对应的星期
1,返回值类型char
2,参数列表int week
*/
public static char getWeek(int week) {
char[] arr = {'一','二','三','四','五','六','日'}; //定义了一张星期表
return arr[week-1]; //通过索引获取表中元素
}
}
返回索引
//查找指定元素第一次在数组中出现的索引
class Demo12_Array {
public static void main(String[] args) {
int[] arr = {11,22,33,44,55,66,77};
int index = getIndex(arr,66);
System.out.println(index);
}
/*
查找元素索引
1,返回值类型int
2,明确参数列表,int[] arr,int value
*/
public static int getIndex(int[] arr,int value) {
for (int i = 0;i < arr.length ;i++ ) {
if (arr[i] == value) {
return i;
}
//如果将return -1移到这里会报错,因为如果不满足for的条件将没有返回值
}
return -1;
}
}
二维数组概述
/*
二维数组格式1 int[][] arr = new int[3][2];
注意事项
以下格式也可以表示二维数组
1:数据类型 数组名[][] = new 数据类型[m][n];
2:数据类型[] 数组名[] = new 数据类型[m][n];
注意下面定义的区别
int x;
int y;
int x,y;
int[] x;
int[] y[];
int[] x,y[]; x是一维数组,y是二维数组,这里的int[]是一个整体
上一行等效于 int[] x; int[]y[];
*/
class test {
public static void main(String[] args) {
int[][] arr = new int[3][2];
/*
这是一个二维数组
这个二维数组中有3个一维数组
每个一维数组中有2个元素
*/
//也可以这样写
//int[] arr[] = new int[3][2];
//int arr[][] = new int[3][2];
System.out.println(arr);
System.out.println(arr[0]);
System.out.println(arr[0][0]);
}
}
/*输出结果
[[I@1774b9b
[I@104c575
0
*/
二维数组内存图1.png
二维数组内存图2.png
class test {
public static void main(String[] args) {
int[][] arr = new int[3][]; //这是一个二维数组,这个二维数组中有三个一维数组。三个一维数组都没有被赋值
System.out.println(arr[0]); //默认初始值为null
System.out.println(arr[1]);
System.out.println(arr[2]);
arr[0] = new int[3]; //第一个一维数组中可以储存三个int值,这时候值由null变成一维数组的地址值
arr[1] = new int[5]; //第一个一维数组中可以储存五个int值
}
}
二维数组内存图3.png
class test {
public static void main(String[] args) {
int[][] arr = {{1,2,3},{4,5},{6,7,8,9}}; //这是一个二维数组,这个二维数组中每个大括号都代表一个一维数组
System.out.println(arr); //[[I@1774b9b,二维数组的地址值
System.out.println(arr[0]);//[I@104c575,一维数组的地址值
System.out.println(arr[0][0]);//输出为一维数组的元素值
}
}
二维数组遍历
class test {
public static void main(String[] args) {
int[][] arr = {{1,2,3},{4,5},{6,7,8,9}};
for (int i = 0;i < arr.length ;i++ ) {
for (int j = 0;j <arr[i].length ;j++ ) {
System.out.println(arr[i][j]);
}
}
}
}
基本数据类型的值传递
基本数据类型的值传递.png基本数据类型的值传递,不改变原值,因为调用后就会弹栈,局部变量随之消失。
引用数据类型的值传递
引用数据类型的值传递.png引用数据类型的值传递,改变原值,因为即使方法弹栈,但是堆内存数组对象还在,可以通过地址继续访问
Java中到底是传值还是传址?
java中只有传值,因为地址值也是值(java之父)
面向对象思想概述
- A:面向过程思想概述
- 第一步
- 第二步
- B:面向对象思想概述
- 找对象(第一步,第二步)
- C:举例
- 买煎饼果子
- 洗衣服
- D:面向对象思想特点
- a:是一种更符合我们思想习惯的思想
- b:可以将复杂的事情简单化
- c:将我们从执行者变成了指挥者
- 角色发生了转换
- E:面向对象开发
- 就是不断的创建对象,使用对象,指挥对象做事情。
- F:面向对象设计
- 其实就是在管理和维护对象之间的关系。
- G:面向对象特征
- 封装(encapsulation)
- 继承(inheritance)
- 多态(polymorphism)
类与对象概述
- A:我们学习编程是为了什么
- 为了把我们日常生活中实物用学习语言描述出来
- B:我们如何描述现实世界事物
- 属性 就是该事物的描述信息(事物身上的名词)
- 行为 就是该事物能够做什么(事物身上的动词)
- C:Java中最基本的单位是类,Java中用class描述事物也是如此
- 成员变量 就是事物的属性
- 成员方法 就是事物的行为
- D:定义类其实就是定义类的成员(成员变量和成员方法)
- a:成员变量 和以前定义变量是一样的,只不过位置发生了改变。在类中,方法外。
- b:成员方法 和以前定义方法是一样的,只不过把static去掉,后面在详细讲解static的作用。
- E:类和对象的概念
- a:类:是一组相关的属性和行为的集合
- b:对象:是该类事物的具体体现
- c:举例:
- 类 学生
- 对象 具体的某个学生就是一个对象
学生类的定义
- A:学生事物
- B:学生类
- C:案例演示
- 属性:姓名,年龄,性别
- 行为:学习,睡觉
class Demo1_Student {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
class Student {
String name;
int age;
String gender;
public void study() {
System.out.println("学生学习");
}
public void sleep() {
System.out.println("学生睡觉");
}
}
学生类的使用
- A:文件名问题
- 在一个java文件中写两个类:一个基本的类,一个测试类。
- 建议:文件名称和测试类名称一致。
- B:如何使用对象?
- 创建对象并使用
- 格式:类名 对象名 = new 类名();
- D:如何使用成员变量呢?
- 对象名.变量名
- E:如何使用成员方法呢?
- 对象名.方法名(...)
class Demo1_Student {
public static void main(String[] args) {
//对象名:其实就是合法的标识符,如果是一个单词所有字母小写,如果是多个单词,从第二个单词开始首字母大写
Student s = new Student();
s.name = "张三";
s.age = 23;
System.out.println(s.name + "..." + s.age);
s.study();
s.sleep();
}
}
class Student {
String name;
int age;
String gender;
public void study() {
System.out.println("学生学习");
}
public void sleep() {
System.out.println("学生睡觉");
}
}
一个对象的内存图
class Demo1_Car {
public static void main(String[] args) {
Car c1 = new Car();
c1.color = "red";
c1.num = 8;
c1.run();
}
}
class Car {
String color;
int num;
public void run() {
System.out.println(color + "..." + num);
}
}
一个对象的内存图.png
两个对象的内存图
class Demo1_Car {
public static void main(String[] args) {
Car c1 = new Car();
c1.color = "red";
c1.num = 8;
c1.run();
Car c2 = new Car();
c2.color = "black";
c2.num = 4;
c2.run();
c2 = null; //用null把原来的地址值覆盖掉了
c2.run(); //c2里面记录的是null,所以报出空指针异常
}
}
class Car {
String color;
int num;
public void run() {
System.out.println(color + "..." + num);
}
}
两个对象的内存图.png
三个引用两个对象的内存图
class Demo1_Car {
public static void main(String[] args) {
Car c1 = new Car();
c1.color = "red";
c1.num = 8;
c1.run();
Car c2 = new Car();
c2.color = "black";
c2.num = 4;
c2.run();
Car c3 = c2;
c3.run();
}
}
class Car {
String color;
int num;
public void run() {
System.out.println(color + "..." + num);
}
}
三个引用两个对象内存图.png
成员变量和局部变量的区别
-
A:在类中的位置不同
- 成员变量:在类中方法外
- 局部变量:在方法定义中或者方法声明上
-
B:在内存中的位置不同
- 成员变量:在堆内存(成员变量属于对象,对象进堆内存)
- 局部变量:在栈内存(局部变量属于方法,方法进栈内存)
-
C:生命周期不同
- 成员变量:随着对象的创建而存在,随着对象的消失而消失
- 局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
-
D:初始化值不同
- 成员变量:有默认初始化值
- 局部变量:没有默认初始化值,必须定义,赋值,然后才能使用。
-
注意事项:
- 局部变量名称可以和成员变量名称一样,在方法中使用的时候,采用的是就近原则。
- 基本数据类型变量包括哪些:byte,short,int,long,float,double,boolean,char
- 引用数据类型变量包括哪些:数组,类,接口,枚举
方法的形式参数是类名的时候如何调用
- A:方法的参数是类名public void print(Student s){};
- 如果你看到了一个方法的形式参数是一个类类型(引用类型),这里其实需要的是该类的对象,即传递的是地址值
class Demo1_Student1 {
public static void main(String[] args) {
print(10);
//print(new Student())
Student s = new Student(); //创建对象,并将对象的地址值赋值给s
print(s);
}
public static void print(int x) { //基本数据类型当作形式参数
System.out.println(x);
}
public static void print(Student stu) {
stu.name = "张三";
stu.age = 23;
stu.speak();
}
}
class Student {
String name;
int age;
public void speak() {
System.out.println(name + "..." + age);
}
}
匿名对象的概述和应用
- A:什么是匿名对象
- 没有名字的对象
- B:匿名对象应用场景
- a:调用方法,仅仅只调用一次的时候。
- 那么,这种匿名调用有什么好处吗?
- 节省代码
- 注意:调用多次的时候,不适合。匿名对象调用完毕就是垃圾。可以被垃圾回收器回收。
- 那么,这种匿名调用有什么好处吗?
- b:匿名对象可以作为实际参数传递
- a:调用方法,仅仅只调用一次的时候。
- C:案例演示
- 匿名对象应用场景
class Demo2_Car {
public static void main(String[] args) {
Car c1 = new Car(); //创建有名字的对象
c1.run();
c1.run();
new Car().run(); //匿名对象调用方法
new Car().run(); //匿名对象只适合对方法的一次调用,因为调用多次就会产生多个对象,不如用有名字的对象
//匿名对象是否可以调用属性并赋值?有什么意思?
//匿名对象可以调用属性,但是没有意义,因为调用后就变成垃圾
//如果需要赋值还是用有名字的对象
new Car().color = "red";
new Car().num = 8;
new Car().run();
}
}
class Car {
String color;
int num;
public void run() {
System.out.println(color + "车运行" + num);
}
}
匿名对象内存图.png
//匿名对象可以作为实际参数传递
class Demo2_Car {
public static void main(String[] args) {
method(new Car());
method(new Car());
}
public static void method(Car cc) {
cc.color = "red";
cc.num = 8;
cc.run();
}
}
class Car {
String color;
int num;
public void run() {
System.out.println(color + "..." + num);
}
}
封装的概述
-
A:封装概述
- 是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
-
B:封装好处
- 隐藏实现细节,提供公共的访问方式
- 提高了代码的复用性
- 提高安全性。
-
C:封装原则
- 将不需要对外提供的内容都隐藏起来。
- 把属性隐藏,提供公共方法对其访问。
private关键字的概述和特点
- A:人类赋值年龄的问题
- B:private关键字特点
- a:是一个权限修饰符
- b:可以修饰成员变量和成员方法
- c:被其修饰的成员只能在本类中被访问
- C:案例演示
- 封装和private的应用:
- A:把成员变量用private修饰
- B:提供对应的getXxx()和setXxx()方法
- private仅仅是封装的一种体现形式,不能说封装就是私有
class Demo1_Person {
public static void main(String[] args) {
Person p1 = new Person();
p1.name = "张三";
//p1.age = 17;
//p1.speak();
p1.setAge(17);
System.out.println(p1.getAge());
}
}
class Person {
String name;
private int age;
public void setAge(int a) {
if (a > 0 && a < 200) { //做判断保证数据安全性
age = a;
}else {
System.out.println("请回火星吧,地球不适合你");
}
}
public int getAge() {
return age;
}
public void speak() {
System.out.println(name + "..." + age);
}
}
this关键字的概述和应用
- A:this关键字特点
- 代表当前对象的引用
- B:案例演示
- this的应用场景
- 用来区分成员变量和局部变量重名
class Demo1_Person {
public static void main(String[] args) {
Person p1 = new Person();
p1.setName("张三");
p1.setAge(24);
System.out.println(p1.getName() + "..." +p1.getAge());
Person p2 = new Person();
p1.setName("李四");
p1.setAge(23);
System.out.println(p1.getName() + "..." +p1.getAge());
}
}
class Person {
private String name;
private int age;
public void setAge(int age) {
if (age > 0 && age < 200) { //做判断保证数据安全性
this.age = age;
}else {
System.out.println("请回火星吧,地球不适合你");
}
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
手机类代码及其测试
class Demo2_Phone {
public static void main(String[] args) {
Phone p1 = new Phone();
p1.setBrand("苹果");
p1.setPrice(6000);
System.out.println(p1.getBrand() + "价格" + p1.getPrice());
p1.call();
p1.sendMessage();
p1.playGame();
}
}
class Phone {
private String brand;
private int price;
public void setBrand(String brand) {
this.brand = brand;
}
public void setPrice(int price) {
this.price = price;
}
public String getBrand() {
return this.brand; //this.可以省略,你不加系统会默认给你加
}
public int getPrice() {
return price;
}
public void call() {
System.out.println("打电话");
}
public void sendMessage() {
System.out.println("发短信");
}
public void playGame() {
System.out.println("玩游戏");
}
}
构造方法Constructor概述和格式
- A:构造方法概述和作用
- 给对象的数据(属性)进行初始化
- B:构造方法格式特点
- a:方法名与类名相同(大小也要与类名一致)
- b:没有返回值类型,连void都没有,加上void会变成普通方法。
- c:没有具体的返回值return;
class Demo1_Constructor {
public static void main(String[] args) {
Person p = new Person(); //在一创建对象的时候,系统就自动调用了构造方法
//p.Person(); //构造方法不能对对象使用
p.show();
}
}
class Person {
private String name;
private int age;
//构造方法
public Person() {
//System.out.println("Hello World!");
//return; //构造方法也是有return语句的,格式是return;
name = "张三";
age = 23;
}
public void show() {
System.out.println(name + "..." + age);
}
}
构造方法的重载及注意事项
- A:案例演示
- 构造方法的重载
- 重载:方法名相同,与返回值类型无关(构造方法没有返回值),只看参数列表
- B:构造方法注意事项
- a:如果我们没有给出构造方法,系统将自动提供一个无参构造方法。
- b:如果我们给出了构造方法,系统将不再提供默认的无参构造方法。
- 注意:这个时候,如果我们还想使用无参构造方法,就必须自己给出。建议永远自己给出无参构造方法
class Demo1_Constructor {
public static void main(String[] args) {
Person p1 = new Person();
p1.show();
Person p2 = new Person("张三",23);
p2.show();
}
}
class Person {
private String name;
private int age;
public Person() { //空参构造
System.out.println("空参的构造");
}
public Person(String name, int age) {
this.name = name;
this.age = age;
System.out.println("有参的构造");
}
public void show() {
System.out.println(name + "..." + age);
}
}
给成员变量赋值的两种方式的区别
- A:setXxx()方法
- 修改属性值
- B:构造方法
- 给对象中属性进行初始化
class Demo1_Constructor {
public static void main(String[] args) {
Person p1 = new Person("张三",23);
//p1 = new Person("张天一",23); //这种方法看运行结果像改名了,但其实是一个新对象,原对象变成了垃圾。
System.out.println(p1.getName() + "..." + p1.getAge());
Person p2 = new Person();
p2.setName("李四");
p2.setAge(24);
p2.setName("李鬼"); //对原对象改名
System.out.println(p2.getName() + "..." + p2.getAge());
}
}
class Person {
private String name;
private int age;
public Person() { //空参构造
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
}
手机类的代码及测试
class Demo5_Phone {
public static void main(String[] args) {
Phone p1 = new Phone("苹果",5000);
p1.setBrand("三星");
p1.setPrice(2000);
p1.show();
}
}
class Phone {
private String brand;
private int price;
public Phone() {}
public Phone(String brand,int price) {
this.brand = brand;
this.price = price;
}
public void setBrand(String brand) {
this.brand = brand;
}
public void setPrice(int price) {
this.price = price;
}
public String getBrand() {
return brand;
}
public int getPrice() {
return price;
}
public void show() {
System.out.println(brand + "的价格是" + price);
}
}
创建一个对象的步骤
- A:画图演示
- 画图说明一个对象的创建过程做了哪些事情?
- Student s = new Student();
- 1,Student.class加载进内存
- 2,声明一个Student类型引用s
- 3,在堆内存创建对象,
- 4,给对象中属性默认初始化值
- 5,属性进行显示初始化
- 6,构造方法进栈,对对象中的属性赋值,构造方法弹栈
-
7,将对象的地址值赋值给s
创建对象的步骤.png
static关键字及内存图
创建对象内存图.png 静态内存图.pngstatic关键字的特点
- A:static关键字的特点
- a:随着类的加载而加载
- b:优先于对象存在
- c:被类的所有对象共享
- 举例:咱们班级的学生应该共用同一个班级编号。
- 其实这个特点也是在告诉我们什么时候使用静态?
- 如果某个成员变量是被所有对象共享的,那么它就应该定义为静态的。
- 举例:
- 饮水机(用静态修饰)
- 水杯(不能用静态修饰)
- 共性用静态,特性用非静态
- d:可以通过类名调用
- 其实它本身也可以通过对象名调用。
- 推荐使用类名调用。
- 静态修饰的内容一般我们称其为:与类相关的,类成员
static的注意事项
A:static的注意事项
* a:在静态方法中是没有this关键字的
* 如何理解呢?
* 静态是随着类的加载而加载,this是随着对象的创建而存在。
* 静态比对象先存在。
* b:静态方法只能访问静态的成员变量和静态的成员方法
* 静态方法:
* 成员变量:只能访问静态变量
* 成员方法:只能访问静态成员方法
* 非静态方法:
* 成员变量:可以是静态的,也可以是非静态的
* 成员方法:可是是静态的成员方法,也可以是非静态的成员方法。
* 简单记:
* 静态只能访问静态。
class Demo2_Static {
public static void main(String[] args) {
Demo d = new Demo();
d.print1();
Demo.print2();
}
}
class Demo {
int num1 = 10; //非静态的成员变量
static int num2 = 20; //静态的成员变量
public void print1() { //非静态的成员方法,既可以访问静态的成员也可以访问非静态的成员
System.out.println(num1);
System.out.println(num2);
}
public static void print2() { //静态的成员方法
System.out.println(num1); //静态的成员方法不能访问非静态的,错误: 无法从静态上下文中引用非静态 变量 num1
System.out.println(num2);
}
}
静态变量和成员变量的区别
- 静态变量也叫类变量 成员变量也叫对象变量
- A:所属不同
- 静态变量属于类,所以也称为为类变量
- 成员变量属于对象,所以也称为实例变量(对象变量)
- B:内存中位置不同
- 静态变量存储于方法区的静态区
- 成员变量存储于堆内存
- C:内存出现时间不同
- 静态变量随着类的加载而加载,随着类的消失而消失
- 成员变量随着对象的创建而存在,随着对象的消失而消失
- D:调用不同
- 静态变量可以通过类名调用,也可以通过对象调用
- 成员变量只能通过对 象名调用
main方法的格式详细解释
- A:格式
- public static void main(String[] args) {}
- B:针对格式的解释
- public 被jvm调用,访问权限足够大。
- static 被jvm调用,不用创建对象,直接类名访问
- void被jvm调用,不需要给jvm返回值
- main 一个通用的名称,虽然不是关键字,但是被jvm识别
- String[] args 以前用于接收键盘录入的,args是唯一可以改的东西,通过命令行键盘录入
- C:演示案例
- 通过args接收键盘例如数据
工具类中使用静态
class ArrayTool {
//如果一个类中所有的方法都是静态的,需要再多做一步,私有构造方法,目的是不让其他类创建本类对象
//直接用类名.调用即可
private ArrayTool(){}
// 1,获取最大值
public static int getMax(int[] arr) {
int max = arr[0];
for (int i = 1;i < arr.length ;i++ ) {
if(max < arr[i]) {
max = arr[i];
}
}
return max;
}
// 2,数组的遍历
public static void print(int[] arr) {
for (int i = 0;i < arr.length ;i++ ) {
System.out.print(arr[i] + " ");
}
}
// 3,数组的反转
public static void revArray(int[] arr) {
for (int i =0;i <arr.length / 2 ;i++ ) {
int temp = arr[i];
arr[i] = arr[arr.length-i-1];
arr[arr.length-i-1] = temp;
}
}
}
class Demo1_ArrayTool {
public static void main(String[] args) {
int [] arr = {33,11,22,66,55,44};
/*ArrayTool at = new ArrayTool();
int max = at.getMax(arr);
System.out.println(max);
at.print(arr);
at.revArray(arr);
at.print(arr);*/
ArrayTool.print(arr);
}
}
说明书的制作过程
- A:对工具类加入文档注释
- B:通过javadoc命令生成说明书
- @author(提取作者内容)
- @version(提取版本内容)
- javadoc -d 指定的文件目录 -author -version ArrayTool.java
- @param 参数名称//形式参数的变量名称@return 函数运行完返回的数据
学习Math类的随机数功能
- A:Math类概述
- 类包含用于执行基本数学运算的方法
- B:Math类特点
- 由于Math类在java.lang包下,所以不需要导包。
- 因为它的成员全部是静态的,所以私有了构造方法
- D:我要获取一个1-100之间的随机数,肿么办?
-
int number = (int)(Math.random()*100)+1;
Math.jpg
猜数字游戏.jpg
-
代码块的概述和分类
- A:代码块概述
- 在Java中,使用{}括起来的代码被称为代码块。
- B:代码块分类
- 根据其位置和声明的不同,可以分为局部代码块,构造代码块,静态代码块,同步代码块(多线程讲解)。
- C:常见代码块的应用
- a:局部代码块
- 在方法中出现;限定变量生命周期,及早释放,提高内存利用率
- b:构造代码块 (初始化块)
- 在类中方法外出现;多个构造方法方法中相同的代码存放到一起,每次调用构造都执行,并且在构造方法前执行
- c:静态代码块
- 在类中方法外出现,并加上static修饰;用于给类进行初始化,在加载的时候就执行,并且只执行一次。
- 一般用于加载驱动
- a:局部代码块
class Demo1_Code {
public static void main(String[] args) {
{
int x = 10; //限定变量的声明周期
System.out.println(x);
}
Student s1 = new Student();
}
static {
System.out.println("主方法中的静态代码块"); //静态代码块优先于主方法执行
}
}
class Student {
private String name;
private int age;
public Student() {} //空参构造
public Student(String name,int age) { //有参构造
this.name = name;
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
public void study() {
System.out.println("好好学习");
}
{ //构造代码块:每创建一次对象就会执行一次,优先于构造函数执行
study();
System.out.println("构造代码块");
}
static { //随着类的加载而加载,且只执行一次。
System.out.println("我是静态代码块"); //作用:用来给类进行初始化,一般用来加载驱动
}
}
网友评论