1.常量
常量是指程序运行期间,内容不可发生改变的量,像10,10.2,“hello”等都是常量
2.变量
变量与常量相反,程序运行期间,可以在一定范围内发生改变的量就是变量,变量的本质其实就是用来存放数据的一小块内存空间
变量的格式:数据类型 变量名 = 数据值
标识符的规则:
- 只能由字符、下划线_和美元符$组成
- 不能以数字开头s
- 不能是java的关键字
常见的标识符命名规则(软性建议):
- 见名只其意
- 只使用英语和数字,更不要使用拼音
- 类:每个单词首字母大写, 如Hello
- 变量第一个单词完全小写后续更多单词首字母大写(小驼峰式),如ageOfLuyi
- 方法:与变量规则一样,如show(),getAge()
- 包:其实就是文件夹,由于对类进行管理,命名建议为全部小写,多级包用点.隔开
变量的注意事项:
- 创建的多个变量不能重名
- 变量一定要赋值之后才能使用
- 变量的作用域问题:变量定义在哪个大括号中,就只能在哪个大括号中使用,超过所属的大括号,就无法使用
- 可以在一个语句中同时定义类型相同的多个变量
3.数据类型的分类
基本类型
- 整数类型:byte(占一个字节) short(占2个字节) int(占4个字节) long(占8个字节)
- 浮点类型:float(占4个字节) double(占8个字节)
- 字符类型:char(占2个字节)
- 布尔类型:boolean(占1个字节)
引用类型
- 字符串
- 类
- 接口
- 数组
- Lambda
- ...
注意事项:
- 整数类型默认为int类型
- 浮点数类型默认为double类型
- 定义一个long型数据,在数值后面要用字母L作为后缀(大小写都可以,推荐使用大写),如5000L
- 定义一个float型数据,在数值后面要用字母F作为后缀(大小写都可以,推荐使用大写),如3.14F
- 字符char型数据,是可以包含中文的
4.运算符
运算符:对常量或变量进行操作的符号,叫做运算符,例如“+”
表达式:用运算符将多个常量或变量连起来的式子,叫做表达式,例如“a+b”
常用的运算符:
算数运算符:
1.加号(+) :跟数学中的加法一样,但是+对于字符串来说,并不是相加的意思,而是连接的功能,需要注意优先级问题
String str5 = "abc" + 10 + 20
//结果为:abc1020
String str5 = "abc" + (10 + 20)
//结果为:abc30
2.减号(-)
3.乘号(*)
4.除号(/)这里的除号是整除,只看商,不看余数
5.求余(%):取模运算,取得余数,只看余数,不看商
6.自增运算符(++):在变量的原有基础上加1,可以写在变量前面,也可以写在变量后面
a.单独使用的时候:前++和后++无任何区别
b.如果和其他运算符混合使用时:如果是前++,那么变量马上+1,然后拿着结果进行使用,如果是后++,那么首先使用当前的本来数据,然后再进行+1操作
- 自减运算符(--):在变量的原有基础上减1
- 计算中如果有小数参与,那么结果一定是小数
赋值运算符
- 基本赋值运算符:表示将右侧的数值赋给左边的变量
- 复合赋值运算符:如 a += 3,a *= 4
- =左侧不能是常量,右侧既可以是常量也可以是变量
比较运算符:比较运算符的结果一定是一个布尔值,要么为true,要么为false
- 大于 >:
- 小于 <:
- 大于等于 >=
- 小于等于 <=
- 不等于 !=
- 等于 ==
逻辑运算符:
- 与(&):全为true才为true
- 或(|):有一个true就是true
- 异或(^):相同是true,不同是false
- 非 取反(!):本来true变成false,本来是false变为true
- 短路使用:如果左侧已经可以判断到最终结果,那么右侧将不再执行
- 短路与(&&)
- 短路或(||)
位运算符(了解)
^的特殊使用:两次异或不改变原值
位运算可能会出现的面试题:
A:请实现两个变量的交换:用位异或运算符实现
a = a^b; b = a^b; a = a^b
B:请用最有效率的方式计算出2乘以8的结果
2<<3
5.Scanner键盘输入
使用引用类型的三个步骤:
1.导包:指定需要使用的目标在什么位置,在public class之前写一行代码 import 包路径名
import java.util.Scanner;
2.创建:数据类型 变量名称 = new 数据类型()
Scanner sc = Scanner(System.in);
3.使用:变量名称.方法名();
String str = sc.next()
int num = sc.nextInt()
总代码:
import java.util.Scanner;
public class Sc{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
System.out.println("please input something");
String str = sc.next();
System.out.println(str);
}
}
6.流程
顺序结构:程序自上而下一条线走下来
选择结构(if-else):
1.单if语句
if(布尔表达式){
语句体;
}
//如果布尔表达式为true,则执行语句体,否则,不执行;
2.标准if-else语句
if(布尔表达式){
语句体A;
}else{
语句体B;
}
//如果布尔表达式为true,则执行语句体A,否则,执行语句体B;
3.扩展if-else语句
if(布尔表达式1){
语句体A;
}else if(布尔表达式2){
语句体B;
}
...
else if(布尔表达式N){
语句体N
}else{
语句体N+1
}
例子:求两个数的最大值
import java.util.Scanner;
public class MaxNumber{
public static void main(String[] arg){
Scanner sc = new Scanner(System.in);
System.out.println("please the num1: ");
int num1 = sc.nextInt();
System.out.println("please the num2: ");
int num2 = sc.nextInt();
if(num1 > num2){
System.out.println("the max number is" + num1);
}else{
System.out.println("the max number is" + num2);
}
}
}
选择结构(switch):
格式:
switch(表达式){
case 值1:
语句体1;
break;
case 值2:
语句体2;
break;
...
default:
语句体n + 1;
break;
}
格式解释说明:
1.switch:说明这是switch语句
2.表达式:可以是byte,short,int,char,不可以是long,JDK5之后可以是枚举,JDK7以后可以是字符串
3.case:后面的值就是要和表达式进行比较的值
4.break:表示程序到这里中断,跳出switch语句
5.default:如果所有情况都不匹配,就执行这里,相当于if语句中的else
执行流程:
1.首先计算表达式的值
2.和每一个case语句进行匹配,如果有匹配的就执行对应的语句体,看到break就结束
3.如果没有匹配到,就执行default的语句n+1
注意事项:
1.case后面只能是常量,不能是变量,而且,多个case后面的值不能出现相同的
2.default可以省略,但是不建议,因为它的作用就是对不正确的情况给出提示
3.break可以省略,但是结果可能不是我们想要的,会出现case穿透的现象,所以不推荐省略
4.default不一定要在最后,可以是任意位置,但是建议放在最后
5.switch语句结束的条件
- 遇到break就结束
- 执行到末尾就结束
示例代码:
import java.util.Scanner;
public class Demo11 {
public static void main(String[] args) {
System.out.println("请输入一个数字(1-7)");
Scanner sc = new Scanner(System.in);
int day = sc.nextInt();
String week = null;
switch(day){
case 1:
week = "一";
break;
case 2:
week = "二";
break;
case 3:
week = "三";
break;
case 4:
week = "四";
break;
case 5:
week = "五";
break;
case 6:
week = "六";
break;
case 7:
week = "天";
break;
default:
System.out.println("数据错误!");
}
System.out.println("今天星期" + week);
}
}
循环结构
循环结构的组成部分
- 初始化语句:这部分内容最先执行,而且仅执行一次;
- 条件判断:如果成立,则循环继续,如果不成立,则循环中止;
- 循环体:每次循环都将重复执行循环体的代码内容;
- 步进语句:每次循环执行后,都会执行一次步进语句;
for 循环:通常用于控制次数的场景
for(初始化语句;条件判断,步进语句){
循环体;
}
例子:求出1-100的偶数和
public class EvenNumber{
public static void main(String[] arg){
int sum = 0;
for(int i = 1; i < 101; i ++){
if(i % 2 == 0){
sum += i;
}
}
System.out.println("the sum is: " + sum);
}
}
whlie循环:
标准模式:
while(条件判断){
循环体;
}
//当条件满足时执行循环体,不满足则跳出循环体
扩展模式:
初始化语句;
while(条件判断){
循环体;
步进语句;
}
例子:求1-100的奇数和
public class OddNumber{
public static void main(String[] arg){
int sum = 0;
int i = 1;
while( i < 101){
if(i % 2 == 1){
sum += i;
}
i ++;
}
System.out.println("the sum is: " + sum);
}
}
for循环与while循环的区别:for循环的步进语句还能接着走,而whlie的步进语句由于continue跳出了循环,导致剩余内容的步进语句也没被跳过
public class ContinueDemo{
public static void main(String[] arg){
for(int i = 1; i < 10; i ++){
if(i == 4){
continue;
}
System.out.println(i);
}
System.out.println("=====================");
int i = 1;
while(i < 10){
if(i == 4){
continue;
}
System.out.println(i);
i ++;
}
}
}
//输出结果为:
1
2
3
5
6
7
8
9
=====================
1
2
3
1.for循环格式固定,控制次数更方便,而while循环格式更加灵活,不在意循环次数,循环次数确定的使用for较多,次数不确定,使用while较多
2.for循环小括号内定义的变量,循环内可用,循环外不可用,while循环的初始化表达式本来就在外面,仍然可用
3.跳转语句continue的效果不同:
跳转控制语句:
- break语句:跳出循环
- continue语句:只跳出本次循环,后续还要继续循环
死循环(永真循环):
这两种方法可以实现死循环
while(true){
}
for(; ;){
}
嵌套循环:
//打印一天中所有可能出现的时:分
public class Clock{
public static void main(String[] arg){
for(int i = 0; i < 24; i ++){
for(int j = 0; j < 60; j ++){
System.out.println(i +":" + j);
}
}
}
}
7.集成开发环境(IDE)
我们这里介绍Eclipse,因为他是完全免费的
Eclipse IDE基本特点:
- 完全免费
- 完全开源
- java语言编写
- 绿色软件:解压就能用,不用安装
- 扩展性很强
下载:官网:http://www.eclipse.org
安装:解压就可直接使用
卸载:删除从官网下载的文件夹即可
Eclipse使用的常用快捷键
- 添加单行注释:Ctrl + / 取消:Ctrl + /
- 添加多行注释:Ctrl + Shift + / 取消:Ctrl + Shift + /
- 向上向下复制一行:Ctrl+Alt+向上/向下
- 向上向下移动一行:Alt+向上/向下
- 删除当前行:Ctrl+D
- 格式化:Ctrl+Shift+F
- 智能提示:Alt+/
8.数组的使用
概述:数组是一种引用类型。变量只可以存放一个数据,数组则可以存放多个类型统一的数据,可以存放基本类型,也可以存放引用类型;
数组的格式:
- 数据类型[] 数组名称;
- 数据类型 数组名称[];(不推荐)
数组的初始化:使用之前一定要先初始化
1.动态初始化:指定数组的长度
//创建了一个可以存放三个数据的int类型的数组array1
int array1 = new int[3]
2.静态初始化:指定数组的内容,会自动根据内容推算出数组的长度
/*标准格式, 标准格式可以拆分为
int array2[];
array2[] = new int[]{1, 2, 3};*/
int array2[] = new int[]{1, 2, 3};
System.out.println(array1);
/*简便格式,不可以拆分为
int array3[];
array3 = {1, 2, 3};*/
int array3[] = {1, 2, 3};
数组的访问:
- 直接打印array1会得到一个包括地址值,如[I@15db9742
- 打印array1[0]:会得到数组中索引为0的值,数组的索引也就是数组中元素的编号,编号从0开
数组的默认值:
当你没有给数组赋值的时候,数组会有自己的默认值,不同数据类型的数组会有不同,整数类型的数组的默认值为0,布尔值类型的数组的默认值为false,浮点类型的数组的默认值为0.0
数组获取长度:数组名称.length,当一个数组在内存中被创建了的时候,那么数组的长度旧不能发生改变
数组在堆栈中存放的情况:
二维数组:元素是一维数组的数组
1.格式:
A.数据类型[][] 数组名 = new 数据类型[m][n];
B.数据类型[][] 数组名 = new 数据类型[m][];
C.数据类型[][] 数组名 = new 数据类型[][]{{...},{...}};
D.数据类型[][] 数组名 = {{...},{...}};
9.java内存分配
栈(Stack):主要用来存放局部变量
堆(Heap):凡是new出来的东西,都在堆当中,都有地址,堆当中的数据有默认规则:
如果是整数,默认是0
如果是浮点数,默认为0.0
如果是字符,默认是‘\\u0000’(Unicode写法)
如果是布尔值:默认是false
如果是引用类型(包括Striing),默认是null(空常量)
数据使用完毕后,在垃圾回收器空闲的时候回收
方法区(Method Area):
与面向对象的知识点相关,再后面详说
本地方法区(Native Method):
与操作系统相关
寄存器(Register):
与CPU相关,性能极高
10.方法
概述:对于一些复杂的代码逻辑,如果希望重复使用这些代码,并且做到“随时任意使用”,那么就可以将这些代码放在一个大括号“{}”之中,并且起一个名字,使用代码的时候,直接找到名字调用即可;
方法的格式:
修饰符 返回值类型 方法名称(参数类型 参数名称){
方法体;
return返回值;
}
解释:
- 修饰符:目前就用public static,后面再详细讲解其他修饰符
- 返回值类型:方法最终产生的数据是什么类型
- 方法名称:自定义的名字,规则和变量一样
- 参数类型:进入方法的数据是什么类型
- 参数名称:进入方法的数据,对应的变量名称
- 方法体:需要执行的若干代码
- return:有两个作用,结束当前方法和带着后面的返回值交给调用处
- 返回值:方法的最终数据结果
注意事项:
- 返回值类型必须和返回值对应
- 如果参数有多个,那么使用逗号隔开
- 如果不需要参数,那么小括号内可以留空
调用方法的三种方法:
- 单独调用:格式为 方法名称(参数值),这种调用无法使用方法中的返回值
- 打印调用:格式为 System.out.println(方法名称(参数值)),调用方法,并把返回值打印出来
- 赋值调用:格式为 数据类型 变量名称 = 方法名称(参数值),注意变量的数据类型必须和方法的返回值数据类型一致
有返回值的方法的例子:求两个数之和
public class Demo2 {
public static int plus(int num1, int num2){
return (num1 + num2);
}
public static void main(String[] args) {
int sum = plus(3, 4);
System.out.println("the sum is: " + sum);
}
}
关于名称的两个问题:
- 变量的名称能不能和方法的名称一样?可以
- 如果有两个方法,每一个方法当中都有一个同名的变量,是否可以?可以,虽然名称相同,但是他们是两个变量
没有返回值的方法格式:没有返回值的时候,只能使用单独调用,不能使用打印调用或赋值调用
修饰符 void 方法名称(参数类型 参数名称){
方法体;
return;//最后一行的return可以省略不写
}
无返回值的方法的例子(遍历数组并打印出来的方法):
public class Demo3 {
public static void arrayMethod(int[] array){
for(int i = 0; i < array.length; i ++){
System.out.println(array[i]);
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] array1 = {1, 2, 3};
arrayMethod(array1);
}
}
方法的重载:
1.问题描述:对于类似的多个方法,全都是执行相加的操作,但是因为参数列表不一样,所有要记住很多名字,太麻烦
2.解决方案:使用方法的重载技术,可以达到效果,对于类似功能的多个方法,只要记住一个相同的方法名即可,可以根据参数列表的不同自动适配
3.方法重载(Overload):方法的名称相同,但是参数列表不同(包括参数个数不同,参数类型不同,参数的多类型顺序不同)
重载的例子:
public class Demo4 {
public static void main(String[] args) {
int sum1 = Plus(1, 2);//3
int sum2 = Plus(1, 2, 3);//6
int sum3 = Plus(1, 2, 3, 4);//10
System.out.println(sum1 + " " + sum2 + " " + sum3);
}
public static int Plus(int a, int b){
return a + b;
}
public static int Plus(int a, int b, int c){
return a + b +c;
}
public static int Plus(int a, int b, int c, int d){
return a + b + c +d;
}
}
重载的注意点:
1.无法根据参数的名称进行重载,当两个方法的参数名不同,但是功能完全一样时,不能进行重载
2.无法根据返回值类型的不同进行重载,当两个方法的返回值类型不同时,也不能进行重载
参数传递:
1.概述:在调用方法的时候,向方法内传入一些数据的动作
2.形式参数与实际参数:在定义方法的时候,写在小括号里面的参数就是形式参数,而在调用方法时,真正传入方法里的数据就叫做实际参数
3.参数传递的过程的两项规则:对于基本数据类型(以及String)来说,传递的是值,形式参数的操作不会影响实际参数;而对于引用类型(除String外),传递的是地址,形式参数的操作会影响实际参数