一、Java概述
1、java特点
- Java是面向对象的一门编程语言;
- 强类型机制、异常处理、垃圾自动回收等是java程序健壮性的重要保证;
- Java语言因为有多平台的jvm虚拟机的原因,所以Java具有跨平台的特点;
- Java是解释性语言,编译后的代码不能被机器直接执行,而是需要解释器执行(编译性语言,编译后的代码可以直接被机器执行)。
public class Hello {
public static void main(String[] args) {
System.out.println("=============Hello,World!==========");
}
}
执行一个java程序的基本步骤:
第一步: 执行javac 文件名.java
生成后缀名为class的字节码文件
第二步: 执行java 文件名
运行字节码文件
反编译:文件名.class----javap 文件名.class
-----> 文件名.java
2、Java环境
(1)JVM
JVM是一个虚拟的计算机,具有指令集并使用不同的存储区域,负责执行指令,管理数据、内存、寄存器等;对于不同平台会有不同的虚拟机;JVM屏蔽了底层运行平台的差异,实现了“一次编译,到处运行”特性,具有跨平台性。
(2)JDK和JRE
JDK(Java Development Kit) java开发工具包,提供给开发人员使用;JRE(Java Runtime Environment) java运行环境。
JDK=JRE+java的开发工具{java,javac,javadoc,javap}
JRE=JVM+java se标准类库
JDK=JVM+java se标准类库+java的开发工具
3、Java命名规范
(1)文件名命名规则与规范
一个java源文件中最多只有一个public类,其他类的个数不限,如果源文件中有一个public类则文件名必须是该public类的类名。
(2)标识符命名规则与规范
Java对各种变量、方法和类等命名时使用的字符序列称为标识符
1. 命名规则
由26个英文字母大小写,数字0-9,_或$组成,不能以数字开头,不可以使用关键字和保留字,英文字母严格遵循大小写,长度无限制。
2. 命名规范
类名、接口名 多个单词组合时,所有单词的首字母大写(大驼峰)
变量名、方法名 多个单词组合时,第一个单词首字母小写,其余单词首字母大写 (小驼峰)
常量名所有字母大写,多单词时用下划线连接
(3)包名命名规则与规范
1. 包名规则
只能包含数字、字母、下划线、小圆点,不能以数字开头,不能是关键字或保留字,多个单词组合时,所有字母小写
2. 包名规范
一般是小写字母+小圆点 com.公司名.项目名.业务模块名
3、Java注释
(1)单行注释
//注释文字
在idea中快捷键是 ctrl + /
(2)多行注释
/*
注释文档:
*/
(3)文档注释
- 基本格式
/**
*@author 作者名字 // @author 代表javadoc标签
*@version 版本号
*/
- 生成对应的文档注释
javadoc -d 目录名 -author -version -其他javadoc标签 文件名.java
二、数据类型
1、基本数据类型
(1)数值类
1.整数类型 (int)
类型 | 存储空间 | 取值范围 |
---|---|---|
字节型byte | 1字节 | -128~127 |
短整型short | 2字节 | –215~215-1 |
整型int | 4字节 | -231~231-1 |
长整型long | 8字节 | -263~263-1 |
java整型常量默认 int 型,声明 long 类型常量须后加l
或L
,例如:int d=1L
bit是计算机种最小的存储单位, byte 是计算机中基本存储单元1byte=8bit
例如:10的在计算机的表示:00000000 00000000 00000000 00001010
思考题: Long类型有几个bit? 答案:64bit
2.浮点类型 (double)
类型 | 存储空间 | 取值范围 |
---|---|---|
单精度float | 4字节 | -3.403E38~3.403E38 |
双精度double | 8字节 | -1.798E308~1.798E308 |
java的浮点常量默认 double 类型,声明 float 类型常量须后面加f
或F
,例如:float a=1.1f
float会舍去 7 位小数后的数据,取近似值;而 double 则全部小数位都保留
(2)字符类
类型 | 存储空间 | 取值范围 |
---|---|---|
字符型char | 2字节 | 单引号括起来的单个任意字符,值可以是转义字符 |
字符类本质是一个整数,在输出时,是unicode
码对应的字符,输出数字时可以使用(int)变量名
存储:
'a'
--> unicode码值97 --> 编码二进制 1100001 --> 存储
读取: 二进制 1100001–> unicode 码值97 -->’a’
基本类型转换成String引用类型时:
a+"" +b +""+c
一定要用双引用号,用单引号会对字符的 unicode码 进行计算
String类型转换成基本类型:
转为int:Integer.parseInt(s)
转为double:Double.parseInt(s)
转其他:Float.parseInt(s)
Long.parseInt(s)
Byte.parseInt(s)
Boolean.parseInt(s)
(3)布尔类 boolean
类型 | 存储空间 | 取值范围 |
---|---|---|
布尔型Boolean | 1字节 | false或true |
布尔类基本用于逻辑运算
2、引用数据类型
(1)类class
1. 类的定义
类是抽象的概念的,对象是具体的,类是对象的模板。
类由两部分构成,分别是成员变量和成员方法,创建一个类就是创建一个新的数据类型,实例一个类就得到一个对象。
[类修饰符] class 类名 [extends 基类] [implements 接口列表]{
[访问修饰符] 属性类型 属性名 [=初始值]; // 成员变量
[访问修饰符] 方法名 { // 构造方法
[方法体;]
}
[访问修饰符] 返回数据类型 方法名(形参类型 形参名)([形参列表]) [throws 异常名1,...,异常名N]]{ // 成员方法
语句;
(return 返回值;)
}
}
class关键字表示类定义的开始;类名要符合标识符的命名规范;
2. 创建类对象
(1)先声明再创建
声明对象: 类名 对象名;
在栈中创建一个对象,指向一个空值
创建对象: 对象名=new 类名();
在堆中开辟空间,然后将堆中的地址返回给栈里的对象,使栈中对象指向堆中的地址
声明并不为对象分配内存空间,而只是分配一个引用空间;对象的引用类似于指针,是32位的地址空间,它的值指向一个中间的数据结构,它存储有关数据类型的信息以及当前对象所在的堆的地址,而对于对象所在的实际内存地址是不可操作的,这就保证了安全性。
(2)直接创建
类名 对象名=new 类名();
3. 类修饰符
类的访问控制符有两个,分别是public(公共类)、默认(没有控制符)
- 公共类是可以被所有类访问和引用;在java源程序中只能有一个public类,而这个类一般含有main方法。
- 默认类只能被同一包中定义的类访问和引用;在java源程序中可以定义多种这样的类。
4. 成员变量
成员变量是在类体的变量部分中定义的变量,java中的实例变量、类变量、常量都属于成员变量,取值可以是基本类型或数组也可以是类的对象。
1、创建成员变量
语法:
[访问修饰符] [static | final] 属性类型 属性名 [=初始值];
功能描述: 定义一个成员变量
访问修饰符: 控制属性的访问范围,有public,procteected,默认,private
属性类型: 基本类型或引用类型
初始值: 可以不赋值也可以赋值
成员变量如果不赋值则有默认值,规则与数组一样,int 0,short 0,byte 0,long 0,flaot 0。0,double 0.0,char \u0000,boolean false,String null
2、访问成员方法
本类访问:
this.变量名
|变量名
(直接调用)
外部类访问:对象名.变量名
派生类访问:super.变量名
(取决于访问修饰符)
5. 成员方法
成员方法用于处理类中的数据
1、创建成员方法
语法:
[访问修饰符] [static | final] 返回数据类型 方法名(形参类型 形参名){ 代码语句块;};
功能描述: 创建一个成员方法,成员方法可以访成员属性和静态属性与静态方法
访问修饰符:public
、private
、默认、protected
返回数据类型: 有返回值时可以是java中所有类型;如果没有返回值是void
关键字,一个方法只有一个返回值,且使用return
关键字返回
形参类型: 可以是任意类型,一个方法可以有0或多个参数,中间逗号分隔
调用: 在同个类中,调用类中其他方法时可直接调用;调用其他类的方法时需要先声明创建对象才能调用方法;跨类的方法调用和方法的访问修饰符相关,(访问修饰符再细讲)
传参机制: 如果传参是引用类型时,形参会影响实参,形参置空时不影响实参。
当main栈中的程序执行到方法时,就会开辟一个独立的空间栈;在新的空间栈中执行到return时候会把值返回给main栈的主程序中,而新的空间栈会被释放
2、调用成员方法
本类访问:
this.方法名([实参])
|方法名(实参)
外部类访问:对象名.方法名([实参]);
派生类访问:super.方法名([实参])
5. 构造方法(构造器)
含义:完成对新对象的初始化,是一类特殊的成员方法
(1)创建构造器
语法:
[访问修饰符] 方法名 { 语句块; };
功能描述: 创建一个构造器,初始化对象的数据
修饰符: 默认、public
、private
、protected
,多数时候使用public
修饰
功能描述: 在创建对象时,系统会自动调用该类的构造器完成对对象的初始化
方法名: 方法名与类名必须一致
- 构造器没有返回值;
- 一个类可以定义多个不同的构造器(构造重载);
- 如果没有定义构造器时,系统会自动给类生成一个默认无参构造器,一旦定义了自己的构造器默认的构造器就会被覆盖,除非显式定义无参构造器
类名(){}
。
(2)实例化类的对象
语法:
类名 对象名=new 构造函数 (实参);
new: 在堆中开辟一个存储空间并返回给对象,调用构造方法初始化数据。
构造器复用
class Employee{
String name;
char sex;
int age;
String job;
double salary;
Employee(){ // 默认无参构造器
}
Employee(String job,double salary){
this.job=job;
this.salary=salary;
}
Employee(String name,char sex,int age){
this.name=name;
this.sex=sex;
this.age=age;
}
Employee(String name,char sex,int age,String job,double salary){
this(name,sex,age); // 构造器复用,后面不能再使用this(job,salary)了,因为this()再构造器使用中之只能放在第一行中使用
this.job=job;
this.salary=salary;
}
}
6. this关键字
Java虚拟机会给每个对象分配this
,代表当前对象;this
可以访问属性、方法和构造器;可用于区分该类的属性和局部变量;只能在类定义中使用,不能在类外部使用
访问成员方法:
this.方法名(实参)
访问构造器:this(实参)
只能在构造器中使用且必须放在第一条语句
7. 可变参数
Java允许将同一个类中多个同名同功能但参数个数不同的方法,封装成一个方法,就可以通过可变参数实现。
语法:
访问修饰符 返回类型 方法名(数据类型... 形参名){ }
功能描述: 通过形参名接受多个参数注意:
1.可变参数的实参可以是0或任意多个;
2.实参可以是数组且本质是数组;
3.可变参数与普通形参一起时,可变参数必须是在形参列表的最后;
4.一个形参列表中只能出现一个可变参数。
8. 方法重载(overloading)
java中允许一个类中,多个同名方法的存在,但要求形参列表不一致,构造方法可以重载。
例如System.out.print可以传入不同的形参,out是PrintStream类型
class MyCalculator{
public int calculate(int n1,int n2){
return n1+n2;
}
public double calculate(int n1,double n2){
return n1+n2;
}
public double calculate(double n1,int n2){
return n1+n2;
}
public int calculate(int n1,int n2,int n3){
return n1+n2+n3;
}
public int calculate(int n1,int n2){
return n1+n2;
}
}
注意:方法名要相同且形参列表必须不同才能构成重载,返回类型无要求
9. 作用域
在java中主要变量是属性(全局变量)和局部变量。
作用域 | 定义 | 赋值 | 作用范围 | 是否可加修饰符 | 生命周期 |
---|---|---|---|---|---|
全局变量 | 既可以是某对象函数创建,也可以是在本程序任何地方创建。 | 可以不赋值,系统会自动分配默认值 | 可以被本类使用,也可以被其他类使用(使用时需要声明创建对象才能使用) | 是 | 全局变量生命周期较长,伴随对象的创建到死亡 |
局部变量 | 由某对象或某个函数所创建的变量通常都是局部变量,只能被内部引用,而无法被其它对象或函数引用。 | 必须赋值,无默认值 | 只能被本类中的局部变量范围内使用 | 否 | 生命周期较短,伴随着他的代码块执行而创建,结束而死亡。 |
全局变量和局部变量可以重名,访问时遵循就近原则;在同一个作用域中,两个局部变量不能重名。
10. 类变量与类方法
被static
修饰的属性(变量)称为静态属性或类变量,被static
修饰的方法称为静态方法或类方法,静态变量和方法实现同类的所有实例对象共享,是在类加载时生成,随着类销毁而死亡。
类加载一般在什么时候?
1.创建对象实例
2.创建子类对象实例,父类也会被加载
3.使用类的静态成员时(静态属性,静态方法)
(1)创建类变量或类方法
语法:
[修饰符] static 数据类型 变量名
/[修饰符] static [void | 数据类型] 方法名
功能描述: 创建一个静态变量或静态方法,数据存放在数据区,无需创建对象即可访问或调用类变量和类方法
注意: 静态方法语句块内不能使用this关键字且不能直接调用非静态的方法,但可以直接调用static修饰的方法;
(2)调用类方法或类属性
语法:
类名|变量名.静态变量
/类名|变量名.静态方法名([实参])
/静态方法名([实参])
功能描述: 外部类调用类变量和类方法,或本类调用静态方法
注意: 非静态方法可以调用静态属性
(3)静态代码块与非静态代码块的异同点
语法:
[修饰符]{代码块}
功能描述: 非静态代码块注意:
1.没有方法名,没有返回,没有参数,只有方法体
2.代码块优先于构造器
3.使用static修饰的是静态代码块,作用是对类进行初始化,随着类的加载而执行,并且只会执行一次
4.普通修饰符修饰的代码块,在创建对象实例时会被隐式调用,被创建一次就会调用一次
class Person{
{
非静态代码块;
}
static{
静态代码块;
}
}
静态代码块只能定义在类里面,不能定义在方法里;块内的变量都是局部变量,只能在本块内有效;会在类被加载时自动执行;静态代码块只能访问类的静态成员,不能访问实例成员。
名称 | 相同点 | 不同点 |
---|---|---|
静态代码 | JVM加载时会在构造方法前执行,在类中可定义多个 | 在第一次new执行一次,之后不会再执行;静态代码块在非静态代码块前执行; |
非静态代码 | JVM加载时会在构造方法前执行,在类中可定义多个 | 在每次new就执行一次;静态代码块在非静态代码块前执行 |
创建一个对象时,各个代码块的调用顺序
- 父类的静态代码块和静态属性
- 子类的静态代码块和静态属性
- 父类的非静态代码块和非静态属性初始化
- 父类的构造方法
- 子类的非静态代码块和非静态属性初始化
- 子类的构造方法
构造器中最前面隐含了super()和调用普通代码块
class A{
public A(){
//super();
//调用非静态代码块;
System.out.println("ok");
}
}
(2)接口 interface
java的普通类只能单继承,接口是用来实现类间多重继承功能的结构,是一特殊的“类”,一种特殊的“抽象类”。
接口是一组方法集,接口中包含的方法都是抽象方法,定义方法体的任务留给实现该接口的类来完成。
接口可以实现不相关类的相同行为,而不需要考虑这些类之间的层次关系。
1.接口可以定义多个类需要实现类的实现方法
2.接口可以了解对象的交互界面,而不需要了解对象所对应的类。
3.接口可以在运行时动态地定位类所调用的方法。
1. 接口定义
接口通过使用关键字interface
来声明,在 jdk8 之前,接口体只有抽象方法;jdk8 版本后允许使用default
关键字定义的实例方法但必须是public
,也允许接口体中定义static
方法;jdk9 后允许接口体中定义private
方法
- 接口中所有方法默认
public abstract
修饰,并且没有方法体; - 所有变量都默认
public static final
修饰的,即变量不支持重写; - 接口中没有构造方法;
- 接口可以继承且支持多继承。
[public] interface 接口名称 [extends 父接口1[,父接口2,...,父接口N]]{ // 接口支持多继承
[public static final] 数据类型 变量名 =常量名; // 默认public static final修饰
[public abstract][native] 返回值类型 方法名(参数列表); // 默认public abstract修饰
}
注意:
接口中的方法体可以由其他语言来书写,前提需要使用native
关键字修饰
2. 实现接口
一个类可以实现多个接口,一个类在实现某个接口的抽象方法时,必须以完全相同的方法头,否则只是在重载一个新方法而不是实现已有的抽象方法。
语法:
[类修饰符] class 类名 [extends 父类名] implements 接口1[,接口2,...,接口N]{}
功能描述: 继承并实现接口的方法,拥有接口中的常量和除了private
和static
修饰方法的其他方法方法体:
1.重写接口中的抽象方法时不可省略public
关键字,否则将被警告为缩小了接口中定义的方法的访问控制范围。
2.default
方法重写时,需去掉default
关键字
3.调用接口中的常量和static方法:接口名.常量名;
|接口名.方法名();
3. 接口回调
可以把实现某一接口的类创建的对象引用赋给该接口声明的接口变量中,那么该接口变量就可以调用被类重写的接口方法。
语法:
接口名 接口变量名=new 实现接口方法的类名;
---->接口变量名.方法名();
功能描述: 接口回调,实际上是向上转型,接口变量指向实现接口的类实例
(3)数组
1. 数组的概念
数组是一组有序的地址、具有相同数据类型的数据集合,实现对这些数据的统一管理,数组中的元素可以是任何数据类型。
数组对象的存储单元示意图:
2. 创建数组
语法:
数据类型[] 数组名 | 数据类型 数组名[]=new 数据类型[]
功能描述: 声明并创建数组对象,会开辟一个新的数据空间,并将数据空间赋给数组对象,元素的值都为0
例子:int arr[]=new int[];
// 创建后没有赋值会有默认值,默认值为0
数组赋值机制:默认引用地址,赋值方式为引用赋值,赋的是地址;基本数据类型是值传递;
多维数组的创建:
数据类型[][] 数组名 | 数据类型 数组名[][]=new 数据类型[][]
没有赋值时会默认以下值的情况:
数据类型 | 默认值 | 数据类型 | 默认值 |
---|---|---|---|
int | 0 | short | 0 |
byte | 0 | long | 0 |
flaot | 0.0 | double | 0.0 |
char | \u0000 | boolean | false |
String | null | 复合数据类型 | null |
3. 数组的访问与赋值
(1) 数据访问
语法:
数组名[index]
功能描述: 根据index来访问数组中的元素
参数说明:
index: 从0开始,上限是数组元素总个数-1,越界时时可以编译但运行时会抛出异常
(2) 数组赋值
语法:
数组名[index]=new_value
功能描述: 根据index来访问数组中的元素,然后赋值给该元素
4. 数组初始化
(1)静态初始化
语法:
数据类型[] 数组名 | 数据类型 数组名[]={元素1,元素2,..,元素N}
功能描述: 静态地将左边具体的值赋给数组对象
(2)动态初始化:
语法:
数据类型[] 数组名 | 数据类型 数组名[]=new 数据类型[size]
例如:
int arr[];
// 声明一个数组arr,尚未分配内存
int arr=new int[5];
// new后会开辟一个新的5*32大小的数据空间,并把arr[0]的地址给栈中的数组,元素的值都为0
5. 数组拷贝
数组创建后就不能改变它的大小,但是可以使用相同引用变量指向一个全新的数组可达到拷贝或修改数组大小作用。拷贝数组还能通过使用System类提供的一个特殊方法arraycopy()。
语法:
System.arraycopy(原数组,开始下标,目标数组,开始下标,拷贝长度)
功能描述: 将原数组中的指定连续元素复制到目标数组的指定连续位置上
附加知识:自动类型转换与强制类型转换
概念:当java程序在进行赋值或运算时,精度小的类型会自动转换为精度大的数据类型
char --> int --> long --> float --> double
byte --> short --> int --> long --> float --> double
自动类型转换的逆过程,将容量大的数据类型转换成容量小的数据类型,使用时要加上强制转换符,例如:int a=(int)1.9;
强制转换符只针对最近的操作数有效,往往会使用小括号来提升操作数的优先级
三、运算符
1、算术运算符
运算符 | 描述说明 | 运算符 | 描述说明 |
---|---|---|---|
± | 正负数 | + | 在数值型中,是算术加;在字符型中,是字符拼接 |
- | 减法 | * | 乘法 |
/ | 除法 | % | 取余,本质是a%b=a-a/bb,如果a为小数时,公式a-(int)a/bb |
++ | 自增 | – | 自减 |
2、关系运算符
运算符 | 描述说明 | 运算符 | 描述说明 |
---|---|---|---|
== | 判断两边是否相等 | != | 判断两边是否不相等 |
< | 判断左边是否小于右边 | > | 判断左边是否大于右边 |
<= | 判断左边是否小于等于右边 | >= | 判断左边是否大于等于右边 |
instanceof | 检查是否是类的对象 |
3、逻辑运算符
运算符 | 描述说明 | 运算符 | 描述说明 |
---|---|---|---|
& | 逻辑与,两个条件成立才返回true | | | 逻辑或,只要一个条件成立,结果返回true |
&& | 短路与,两个条件成立才返回true | || | 短路或,只要一个条件成立,结果返回true |
^ | 逻辑异或 ,a^b,当a与b不同时结果为true | ! | 取反 |
&&
与&
的区别:
a&&b
:如果a为false,第二个条件不用判断,最终结果为false,相比&效率会更高。
||
与|
的区别:
a||b
:如果a为true,第二个条件不用判断,最终结果为true,相比&效率会更高。
4、赋值运算符
运算符 | 描述说明 | 运算符 | 描述说明 |
---|---|---|---|
= | 基本赋值运算符 | += 、-= 、*= 、%= 、/= | 复合赋值运算符 ( 存在类型强制转; b+=2 相当于 b=(byte)b+2 ;a+=3 相当于 a=a+3) |
5、三元运算符
语法:
条件表达式 ? 表达式1 : 表达式2;
功能说明: 条件成立返回表达式1 ,否则返回表达式2;表达式1和表达式2要是赋给接收变量的类型(可以自动转换)
6、运算符优先级
7、位运算(与进制有关)
运算符 | 描述说明 | 运算符 | 描述说明 |
---|---|---|---|
~ | 按位取反:0变1,1变0 | & | 按位与:两位都为1,结果为1,否则为0 |
\ | 按位或:有一个为1,结果为1,否则为0 | ^ | 按位异或:两个都不同为1,相同为0 |
>> | 算术右移,低位溢出,符号位不变,并用符号位补溢出的高位 | << | 算术左移,符号位不变,低位补0 |
>>> | 无符号右移 ,低位溢出,高位补0 | 没有<<< |
int a=1>>2 // 0 1/2/2=0
int c=1<<2 // 4 4*2*2=4
四、键盘输入语句
Scanner类,简单文本扫描器
import java.util.Scanner // 引入Scanner类所在的包
Scanner myScanner=new Scanner(System.in) //创建Scanner对象
String 变量名=myScanner.next() //接收用户输入的字符串,如果用户不输入会阻塞
int变量名=myScanner.nextInt() //接收用户输入的int
double 变量名=myScanner.nextDouble() // 接收用户输入的double
五、程序控制结构
1、顺序控制
程序从上倒下逐行地执行,中间没有任何判断和跳转,
2、分支控制(if,else,switch)
(1)if else
1.单分支
if(条件表达式){
执行代码块;
}
2.多分支
if(条件表达式){
执行代码块1;
}
else{
执行代码块2;
}
3.多分支
if(条件表达式){
执行代码块1;
}
else if{
执行代码块2;
}
...
else {
执行代码块n;
}
(2)Switch
switch(表达式){ // switch关键字
case 常量1: //当表达式等于常量1执行语句1
语句1;
break; //退出switch,如果没有会顺序执行下一个case
case 常量2:
语句2;
break;
...
case 常量n:
语句n;
break;
default: //如果没有常量匹配则执行该语句,可选语句
default语句;
break;
}
1.表达式中数据类型必须是
byte
、short
、int
、char
、enum
、String
其中一种
2.表达式的数据类型必须与常量的数据类型一致,或者可以自动转成相同类型或可以比较的类型的数据,例如:输入的是字符,而常量是int
3.case
中的常量不可以是变量,但是可以是'a'+1
(3)if 和 switch 的区别
如果判断的具体值不多,而且符合byte
、short
、int
、char
、enum
、String
这些类型,建议使用switch
;如果判断的具体值多或有区间判断则建议使用if
3、循环结构(for,while,dowhile,多重循环)
(1)for循环
for(循环变量初始值;循环条件;循环变量迭代){ //for是关键字,
循环语句;
}
1.循环条件是一个布尔值的表达式
2.循环变量初始值写在循环条件区域外和循环变量迭代可以在循环操作中,分号不可省略for(;i<=10;)
3.循环变量初始值可以有多条初始化语句,但类型必须一样,而且使用逗号分隔
4.循环变量迭代可以有多条变量迭代语句,中间逗号分隔
5.死循环:for(;;;)
(2)while循环
while(循环条件){ // while先判断再执行
循环体(语句);
循环变量迭代;
}
(3)do while
do{ // 先执行再判断
循环体(语句);
循环变量迭代;
}while(循环条件); //do while 是关键字
4、break
用于终止循环,跳出循环体
{ ...
break; // 跳出当前循环
...
}
5、continue
用于结束本次循环,继续执行下一次循环,可以指定跳转的标签
{ ...
continue; // 跳出当前循环
...
}
6、return
表示跳出所在的方法,可带值作为函数的返回
{ ...
return ... ; // 跳出所在的方法
...
}
六、面向对象编程
1、修饰符
修饰符分为访问修饰符和非访问修饰符
(1)访问修饰符
用于控制方法和属性的访问权限,可以用来修饰属性,成员方法以及类
访问级别 | 访问修饰符 | 同类 | 同包 | 子类 | 不同包 |
---|---|---|---|---|---|
公开 | public | ✔ | ✔ | ✔ | ✔ |
受保护 | protected | ✔ | ✔ | ✔ | × |
默认 | 没有修饰符 | ✔ | ✔ | × | × |
私有 | private | ✔ | × | × | × |
(2)final 关键字
如果一个类没有必要再派生子类,通常可以使用final关键字来修饰,标明它是一个最终类
语法:
[访问修饰符] final class 类名
|[访问修饰符] final class 类名
|final 数据类型 变量名[ =值 ]
功能描述: 声明一个最终类或最终方法或常量,类和方法不能被改变注意:
1.最终方法不能被重写;
2.final类中的方法都是隐式的final方法,所以final类中的方法可以不声明为final方法;
3.final修饰方法不一定要存在于final类中;
4.abstract和final不能同时使用;
5.final不能用来修饰构造器;
6.final可以跟static一起修饰使常量变为类常量,不会导致类加载的情况。常量的数据类型是基本数据类型时,其值不可被修改;如果是引用数据类型时,其引用不能被修改。
常见的最终类: String、Integer、Double、Float、Boolean和Math
注意:被final修饰的引用类型是不能修改其引用地址,如果是修饰的是基本类型时,不可修改其值
(3)static 关键字
被static
修饰的属性(变量)称为静态属性或类变量,被static
修饰的方法称为静态方法或类方法.
具体请看第二章数据类型中引用数据类型的知识
(3)abstract 关键字
被abstract
修饰的类称为抽象类,被abstract
修饰的方法称为抽象方法,抽象方法没有方法体。
1. 声明抽象类或抽象方法
语法:
[访问修饰符] abstract 类名{ 方法体;} ;
|[访问修饰符] abstract 返回类型 方法名([参数列表]);
功能描述: 声明抽象类或抽象方法注意:
1.只要类中含有抽象方法则该类必须声明为抽象类
2.抽象类是不能被实例化的,他的作用是提供一个恰当的父类,因此一般作为其他类的超类,与final类正好相反。
3.如果一个类继承某个抽象父类,而没有具体实现抽象父类的抽象方法,则必须定义为抽象类。
4.抽象类中可以存在非抽象方法。
2. 实现类的抽象方法
语法:
[访问限制符] class 类名 extends 抽象类类名{[修饰符] 返回类型 抽象方法名([参数列表]){..重写抽象方法.}}
功能描述: 实现抽象类,重写抽象方法,前提必须要继承抽象类
(3)synchronized 关键字
(3)volatile 关键字
2、包package
包可以包含类、接口和子包,包是类的容器,帮我们管理大型的软件系统,本质是创建不同的文件夹来保存类文件,包能消除不同组的类直中潜在的类名冲突问题
包是java源文件中第一条执行的语句,
(1)包的声明
java是通过关键字package
来创建包的,java的类库被包含在java或javax的包中,默认情况下java类只能访问到在java.lang的类和接口
语法:
package 包名
功能描述: 声明所在类的包名
(2)包的引用
语法:
import 包名[.下一级包名].类名|*
功能描述: 引入其他包的指定类或所有类
当一个类中同时导入两个包中类名相同的类,第二个使用的类必须要 com.xiaoming.Dog 变量名= new com.xiaoming.Dog()
。
(3)常用包
包名 | 功能 |
---|---|
java.lang | java核心类库,无需显式引入 |
java.util | 工具类 |
java.io | 标准输入输出类 |
java.net | 实现网络功能 |
java.awt | GUI界面 |
java程序设计实际上是定义类的那个,一个java工程往往是由很多个类和接口组成,编程的过程就是继承基类或实现接口而创建、定义特殊子类的过程。
3、封装
含义:把属性与方法都封装在一起,并使用公共的方法来控制属性访问与修改,封装特性是通过访问修饰符来实现的。
(1)封装步骤
1.将属性私有化private
2.提供一个公共的set
方法,用于属性的判断与赋值
3.提供一个公共的get
方法,用于获取属性的值
4、继承
子类继承父类时,子类会自动拥有父类的属性与方法;父类又称超类、基类;子类又称派生类。
继承是类实现可重用性和可扩充性的关键特征,在继承关系下类之间组成网状的层次结构。
继承的好处:提高代码复用性、扩展性以及维护性
1、继承声明
语法:
[类修饰符] class 类名 extends 父类名{};
功能描述: 使创建的类继承父类的所有非私有属性和方法注意:
1.当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会调用父类的无参构造器,如果父类中没有定义无参构造器或无参构造器被覆盖,则必须在子类的构造器中使用super来指定使用父类的哪个构造器完成对父类的初始化工作,否则编译失败。
2.如果想指定去调用父类的某个构造器,则显式调用,super([参数列表])
3.super在使用时,必须放在构造器的第一行且只能在构造器中使用,this()也只能放在构造器第一行,因此这两个方法不能共存在同一个构造器
4.Java所有类都是Object的子类,Object是所有类的基类
5.父类构造器的调用不限于直接追溯父类,如果其父类找不到将一直往上追溯,直到Object类
6.子类最多只能继承一个父类(即java中是单继承机制),java不支持类的多继承,但支持接口的多继承
7.不能滥用继承,子类和父类之间必须满足is-a的逻辑关系
2、super关键字
super代表父类的引用,用于访问父类的属性、方法以及构造器
语法:
super([参数列表])
/super.方法名([参数列表])
/super.属性名
功能描述: 调用父类的构造方法或成员方法或属性
属性名: 不能访问父类的private属性
方法名: 不能访问父类的private方法注意:
1.访问父类的构造器只能放在构造器的第一行中
2.当子类中有父类中的成员(属性和方法)重名时,为了访问父类的成员,必须通过super
关键字标明,如果没有重名,使用super
、this
或直接访问可达到一样的效果cal()
/this.cal()
/super.cal()
区别点 | this | super |
---|---|---|
访问属性 | 访问本类中的属性,如本类没有此属性则从父类中继续查找 | 直接访问父类中的属性,super.父类属性名 |
调用方法 | 访问本类中的方法,如果本类没有此方法则从父类继续查找 | 直接访问父类的方法,super.父类方法名() |
调用构造器 | 调用本类构造器,必须放在构造器的首行 | 调用父类构造器,必须放在子类构造器的首行 |
特殊 | 表示当前对象 | 子类中访问父类对象 |
5、多态(ploymorphism)
(1)方法重写( override)
方法重写就是子类有一个和父类方法名和参数都完全一样,子类的返回类型和父类的返回类型一样或是父类返回类型的子类的方法,也称方法覆盖。
方法重写与方法重载的区别:
名称 | 发生范围 | 方法名 | 形参列表 | 返回类型 | 修饰符 |
---|---|---|---|---|---|
方法重载 | 本类 | 相同 | 形参类型,个数或顺序至少有一个不同 | - | - |
方法重写 | 父子类 | 相同 | 相同 | 子类重写的方法,返回的类型和父类返回的类型一致或是其子类 | 子类方法不能缩小父类方法的访问权限 |
(2)多态
多态是指在父类中定义的属性和方法被子类继承之后,可以具有不同的数据类型或表现出不同的行为
对面向对象来说,多态分为编译时多态(静多态)和运行时多态(动多态)。
Java 实现多态有 3 个必要条件:继承、重写和向上转型
静态多态: 在编译或运行前时,就可以被系统识别,也称为编译时多态,也称为静态联编或静绑定,方法重载是静态多态
动态多态: 在编译时不能被系统识别,而是在运行时才被系统识别,也称为运行时多态或动态联编或动绑定,方法重写、抽象方法和接口都是动态多态。
多态就是多种形态,多态渐离在封装和继承基础之上的,多态可以体现在方法或对象上
1. 向上转型
父类引用指向了子类的对象
语法:
父类类型 对象名=new 子类类型();
功能描述: 向上转型,自动类型转换注意:
1.实例可以调用父类中的所有成员方法或成员属性(需遵循访问权限),但不能调用子类的特有成员方法或成员属性。
2.最终结果调用方法时与子类相关联,属性从父类类型相关联
3.编译类型是赋值符号的左边,运行类型在赋值符号的右边 (编译类型=运行类型)
2. 向下转型
强制将父类引用转换成子类类型
语法:
子类类型 对象名=(子类类型) 父类引用;
功能描述: 向下转型,强制类型转换注意:
1.父类的引用必须指向目标类型,否则会报ClassCastException
2.如果调用子类的特有方法或属性时,可以向下
3. instance of
语法:
被判断对象 instance of 类型
功能描述: 用于判断对象的运行类型是否为某类型或其子类
4. 动态绑定机制
当调用对象方法时,该方法会和该对象的内存地址/运行类型绑定;当调用对象属性时,没有动态绑定机制。
public class Hello {
public static void main(String[] args) {
Father father=new firstSon();
father.hello(); // 输出:我是第一个儿子
System.out.println(father.showO()); // 101 动态绑定机制,在firstSon找不到showO方法时,根据继承机制向上查找父类方法,如果有且调用方法时会根据动态绑定机制找运行子类中是否存在方法再根据继承机制向上查找父类方法
father.ff(); // 报错
System.out.println(father.v); //报错
System.out.println(father.o); // 0
firstSon son=(firstSon) father;
System.out.println(son.showO()); //101
son.hello(); // 输出:我是第一个儿子
//secondSon son2=(secondSon) father; // 编译报错 ClassCastException
}
}
class Father{
int o=0;
public int showO(){
return getO()+1;
}
public int getO(){
return o;
}
public void hello(){
System.out.println("我是父亲");
}
}
class firstSon extends Father{
int o=100;
public int getO() {
return o;
}
public void hello(){
System.out.println("我是第一个儿子");
}
public void ff(){
System.out.println("第一个儿子特有的方法!");
}
}
class secondSon extends Father{
int v=2002;
public void hello(){
System.out.println("我是第二个儿子");
}
}
4. 多态应用
- 多态数组:定义数组时定义为父类类型,其子类作为数组元素存放在数组中
- 多态参数:方法定义的形参为父类类型,实参参数可以是子类类型
6、main方法
语法:
public static void main(String[] args){}
参数说明:
public: jvm虚拟机调用main
方法,不用public
修饰会影响main
方法的运行
static: jvm虚拟机调用main
方法无需创建对象
String: 数组参数,执行java
命令时传送进去的参数,如java 文件名 参数1 参数2
六、设计模式
1、单例模式
就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法。java类中Runtime是单例模式
单例模式有两种方式:饿汉式 和 懒汉式
1. 饿汉式单例模式
步骤如下:
1、构造器私有化
2、类的内部创建对象
3、向外暴露一个静态的公共方法。getlnstance
class Sub{
private String name;
public static int h=111;
private static Sub s=new S('ss'); // 2、类的内部创建对象,如果调用该类的类变量h时,导致类加载致使对象创建后没有使用,浪费资源
private Sub(String name){ //1、构造器私有化
this.name=name;
}
public static Sub getlnstance(){ // 3、向外暴露一个静态的公共方法
return s;
}
}
// 获取对象
// Sub instance=Sub.getlnstance ();
2. 懒汉式单例模式
class Cub {
private String name;
private static Cub c;
private Cub(String name){ //1、构造器私有化
this.name=name;
}
public static Cub getlnstance(){ // 3、向外暴露一个静态的公共方法
if(c==null){ //2、类的内部创建对象,存在线程安全位置
c=new Cub("happy");
}
return c;
}
}
七、内部类
被嵌套的类称为内部类;
按照外部类局部位置划分,分为局部内部类和匿名内部类;
按照外部类成员位置划分,可分为成员内部类和静态内部类。
(1)局部内部类
局部内部类是定义在外部类的成员方法里的类
语法:
class 外部类{ [修饰符] 返回类型 方法名([参数列表]){class 类名{成员内部类体}}}
功能描述: 定义一个局部内部类注意:
1.可以直接访问外部类的所有成员 (局部内部类可以直接访问-外部类的成员)
2.类和类中的局部变量不能添加访问修饰符,但是可以使用final 修饰。
3.作用域:仅仅在定义成员方法的代码块中。
4.外部类访问局部内部类的成员访向方式:创建对象,再访问 (注意: 必须在作用域内)
5.外部其他类不能访问局部内部类
6.如果外部类和局部内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员时,可以使用外部类名.this.成员
访问
public class HomeWork02 {
public static void main(String[] args) {
A a = new A();
a.f1();
}
}
class A{
private String NAME="正在学习JAVA";
public void f1(){
class B{
private String NAME="张三";
public void show(){
System.out.println(NAME);
System.out.println(A.this.NAME);
}
}
B b=new B();
b.show();
}
}
(2)匿名内部类
匿名内部类是定义在外部类的局部位置,没有类名的内部类
语法:
new 类名|接口名(参数列表){}
功能描述: 创建一个匿名内部类,jvm会在栈中创建一个对象,然后再创建实例并将地址返回给对象
应用: 可以当实参直接使用减少代码注意:
1.如果是要实现抽象类时,需要重写抽象方法
2.不能添加访问修饰符,因为匿名内部类是局部变量,所以外部其他类不能访问匿名内部类
3.可以直接访问外部类的所有成员
4.作用域:仅仅在定义它的方法体内
5.如果外部类和局部内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员时,可以使用外部类名.this.成员
访问
6.编译类名是外部类名$数字
public class Hello {
public static void main(String[] args) {
new TestBell().alrertBell(new Bell(){
public void ring(){
System.out.println("明天不用上班!");
}
});
}
}
interface Bell{
public abstract void ring();
}
class TestBell{
public void alrertBell(Bell bell){
bell.ring();
}
}
(3)成员内部类
成员内部类是定义在外部类的成员位置且没有static修饰
语法:
class 外部类{class 类名{成员内部类体}}
功能描述: 定义一个成员内部类注意:
1.可直接访问外部类的所有成员
2.可以添加任意访问修饰符
3.作用域:和外部类的其他成员一样
4.外部类访问成员内部类需要创建对象再访问
5.如果外部类和局部内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员时,可以使用外部类名.this.成员
访问
public class HomeWork03 {
public static void main(String[] args) {
final Car car = new Car(40.2);
car.getAir().flow();
}
}
class Car {
public double temperature;
public Car(double temperature) {
this.temperature = temperature;
}
class Air {
public void flow() {
if (temperature > 40) {
System.out.println("吹冷风");
} else if (temperature < 0) {
System.out.println("吹暖风");
} else {
System.out.println("关掉空调");
}
}
}
public Air getAir(){
return new Air();
}
}
(3)静态内部类
静态内部类是定义在外部类的成员位置且用static修饰
语法:
class 外部类{static class 类名{成员内部类体}}
功能描述: 定义一个静态内部类注意:
1.可直接访问外部类的所有静态成员
2.可以添加任意访问修饰符
3.作用域:和外部类的其他成员一样
4.外部类访问成员内部类需要创建对象再访问
八、其他类
1、Object类
Object是所有类的基类或父类,
(1)equals方法
语法:
对象.equals(另一个对象)
功能描述: 比较两个对象的引用地址是都一样equals与==的区别
==: 判断基本类型时,判断值是否相等;判断引用类型时,判断地址引用是否相同。
equals: 是Object类中的方法,只能判断引用类型,判断地址引用是否相同(子类String和Interger可以重写该方法用来判断内容是否相等)
(2)hashCode方法
语法:
对象名.hashCode();
功能描述: 返回该对象的哈希码值注意:
1.两个引用如果都是指向同一个对象,则哈希值肯定是一样的,如果不是指向同一个对象则哈希值不一样。
2.哈希值是通过将该对象的内部地址转换成一个整数来实现的
(3)toString方法
语法:
对象名.toString()
功能描述: 返回对象字符串表示注意:
1.默认返回全类名+@+哈希值的十六进制 (全类名=包名+类名)getClass().getName()+"@"+Integer.toHexString(hashCode())
2.往往重写toString方法,一般输出对象的属性
3.当直接处处对象时,toString会被默认调用
(4)finalize方法
功能描述: 当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法
注意:
1.当对象被回收时,系统自动调用该对象的finalize方法,子类可以重写该方法,做一些西方资源的操作。
2.当某个对象没有任何引用时,jvm会使用垃圾回收机制来销毁该对象,在销毁该对象前,会调用finalize方法
3.垃圾回收机制的调用,是由系统来决定,也可以通过System.gc()主动触发垃圾回收机制
4.重写finalize方法,可以写释放资源的逻辑代码(断开数据库连接)
2、String类
String对象用于保存字符串,字符串的字符使用Unicode字符编码,一个字符占两个字节,字符串常量是由双引号括起来的。
String因为实现了Serializable接口,所以可以在网络上传播;因为实现了Comparable接口致使可以比较大小。
String类是final修饰,所以无法被其他类继承
(1)创建String对象
- 直接赋值
语法:
String 对象名="value";
功能描述: 将字符串常量直接赋值给String对象
- 调用构造器
语法:
String 对象名=new String("value");
功能描述: 调用构造器构造一个String对象
- 两种方式的内存分布
方式一: 先从常量池查看是否有”hsp”数据空间,如果有,直接指向;如果没有则重新创建,然后指向。s最终指向的是常量池的空间地址
方式二: 先在堆中创建空间,里面维护了value属性,指向常量池的hsp空间如果常量池没有"hsp",重新创建,如果有,直接通过value指向。最终指向的是堆中的空间地址。
String对象.intern()返回常量池的地址
(2)String常用方法
字符串处理:Java字符串处理
==和equals:
==是判断两个字符串对象是否是同一实例,即它们在内存中的存储空间是否相同
equals是重写了Object的equals中,只需判断两个值是否相等即不考虑是否是同一个实例,
(3)StringBuffer类
StringBuffer类是String类的增强类,其父类是AbstractStringBuilder类,相比String类而言,其可以直接修改字符串的值而不是修改其地址,提高效率。
StringBuffer的值存放在堆中,String类的值存放在常量池中。
1.StringBuffer的构造器
StringBuffer():构造一个其中不带字符的字符串缓冲区,其初始容量为16字符
StringBuffer(int N):构造一个不带字符,但具有指定初始容量的字符串缓冲区,即对char[]大小进行指定
StringBuffer(String str):构造一个字符串缓冲区,并将其内容初始化为指定的字符串内容
2.StringBuffer类常用方法
1)获取长度
语法:
StringBuffer对象名.length()
功能描述: 返回StringBuffer对象的长度
2)增
语法:
StringBuffer对象名.append(Object)
功能描述: 向StringBuffer对象添加Object对象,改变原对象
其他情况:
append(AbstractStringBuilder)
append(String)
append(float)
append(int)
append(char)
append(long)
append(StringBuffer)
append(char[], int, int)
append(double)
append(boolean)
append(char[])
append(CharSequence)
append(CharSequence, int, int)
注意: 底层调用AbstractStringBuilder的appendNull
3)删
语法:
StringBuffer对象名.delete(int startIndex,int endIndex)
功能描述: 根据传入的参数删除StringBuffer对象指定位置的字符
4)改
语法:
StringBuffer对象名.replace(int,int,String)
功能描述: 修改指定位置的字符
5)查
语法:
StringBuffer对象名.indexOf(String,int)
|StringBuffer对象名.insert(String)
功能描述: 查找第一次出现指定字符并返回位置,找不到返回-1
6)插
语法:
StringBuffer对象名.insert(int, Object)
功能描述: 向指定位置中插入指定字符或对象
其他情况:
insert(int, boolean)
insert(int, char)
insert(int, String)
insert(int, CharSequence)
insert(int, CharSequence, int, int)
insert(int, float)
insert(int, long)
insert(int, char[], int, int)
insert(int, char[])
insert(int, int)
insert(int, double)
7)转成String
语法:
StringBuffer对象名.toString()
功能描述: 将StringBuffer对象的数据转换成String类型
// 反转指定位置的字符串
public class HomeWork05 {
public static void main(String[] args) {
String s="abcdef";
String s1=Rever.reverse(s,1,4);
System.out.println(s1);
}
}
class Rever{
public static String reverse(String str,int start,int end){
if (!(str!=null&& start>=0&&end<=str.length())) {
throw new RuntimeException("参数不正确");
}
String[] arr=str.split("");
for (int i = 0; i < arr.length; i++) {
if(i==start){
String temp=arr[i];
arr[i]=arr[end];
arr[end]=temp;
start+=1;
end-=1;
if (start==end || start>=arr.length/2){
break;
}
}
}
StringBuffer newStr = new StringBuffer();
for(int i = 0; i < arr.length; i++){
newStr.append(arr[i]);
}
return newStr.toString();
}
}
(4)StringBuilder类
StringBuilder类实现了 Serializable接口即可以串行化(对象可以网络传输,可以保存到文件)且是final类不能被继承;
StringBuffer 对象字符序列仍然是存放在其父类 AbstractstringBuilder的 char[] valve,所以其值存放在堆中。
因为类中方法没有synchronized 关键字,因此在单线程的情况下使用。
在StringBuilder上的主要操作是append禾insert方法,可重载这些方法来接受任意类型的数据。
(5)String、StringBuffer和StringBuilder三者的区别
String: 不可变字符序列,效率低,但是复用率高。
StringBuffer: 可变字符序列、效率较高(增删)、线程安全
StringBuilder: 可変字符序列、效率最高、只能在单线程中使用线程不安全
- 如果字符串很少修改但存在被多个对象引用建议使用
String
。 - 如果需要进行大量的修改操作一般建议使用
StringBuffer
或StringBuilder
。
进行大量修改操作且在单线程的情况下,建议使用StringBuilder
;进行大量修改操作且在多线程的情况下,建议使用StringBuffer
3、Math类
Math类包含用于执行基本数学运算的方法
方法语法 | 功能描述 | 示例 |
---|---|---|
Math.abs(int|double|float|long) | 返回绝对值 | Math.abs(-10.64) |
Math.pow(double,double) | 返回幂的结果 | Math.pow(-2,4) |
Math.ceil(double) | 向上取整 | Math.ceil(-4.7) |
Math.floor(double) | 向下取整 | Math.floor(74.3) |
Math.round(double|float) | 四舍五入 | Math.round(4.14542) |
Math.sqrt(double) | 求开方 | Math.sqrt(9.0) |
Math.random() | 返回[0,1]之间的随机小数 | Math.random() |
4、Arrays类
Arrays 类是一个工具类,里面包含很多管理和处理数组的方法。
方法语法 | 功能描述 |
---|---|
Arrays.toString(数组对象) | 返回数组的字符串格式 |
Arrays.sort(数组对象) | 默认升序排序,返回一个空值 |
Arrays.sort(数组对象,Comparator接口匿名内部类) | 自定义排序,返回一个空值 |
Arrays.binarySearch(数组对象,value) | Arrays.binarySearch(数组对象,startIndex, endIndex,value) | 二分查找,(只针对有序数组) |
Arrays.copyOf(数组对象,长度) | 返回一个新的复制后的数组 |
Arrays.equals(数组对象1,数组对象2) | 比较两组数组是否一样,一样返回true |
Arrays.fill(数组对象,value) | 将value填充至数组对象每个元素里 |
自定义排序的案例:
import java.util.Arrays;
import java.util.Comparator;
public class TestWrapper {
public static void main(String[] args) {
int [] arr={1,5,152,62,6,9,24,67,2,3};
A1.ArrMethod(arr,new Comparator(){
@Override
public int compare(Object a,Object b) {
return (Integer)a-(Integer)b;
}
});
System.out.print(Arrays.toString(a));
}
}
class A1{
public static void ArrMethod(int[] arr,Comparator c ){
int temp=arr[0];
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length-i-1; j++) {
if(c.compare(arr[j],arr[j+1])>0){
temp=arr[j+1];
arr[j+1]=arr[j];
arr[j]=temp;
}
}
}
}
}
5、System类
方法语法 | 功能描述 |
---|---|
System.exit(0) | 退出当前程序,0代表正常状态 |
System.arraycopy(src,srcPod,dest,destPod,length ) | 拷贝数组,是Arrays.copyOf()的底层实现 |
System.currentTimeMillis() | 返回当前时间戳 |
6、BigInteger和BigDecimal类
BigInteger适合存放比较大的整型数据,BigDecimal适合存放精确度更大的浮点数,BigInteger和BigDecimal不是静态类,所以使用时需要使用构造函数创建对象才能使用 new BigInteger(String);
方法语法 | 功能描述 |
---|---|
BigInteger对象1.add(BigInteger对象2) | 两数相加 |
BigInteger对象1.subtract(BigInteger对象2) | 两数相减 |
BigInteger对象1.multiply(BigInteger对象2) | 两数相乘 |
BigInteger对象1.divide(BigInteger对象2) |BigInteger对象1.divide(BigInteger对象2,BigDecimal.ROUND_CEILING) |
除法时,如果除不尽会抛出ArithmeticException异常,可再传入一个BigDecimal.ROUND_CEILING参数进去使无限循环的结果保留分子的精度
7、日期类
日期格式字符表示:
字符标志 | 含义 | 字符标志 | 含义 |
---|---|---|---|
y | 年 | M | 月份 |
w | 年中周数 | W | 月中周数 |
D | 年中天数 | d | 月中天数 |
F | 月份中的星期 | E | 星期的天数 |
H | 一天中的0-23小时 | k | 一天中的1-24小时 |
h | am/pm的小时数 1-12 | m | 小时里的分钟数 |
s | 分钟里的秒数 | S | 毫秒数 |
(1)Date类
获取当前时间:
Date 变量名=new Date();
指定毫秒数:Date 变量名=new Date(long);
格式化时间:
第一种方式:String转换成指定格式
Date 格式化后的变量名=new SimpleDateFormat(格式的字符串形式).parse(String);
第二种方式:Date转换成指定格式
String 格式化后的变量名=new SimpleDateFormat(格式的字符串形式).format(Date变量名);
(2)Calendar类
Calendar类再jdk1.1之后引入弃用了Date类,Calendar类是抽象类并且构造器是使用private关键字修饰的,可通过getInstance()获取实例
获取实例:
Calendar 实例变量名=Calendar.getInstance();
获取年份:实例变量名.get(Calendar.YEAR);
获取月份:实例变量名.get(Calendar.MONTH);
获取日:实例变量名.get(Calendar.DAY_OF_MONTH);
获取小时:实例变量名.get(Calendar.HOUR);
获取分钟:实例变量名.get(Calendar.MINUTE);
获取秒:实例变量名.get(Calendar.SECOND);
注意:没有格式化的方法
(3)日期类
LocalDate可以获取日期,LocalTime可以获取时间,LocalDateTime可以获取日期时间,DateTimeFormatter可以格式化日期,使用方法请参考下方案例。
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
/**
* @author just表面兄弟
* @version 1.0
*/
public class Test {
public static void main(String[] args) {
LocalDateTime localDateTime =LocalDateTime.now();
System.out.println("获取年份:"+localDateTime.getYear());
System.out.println("获取月份:"+localDateTime.getMonth());
System.out.println("获取日:"+localDateTime.getDayOfMonth()); // localDateTime.getMonthValue()
System.out.println("获取小时:"+localDateTime.getHour());
System.out.println("获取分钟:"+localDateTime.getMinute());
System.out.println("获取秒:"+localDateTime.getSecond());
System.out.println("获取日期:"+ LocalDate.now());
System.out.println("获取时间:"+ LocalTime.now());
DateTimeFormatter dateTimeFormatter=DateTimeFormatter.ofPattern("yyyy年 MM月 dd日 hh:mm:ss");
String dateTime=dateTimeFormatter.format(localDateTime);
System.out.println(dateTime);
}
}
附录
Java 常用转义字符
转义字符 | 描述说明 | 转义字符 | 描述说明 |
---|---|---|---|
\t | 制表符 | \\ | | |
\n 换行符 | \” | “ | |
\’ | ‘ | \r | 回车 |
Java内存结构分析
栈:一般存放基本数据类型(局部变量)
堆:存放对象(类对象,数组等)
方法区:常量池(常量和字符串),类加载信息(只会加载一起)
java内存管理
内存管理通常有两种方法:
1.由程序员在编写程序时显式地释放内存(如c++)
2.由语言的运行机制自动完成,(如java)
java内存释放
java虚拟机后台线程负责内存的回收;可人为执行强制回收机制,java提供了一个System.gc()
方法来立即回收垃圾
java自动回收垃圾
通过判断该存储单元所对应的对象是否仍被程序所用可决定该存储单元是否是垃圾;同理所得通过判断对象是否由引用指向该对象判断程序是否正在被使用。
java垃圾收集器一般自动扫描对象的堆,对所用的对象加标记,没有引用的对象则释放出来。
java强制回收
???????????????
进制
对于整数,有四种表示方式
1.二进制:0,1 满2进1,以0b或0B开头
2.十进制:0-9 满10进1
3.八进制:0-7 满8进1,以0开头
4.十六进制:0-9,a(10)-f(15) 满16进1,以0x或0X开头表示 a-f不区分大小写
二进制转换成十进制:
从最低位开始,将每个位上的数提取出来,乘以2的(位数-1)次方,然后求和。
八进制转换成十进制:
从最低位开始,将每个位上的数提取出来,乘以8的(位数-1)次方,然后求和。
十六进制转换成十进制:
从最低位开始,将每个位上的数提取出来,乘以16的(位数-1)次方,然后求和。
十进制转换成二进制:
将该数不断除以2,直到商为0为止,然后每步得到的余数倒过来就是结果。(参照短除法)
十进制转换成八进制:
将该数不断除以8,直到商为0为止,然后每步得到的余数倒过来就是结果。
十进制转换成十六进制:
将该数不断除以16,直到商为0为止,然后每步得到的余数倒过来就是结果。
二进制转换成八进制:
从最低位开始,将二进制每3位一组,转成对应的八进制即可
0b11(3)010(2)101(5)=====>0325
二进制转换成十六进制:
从最低位开始,将二进制每4位一组,转成对应的十六进制即可
0b1101(13)0101(5)=====>0xd5
八进制转换成二进制:
将八进制数每一位转成对应的3位二进制数
十六进制---->二进制:将八进制数每一位转成对应的4位二进制数
编码
ascii 是每个字符只占用1个字节,128个字符;
Unicode,由ascii 扩展,每个字符只占用2个字节,可存储中文;
utf-8字母占用1个字节,汉字占用3个字节;
gbk字母占用1个字节,汉字占用2个字节;
原码、补码和反码
1.二进制的最高位代表符号位,0为正数,1为负数
2.正数的原码,补码和反码都一阿姨那个
3.负数的反码=原码符号位不变+其他位取反
4.负数的补码=它的反码+1,负数的反码=负数的补码-1
5.0为反码,补码都是0
6.Java的数都是有符号的
7.计算机运算时都是以补码来运算