Java笔记
一
标识符由数字,字母,下划线,及¥组成
注意:数字不能成为标识符的开始,如:1ac
关键字:具有特殊含义的标识符,如:int,void,main,string
用户自定义标识符:是由用户按标识符构成规则生成的非保留字的标识符,如:abc,name
命名规则:Java类的命名规则:类名首字母大写,如果有多个单词组合,则每个单词大写(大驼峰命名法):例如,HelloWorld
小驼峰命名法:首个单词字母小写,后面的单词首字母大写
例如:helloWorld
二
注意:Java严格区分大小写,如;name和Name表达的意思不一样
//单行注释
/*
多行注释
/
/
文档注释
/
//int name
Java严格区分大小写,是强类型。
三,声明
变量:用来存放东西的
变量命名:
语法:变量类型 变量名字 赋值符号 值;
int age ;//声明变量,不赋值
age = 32;//声明后赋值
Srting name = “大锤”; //声明变量,赋值
//修改变量值(重新赋值)
age = 56;
name = “张三”;
int 2num;//非法命名
n1 = 2;
n2 = 3;
n3 = 4;
int n1,n2,n3;//批量命名(不推荐)
n1 = n2 = n3 =58;
int num1 = 3,num2 = 4;
四
变量的作用域:
全局变量:定义在方法(函数)和代码块之外的变量
局部变量:定义在方法或者代码块之间的变量
静态变量
static int number;
五,常量
常量:在某个程序中不改变值的量
常量值又称为字面常量,通过数据直接表示的,因此有多种数据类型。
整型int占4个字节,32位,大于32,用long长整型,占64位。后面加l或L。
常量一旦被赋值定义,则不可再被修改
成员常量
final double PI = 3.14
静态变量
final static float price = 99.99F;
成员常量和静态常量在再定义的同时必须要初始化
常量命名规则
1,常量名应该全部大写
2,当常量命名由多个单词组成,用下划线分割
如HTTP_CODE
java中的数据类型
1,基本数据类型(8)种
byte(字节型)、short(短整型)、int(整型)、long(长整型)、
float(单精度浮点型)、double(双精度浮点型)(后加F或者f)、Java小数默认double
char(字符型),字符型使用单引号引起来,当值为整型时,不需要单引号
boolean(布尔型)Java中,布尔型只有ture和false两种。
2,引用数据类型
除了基本数据类型,其他都是引用数据类型。如String、数组等
null类型:空类型
package com.zpark.day02;
/ * @PackageName: com.zpark.day02 * @ClassName: dEMO02 * @Description: * @author: RZS * @date: 2022/8/26 11:01 / public class Demo02 {
static String name;
public static void main(String[] args) { /* * Java中的数据类型: * 1、基本数据类型(八种) * byte(字节型)、short(短整型)、int(整形)、long(长整型)、float(单精度浮点型)、double(双精度浮点型) * char(字符型)、boolean(布尔型) * 2、引用数据类型 * 除了基本数据类型,其他全部是引用数类型,如:String、数组等 */ // 字节型 byte by = 127; // System.out.println((byte) (by + 1)); // 短整型 short sh = 56; // 整形 int num = 78946; // 长整型,注意: 需要早长整型末尾添加L或者l long number = 56L;
// 单精度浮点型, 注意: 需要早长整型末尾添加F或者f float fl = 3.14F; float fl1 = 3.1415888888879874243246564564561129f; // 精度丢失 System.out.println(fl1);
// 双精度浮点型,java中小数默认是double类型 double db = 3.14159;
// 字符型, 字符型的值使用单引号引起来,当值为整形时不需要单引号 char ch1 = 3; char ch2 = ‘a’; char ch3 = 97; System.out.println(ch1); System.out.println(ch3);
// 布尔值类型,注意:Java中布尔值类型只有true和false两个值 boolean bool1 = true; boolean bool2 = false;
// null类型 String str = null;
System.out.println(name); // int a = null; 报错 } }
关系运算符:
==:对等于
!=:不等于
>:大于
<:小于
>=:大于等于
<=:小于等于
关系运算符的结果为布尔值类型
equals(obj)方法和 == 的区别:
equals方法比较的是两个对象的内容是否相等
== 比较的是两个对象再内存中存放的地址是否为同一个
next()与nextLine()方法的区别:
1、当遇到空格或者回车的时候 next()方法停止读取
2、当遇到回车的时候 nextLine()方法停止读取,读取整行数据
单分支结构:
if () {
}
双分支结构
if语句:
if (条件表达式) {
条件为true执行
代码块
} else {
条件为false执行
}
if嵌套
* if(boolean){
* if(boolean){
* …
* }
* }else{
* if(boolean){
……
}
while循环:
语法:
while (循环条件) {
循环体
}
do.while循环
语法:
do{
循环体
} while (循环条件);
while循环与do…while循环的区别:
1、while是先判断后执行,do…while循环是先执行然后再判断
2、do…while循环至少执行一次
3、while循环与do…while的特点:都是循环执行某一语句,循环次数素不固定
for循环:
语法:
for (表达式1; 表达式2; 表达式3) {
循环体
}
特点:循环次数固定
foreach语法:
for(迭代变量类型 变量的名字 :需要遍历(迭代)的对象){
语句块;
}
定义方法的语法:
修饰符 返回值类型 方法名(参数1,参数2…) { 方法体… }
return关键字的作用:1、结束方法的执行。2、将方法的执行结果返回给调用者
方法(函数)的类型:
1、无参无返回值
修饰符 void 方法名(){ 方法体 }
2、无参有返回值
修饰符 返回值类型 方法名(){ 方法体}
3、有参无返回值
修饰符 void 方法名(参数1, 参数2,…){ 方法体}
4、有参有返回值
修饰符 返回值类型 方法名(参数1, 参数2,…){ 方法体}
比较两个数的大小,将大的值返回回去
@param num1
@param num2
@return 返回最大值
定义方法:
比较两个数大小,返回布尔值
方法调用
1、通过 对象.方法名字(参数)
2、类名.方法(参数)
3、方法(参数)
调用非static关键字修饰的方法,语法:对象.方法(参数)
调用被static修饰的方法,语法:类名.方法(参数)
方法重载:
重载就是在一个类中,有相同的函数名称,但参数列表不相同的方法。
注意:
方法重载只与方法名字和参数列表有关,与方法返回值类型无关
方法签名:方法名字 + 参数列表
什么是程序?
答:程序 = 算法 + 数据结构
修饰符:修饰符,这是可选的,告诉编译器如何调用该方法。定义了该方法的访问类型。
返回值类型 :方法可能会返回值。returnValueType 是方法返回值的数据类型。有些方法执行所需的操作,但没有返回值。在这种情况下,returnValueType 是关键字void。
方法名:是方法的实际名称。方法名和参数表共同构成方法签名。
参数类型:参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。
方法体:方法体包含具体的语句,定义该方法的功能。
方法的作用及特点:
1、封装一段特定的业务逻辑功能
2、尽可能独立,一个方法只干一件事
3、方法可以被反复多次的调用
4、减少代码的重复,有利于代码的维护,有利于团队的协作
数组定义:
用来存放相同类型的一组数据
数组下标从0开始,对数组元素进行操作是通过数组的下标(索引)
数组一旦被创建,则数组的长度不可被修改
语法:
静态创建数组
数据类型[] 数组名 = {值1,值2…}
数据类型 数组名[] = {值1,值2…}
动态创建数组
数据类型[] 数组名 = new 数据类型[数组长度]
数据类型 数组名[] = new 数据类型[数组长度]
静态创建数组,特点:创建数组的同时给数组元素赋值
动态创建数组,特点创建数组时指定数组的长度
数组元素必须是相同类型的,不允许出现混合类型。
数组元素赋值:语法,数组名[索引] = 值
数组的长度获取方式,array.length
初始值
int 初始值为0
double初始值为0.0
boolea初始值为false
char的初始值为空格的编码
string的初始值null
data的初始值为null
Demo初始值为null
引用数据类型数组初始值为null
二维数组
两种初始化形式:**
格式1、动态初始化**
数据类型 数组名[][] = new 数据类型[m][n]
数据类型[][] 数组名 = new 数据类型[m][n]
数据类型[] 数组名[] = new 数据类型[m][n]
格式2、 静态初始化**
数据类型[][] 数组名 = {{元素1,元素2…},{元素1,元素2…},{元素1,元素2…}…};
Arrays类
Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用,而“不用”使用对象类调用(注意是“不用”,而不是“不能”)。
Arrays类具有以下常用的功能:
**给数组赋值:通过调用fill方法。
对数组进行排序:通过sort方法。
比较数组:**通过equals方法比较数组中元素的值是否相等。
**查找数组元素:**通过binarySearch方法能对排序好的数组进行二分查找法操作。
**将数组转为字符串输出:通过toString方法实现。
浅拷贝:这个是系统提供的拷贝方式,也是我们推荐使用的拷贝方式,它是浅拷贝,也就是说对于非基本类型而言,它拷贝的是对象的引用,而不是去新建一个新的对象。通过它的代码我们可以看到,这个方法不是用java语言写的,而是底层用c或者c++实现的,因而速度会比较快
数组扩容与缩容
数组扩容与缩容的实质:就是创建一个新的数组,新数组的长度比原来的数组(大,扩容,小,缩容),然后将原来数组中的内容全部拷贝到新的数组中,最后将新数组重新赋给原来的数组。
稀疏数组
稀疏数组介绍:
当一个数组中大部分元素为0时,或者为同一值的数组时,可以使用稀疏数组来保存该数组。
稀疏数组的处理方式是:
1、 记录数组一共有几行几列,有多少个不同的值。
2、 把具体有不同值的元素和行列及值记录在一个小规模的数组中,从而缩小程序的规模。
稀疏数组定义:
稀疏数组可以看做是普通数组的压缩,但是这里说的普通数组是值无效数据量远大于有效数据量的数组。
冒泡排序
冒泡排序是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。
package com.zpark.day10;
import java.util.Arrays;
public class Demo05 {
public static void main(String[] args) {
/
* 冒泡排序
*/
int[] arr = {112, 56, 89, 789, 45, 2, 0};
for (int i = 0; i < arr.length - 1; i++) {
for(int j = 0; j < arr.length - 1 - i; j++) {
if(arr[j] > arr[j+1]) { // 相邻元素两两对比
int temp = arr[j+1]; // 元素交换
arr[j+1] = arr[j];
arr[j] = temp;
}
}
}
System.out.println(Arrays.toString(arr));
}
}
面向对象
包机制的作用:
为了更好的组织类,Java提供了包机制,用于区分类的命名空间,包语句的语法格式为:
package 包名1.包名2.……
一般利用公司的域名倒置作为包名。
为了能够使用包的成员,我们需要在Java程序中明确导入所使用的包,使用规则为通过import关键字:
import 完整的包名.类名;
注:
package语句必须位于Java源文件中的第一行,否则编译不通过。
面向过程与面向对象:
面向过程思想:
1、 步骤清晰简单,第一步要做什么,第二步要做什么……
2、 面向过程适合处理一些较为简单的问题
面向对象思想:
1、 物以类聚,分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考,最后,才对某个分类 下的细节进行面向过程的思索。
2、 面向对象适合处理复杂的问题,适合处理需要多人协作的问题
面向过程的结构化程序设计:
结构化程序设计的弊端:
1、缺乏对数据的封装
2、数据与方法(操作数据)的分离
什么是面向对象:
面向对象的本质就是:以类的方式组织代码,以对象的组织(封装)数据。
什么是抽象的数据类型:
所谓抽象数据类型可以理解为:将不同类型的数据的集合组成一个整体,用来描述一种新的事务。如:对象类型数据
什么是类?什么是对象?
1、现实世界是由很多很多对象组成的
基于对象抽出了类
2、对象:真实存在的单个的个体
类:类型/类别,代表一类个体
3、类中可以包含:
3.1、所有对象所共有的属性/特征------------成员变量
3.2、所有对象所共有的行为-----------------方法
4、一个类可以创建多个对象
同一类型所创建的对象,结构相同,数据不同
5、类是对象的模板,对象是类的具体的实例
面向对象的三大特征:
封装、继承、多态
类与对象创建
定义一个类:
定义类的成员变量:
1、类的定义包括“成员变量”的定义和“方法”的定义,其中“成员变量”用于描述对象 共同的数据结构,“方法”则是所有对象共同的 行为。
2、Java语言中,类的成员变量的定义可以使用如下的语法:
修饰符 class 类名 {
成员变量类型 变量名;
………
}
构造器/构造方法
构造方法语法结构:
构造方法是在类中定义的方法,不同于其他的方法,构造方法的定义有如下两点规则:
1)构造方法的名称必须与类名完全相同。
2)构造方法没有返回值,连void关键字有没有
默认构造器
1)任何一个类都必须含有构造方法。
2)如果源程序中没有定义构造方法,编译器在编译时会为其添加一个无参的构造方法(称为默认无参构造器)。
3)当定义了构造方法之后,Java编译器不再添加默认的无参构造器。
重载
一个构造方法可以通过this关键字调用另外一个重载的构造方法。
通过构造方法初始化成员变量:
构造方法常用于实例化对象和对成员变量进行初始化。
this关键字的使用:
this关键字用在方法体中,用于指向调用该方法的当前对象,简单来说,那个对象调用方法,this就指的是那个对象,严格来讲在方法中需要通过this关键字指明当前对象。
注意:在构造方法中,用来初始化成员变量的参数一般和成员变量取的名字相同,这样会有利于代码的可读性,但下列这种情况如果将this省略,就不能区分成员变量和参数了,所以必须加上this关键字
Java内存分析
堆、栈、方法区:
堆: new出来的对象(包括实例变量)
栈: 局部变量(包括方法的参数)
方法区: .class字节码文件(包括方法、静态变量)
内存区域类型
1.寄存器:最快的存储区, 由编译器根据需求进行分配,我们在程序中无法控制;
2. 堆:存放所有new出来的对象;
3. 栈:存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量池中(对象可能在常量池里)(字符串常量对象存放在常量池中。);
4. 静态域:存放静态成员(static定义的);
5. 常量池:存放字符串常量和基本类型常量(public static final)。有时,在嵌入式系统中,常量本身会和其他部分分割离开(由于版权等其他原因),所以在这种情况下,可以选择将其放在ROM中 ;
6. 非RAM存储:硬盘等永久存储空间
对于string的特殊解释
1、对于字符串:其对象的引用都是存储在栈中的,如果是编译期已经创建好(直接用双引号定义的)的就存储在常量池中,如果是运行期(new出来的)才能确定的就存储在堆中。对于equals相等的字符串,在常量池中永远只有一份,在堆中有多份。
特别注意:对于通过new产生一个字符串(假设为”china”)时,会先去常量池中查找是否已经有了”china”对象,如果没有则在常量池中创建一个此字符串对象,然后堆中再创建一个常量池中此”china”对象的拷贝对象。
对于成员变量和局部变量:成员变量就是方法外部,类的内部定义的变量;局部变量就是方法或语句块内部定义的变量。局部变量必须初始化。
常量池理解
1、必须要关注编译期的行为,才能更好的理解常量池。
2、运行时常量池中的常量,基本来源于各个class文件中的常量池。
3、程序运行时,除非手动向常量池中添加常量(比如调用intern方法),否则jvm不会自动添加常量到常量池。
内存总结
1.内存管理:由JVM来管理的
- 堆:
1.1) 存储new出来的对象(包括实例变量)
1.2) 垃圾: 没有任何引用所指向的对象
垃圾回收器(GC)不定时到内存中清理垃圾,
回收过程是透明的(看不到的),不一定一发现垃圾就立刻回收,
调用System.gc()可以建议虚拟机尽快调度GC来回收
1.3) 内存泄漏: 不再使用的内存没有被及时的回收
建议: 对象不再使用时及时将引用设置为null
1.4) 实例变量的生命周期:
在创建对象时存储在堆中,对象被回收时一并被回收 - 栈:
2.1) 存储正在调用的方法中的所有局部变量(包括方法的参数)
2.2) 调用方法时,会在栈中为该方法分配一块对应的栈帧,
栈帧中存储方法中的局部变量(包括参数),
方法调用结束时,栈帧被清除,局部变量一并被清除
2.3) 局部变量的生命周期:
方法被调用时存储在栈中,方法结束时与栈帧一并被清除 - 方法区:
3.1) 存储.class字节码文件(包括静态变量、方法)
3.2) 方法只有一份,通过this来区分具体的调用对象
对象数组
数组是对象:
1、在Java中,数组属于引用数据类型。
2、数组对象存储在堆中,数组变量属于引用类型,存储数组对象的地址信息,指向数组对象。
3、数组的元素可以看成数组对象的成员变量(只不过类型全部相同)
引用类型数组的声明:
数组的元素可以是任意类型,当然也包括引用类型。
引用类型数组的初始化:
1)引用类型数组的默认初始值但是null。
2)如果希望每一个元素都指向具体的对象,需要针对每一个数组元素进行new运算。
访问控制修饰符
1、public和private
private修饰的成员变量和方法仅仅只能在本类中访问调用。
public修饰的成员变量和方法可以在任何地方调用,public修饰的内容是对外提供可以被调用的功能,需要相对稳定,private修饰的内容是对类实现的封装,如果“公开”会增加维护的成本。
2、 protected和默认访问控制
1)用protected修饰的成员变量和方法可以被子类及同一个包中的类使用。
2)默认的访问控制即不书写任何访问修饰符,默认访问控制的成员变量和方法可以被同一个包中的类调用。
3、访问控制修饰类
1)对于类的修饰可以使用public和默认的方式,public修饰的类可以被任意一个类使用,默认方法控制的类只能被同包中的类使用。
2)protected和private可以用于修饰内部类
封装
封装,简单的说就是该露的露,该藏的藏。我们在设计程序是要追求“高内聚,低耦合”,其中,高内聚指的是类的内部数据操作细节由自己完成,不允许外部干涉。低耦合指的是仅暴露少量的方法给外部调用(使用get/set方法)。
封装(对数据的隐藏),通常来说,应禁止直接访问应该对象中数据的实际表示,而是应该通过操作接口来访问,这种称为信息隐藏。
封装的意义:
1、对外提供可调用的,稳定的功能。
2、封装容易变化的,具体的细节,外界不可访问,这样封装的意义在于:
a. 降低代码出错的可能性,便于维护。
b. 当内部的实现细节改变时,只要保证对外的功能定义不变,其他的模块就不会因此而受到牵连。
封装的核心:属性私有化,行为(方法)公开化
继承
extends关键字
1、通过extends关键字可以实现类的继承。
2、子类可以继承父类的成员变量及成员方法,同时也可以定义自己的成员变量和成员方法。
3、Java语言不支持多重继承,一个类只能继承一个父类,但是一个父类可以有多个子类。
继承中的构造方法
1、子类的构造方法中必须通过super关键字调用父类的构造方法,这样可以妥善的初始化继承自父类的成员变量。
2、如果子类的构造方法中没有调用父类的构造方法,Java编译器会自动的加入对父类的无参构造方法的调用(如果父类没有无参构造方法,则会有编译错误)。
父类的引用指向子类的对象
1、一个子类的对象可以向上造型为父类的类型,即,定义父类型的引用可以指向子类型的对象。
2、 父类的引用可以指向子类的对象,但是通过父类的引用只能访问父类所定义的成员,不能访问子类扩展的部分。
super关键字
在java里面,对于super关键字通常有两种用法:
- 用在子类的构造方法里(初始化用),主要是调用父类的默认构造方法,如果父类有不止一个构造方法,可以通过super指定具体的构造函数,比如 super(paras)。
- 用在子类里调用隐藏或重写的属性或行为,比如 super.onDestroy()等等。
对于第1种需要注意,super表示当前类的父类对象,super()调用的是父类默认的构造方法,即这样可以对父类进行初始化。如果没有对父类进行初始化,当子类调用父类的方法时,便会从逻辑上出现错误,因为没对父类初始化,父类的方法和属性便没有内存空间。
关于super 与 this 关键字的对比(区别): - super(参数):调用基类中的某一个构造函数(应该位于子类构造函数中的第一条语句)。
- this(参数):调用本类中的构造函数(应该位于构造函数中的第一条语句)。
- super: 它引用当前对象的直接父类中的成员(用来访问直接父类中被隐藏的父类中成员数据或函数,基类与派生类中有相同成员定义时如:super.变量名 super.成员函数据名(实参)。
- this:它代表当前对象名(在程序中易产生二义性之处,应使用this来指明当前对象;如果函数的形参与类中的成员数据同名,这时需用this来指明成员变量名)
5、调用super()必须写在子类构造方法的第一行,否则编译不通过。每个子类构造方法的第一条语句,都是隐含地调用super(),如果父类没有这种形式的构造函数,那么在编译的时候就会报错。
6、super()和this()类似,区别是,super()从子类中调用父类的构造方法,this()在同一类内调用其它构造方法。
7、super()和this()均需放在构造方法内第一行。
8、尽管可以用this调用一个构造器,但却不能调用两个。
9、this和super不能同时出现在一个构造函数里面,因为this必然会调用其它的构造函数,其它的构造函数必然也会有super语句的存在,所以在同一个构造函数里面有相同的语句,就失去了语句的意义,编译器也不会通过。
10、 this()和super()都指的是对象,所以,均不可以在static环境中使用。包括:static变量,static方法,static语句块。
11、 从本质上讲,this是一个指向本对象的指针, 然而super是一个Java关键字。
方法重写
方法的重写(Override):
1、发生在父子类中,方法名称相同,参数列表相同,方法体不同
2、重写方法被调用时,看对象的类型
3、遵循"两同两小一大"原则:------------了解
3.1、两同:
3.1.1、方法名称相同
3.1.2、参数列表相同
3.2、两小:
3.2.1、派生类方法的返回值类型小于或等于超类方法的
a、void时,必须相同
b、基本数据类型时,必须相同
c、引用数据类型时,小于或等于
3.2.2、派生类方法抛出的异常小于或等于超类方法的
3.3、一大:
3.3.1、派生类方法的访问权限大于或等于超类方法的
重写与重载的区别:
1、重写(Override):
1.1、发生在父子类中,方法名相同,参数列表相同,方法体不同
1.2、“运行期绑定”,看对象的类型绑定方法
2、重载(Overload):
2.1、发生在一个类中,方法名相同,参数列表不同,方法体不同
2.2、“编译期绑定”,看参数/引用的类型绑定方法
补充:
编译期:.java源文件,经过编译,生成.class字节码文件
运行期:JVM加载.class并运行.class
编译错误:只是检查语法
多态
多态指的是同一方法可以根据发送对象的不同而采用多种不同的行为方式。
一个对象的实际类型是确定的,但是可以指向对象的引用的类型有很多。
多态存在的条件:
1、 有继承关系
2、 子类重写父类的方法
3、 父类引用指向子类对象
多态的意义:
1、行为的多态(所有抽象方法都是多态的)
2、对象的多态(所有对象都是多态的)
多态的表现形式:
1、重写:根据对象的不同来表现多态
2、重载:根据参数的不同来表现多态
注:多态是方法的多态性,属性没有多态性。
instanceof 和类型转换
instanceof 是 Java 的一个二元操作符,类似于 ==,>,< 等操作符。
instanceof 是 Java 的保留关键字。它的作用是测试它左边的对象是否是它右边的类的实例(实例指的是“类”在实例化之后叫做一个“实例”。实例化:通常把用类创建对象的过程称为实例化),返回 boolean 的数据类型。
向上造型:
1)超类型的引用指向派生类的对象
2)能点出来什么,看引用的类型
向下造型:(容易出现类型转换异常)
1)派生类的引用指向超类对象
2)向下造型需要进行强转
3)能点出来什么,看引用的类型
内部类(内部类服务于外部类)
java内部类的几种类型:成员内部类,静态内部类,方法内部类,匿名内部类。
成员内部类:成员内部类是类内部的非静态类。成员内部类不能定义静态方法和变量(final修饰的除外)。这是因为成员内部类是非静态的,类初始化的时候先初始化静态成员,如果允许成员内部类定义静态变量,那么成员内部类的静态变量初始化顺序是有歧义的。
成员内部类的使用方法:
1、 Inner 类定义在 Outer 类的内部,相当于 Outer 类的一个成员变量的位置,Inner 类可以使用任意访问控制符,如 public 、 protected 、 private 等
2、 Inner 类中定义的 test() 方法可以直接访问 Outer 类中的数据,而不受访问控制符的影响,如直接访问 Outer 类中的私有属性a
3、 定义了成员内部类后,必须使用外部类对象来创建内部类对象,而不能直接去 new 一个内部类对象,即:内部类 对象名 = 外部类对象.new 内部类( );
静态内部类:
静态内部类是 static 修饰的内部类,这种内部类的特点是:
1、 静态内部类不能直接访问外部类的非静态成员,但可以通过 new 外部类().成员 的方式访问。
2、 如果外部类的静态成员与内部类的成员名称相同,可通过“类名.静态成员”访问外部类的静态成员;如果外部类的静态成员与 内部类的成员名称不相同,则可通过“成员名”直接调用外部类的静态成员。
3、 创建静态内部类的对象时,不需要外部类的对象,可以直接创建 内部类 对象名= new 内部类();
方法内部类(局部内部类):
方法内部类就是内部类定义在外部类的方法中,方法内部类只在该方法的内部可见,即只在该方法内可以使用。
需要注意:由于方法内部类不能在外部类的方法以外的地方使用,因此方法内部类不能使用访问控制符和 static 修饰符。
匿名内部类:
匿名类是不能有名称的类,所以没办法引用他们。必须在创建时,作为new语句的一部分来声明他们。但使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接口。
这种形式的new语句声明一个 新的匿名类,他对一个给定的类进行扩展,或实现一个给定的接口。他还创建那个类的一个新实例,并把他作为语句的结果而返回。要扩展的类和要实现的接口是 new语句的操作数,后跟匿名类的主体。
注意匿名类的声明是在编译时进行的,实例化在运行时进行。这意味着 for循环中的一个new语句会创建相同匿名类的几个实例,而不是创建几个不同匿名类的一个实例。
从技术上说,匿名类可被视为非静态的内 部类,所以他们具备和方法内部声明的非静态内部类相同的权限和限制。
假如要执行的任务需要一个对象,但却不值得创建全新的对象(原因可能 是所需的类过于简单,或是由于他只在一个方法内部使用),匿名类就显得很有用。匿名类尤其适合在Swing应用程式中快速创建事件处理程式。
枚举(一个一个的列举出来)
枚举是一个被命名的整型常数的集合,用于声明一组带标识符的常数。枚举在曰常生活中很常见,例如一个人的性别只能是“男”或者“女”,一周的星期只能是 7 天中的一个等。类似这种当一个变量有几种固定可能的取值时,就可以将它定义为枚举类型。
声明枚举
声明枚举时必须使用 enum 关键字,然后定义枚举的名称、可访问性、基础类型和成员等。
任意两个枚举成员不能具有相同的名称,且它的常数值必须在该枚举的基础类型的范围之内,多个枚举成员之间使用逗号分隔。
提示:如果没有显式地声明基础类型的枚举,那么意味着它所对应的基础类型是 int。
枚举类
Java 中的每一个枚举都继承自 java.lang.Enum 类。当定义一个枚举类型时,每一个枚举类型成员都可以看作是 Enum 类的实例,这些枚举成员默认都被 final、public, static 修饰,当使用枚举类型成员时,直接使用枚举名称调用成员即可。
为枚举添加方法
Java 为枚举类型提供了一些内置的方法,同时枚举常量也可以有自己的方法。此时要注意必须在枚举实例的最后一个成员后添加分号,而且必须先定义枚举实例。
Java 中的 enum 还可以跟 Class 类一样覆盖基类的方法。
六大设计原则
原则一:开闭原则(Open Close Principle)
优点
实践开闭原则的优点在于可以在不改动原有代码的前提下给程序扩展功能。增加了程序的可扩展性,同时也降低了程序的维护成本。
原则二:单一职责原则(Single Responsibility Principle)
优点
如果类与方法的职责划分得很清晰,不但可以提高代码的可读性,更实际性地更降低了程序出错的风险,因为清晰的代码会让bug无处藏身,也有利于bug的追踪,也就是降低了程序的维护成本。
原则三:依赖倒置原则(Dependency Inversion Principle)
优点
通过抽象来搭建框架,建立类和类的关联,以减少类间的耦合性。而且以抽象搭建的系统要比以具体实现搭建的系统更加稳定,扩展性更高,同时也便于维护。
原则四:接口分离原则(Interface Segregation Principle)
优点
避免同一个接口里面包含不同类职责的方法,接口责任划分更加明确,符合高内聚低耦合的思想。
原则五:迪米特法则(Law of Demeter)
优点
实践迪米特法则可以良好地降低类与类之间的耦合,减少类与类之间的关联程度,让类与类之间的协作更加直接。
原则六:里氏替换原则(Liskov Substitution Principle)
优点
可以检验继承使用的正确性,约束继承在使用上的泛滥。
JavaSE
1.将数字数组转为字符串
2.通过to string方法
通过
3.将字符串转为int型数据
4.注意:前提是字符串必须为纯数字
使用包装类进行转换 Integer.parseInt
5.将int型数组转为string类型
6.通过 int类型 + 字符 可得到一个string类型
第二种方式 string.valueOf
7.字符串的拼接
8.第一种方式 用 + 拼接
第二种方式 用concat
9.取出字符串两边的空白
10.使用 trim
11.字符串大小写的转换
12.转为大写 toUppercase()
转为小写 toLaworcase()
13.String , string buffer, string builder的区别
String类是不可变类,即一旦一个String对象被创建以后,包含在这个对象中的字符序列是不可改变的,直至这个对象被销毁。
Java提供了两个可变字符串类StringBuffer和StringBuilder,中文翻译为“字符串缓冲区”。
StringBuilder类是JDK 1.5新增的类,它也代表可变字符串对象。实际上,StringBuilder和StringBuffer功能基本相似,方法也差不多。不同的是,StringBuffer是线程安全的,而StringBuilder则没有实现线程安全功能,所以性能略高。因此在通常情况下,如果需要创建一个内容可变的字符串对象,则应该优先考虑使用StringBuilder类。
StringBuffer、StringBuilder、String中都实现了CharSequence 接口。CharSequence是一个定义字符串操作的接口,它只包括length()、charAt(int index)、subSequence(int start, int end)这几个API。
StringBuffer、StringBuilder、String对CharSequence接口的实现过程不一样
注意:string buffer 线程安全 string builder线程不安全
14.数字和日期处理
(1)Math类的常用方法
(2)Math类位于java.lang包,它的构造方法是private的,因此无法创建Math类的对象,并且Math类中的所有方法都是类方法,可以直接通过类名来调用它们
(3) 1>静态常量
(4) Math类中包含E和Pl两个静态常量,他们的值分别等于e(自然对数)和Π(圆周率)
求最大值最小值和绝对值
2>java 时间日期处理
l、Date类
Date类表示系统特定的时间戳,可以精确到毫秒。Date对象表示时间的默认顺序是星期、月、日、小时、分、秒、年。.1、构造方法
Date类有如下两个构造方法。
1、Date():此种形式表示分配Date对象并初始化此对象,以表示分配它的时间(精确到毫秒),使用该构造方法创建的对象可以获取本地的当前时间。
2、 Date(long date):此种形式表示从GMT时间(格林尼治时间)1970年1月1日0时0分0秒开始经过参数date指定的毫秒数。
日期格式化
DateFormat是日期/时间格式化子类的抽象类,它以与语言无关的方式格式化并解析日期或时间。日期/时间格式化子类(如SimpleDateFormat)允许进行格式化(也就是日期→文本)、解析(文本一日期)和标准化日期。
在创建 DateFormat 对象时不能使用new关键字,而应该使用DateFormat类中的静态方法getDatelnstance(),示例代码如下DateFormat df = DateFormat.getDatelnstance();
(1)
(2)
15.正则表达式
正则表达式是字符串处理工具,可以对字符串进行查找、提取、分割、替换等操作,是一种可以用于模式匹配和替换的范。一个正则表达式就是由普通的字符(如字符 a-z)以及特殊字符(元字符)组成的文字模式,它用以描述在查找文字主体时待匹配个或多个字符串。
方括号表达式
表示枚举如 [abc]表示a,b,c其中任意的一个字符
表示范围如 [a-f]表示a-f范围内任意字符[a-cx-z]表示a-c和x-z范围内的任意字符
表示求否 [^abc]表示不在a,b,c范围内的任意字符
表示‘与’ [a-&&[def]]是a-z和[def]的交集
表示‘并’ 和‘与’类似
包装类
1>拆箱与装箱
2>拆箱:将包装类转换为基本数据类型
装箱:将基本数据类型转换为包装类
应用:
1
2将字符串转换为数值类型 parse___
例如;在Integer类中将string转换为int类型
Int parseInt (string 字符串)
在float类型中将string转换为int类型
Float parsefloat(string 字符串)
3.将整数转换为字符串
通过 toString() 方法
Object类:
方法:
ToStrng()方法;
toString() 方法返回该对象的字符串,当程序输出一个对象或者把某个对象和字符串进行连接运算时,系统会自动调用该对象的 toString() 方法返回该对象的字符串表示。
Equals ()方法;
equals() 方法是比较两个对象的内容是否相等,通常字符串的比较只是关心内容是否相等。
getCalss ()方法
getClass() 方法返回对象所属的类,是一个 Class 对象。通过 Class 对象可以获取该类的各种信息,包括类名、父类以及它所实现接口的名字等。
接收任意引用类型的对象;既然 Object 类是所有对象的父类,则所有的对象都可以向 Object 进行转换,在这其中也包含了数组和接口类型,即一切的引用数据类型都可以使用 Object 进行接收。
Integer类
1.构造方法:
Integer 类中的构造方法有以下两个:
Integer(int value):构造一个新分配的 Integer 对象,它表示指定的 int 值。
Integer(String s):构造一个新分配的 Integer 对象,它表示 String 参数所指示的 int 值。
Float类
Float 类在对象中包装了一个基本类型 float 的值。Float 类对象包含一个 float 类型的字段。此外,该类提供了多个方法,能在 float 类型与 String 类型之间互相转换,同时还提供了处理 float 类型时比较常用的常量和方法。
Float 类
Float 类在对象中包装了一个基本类型 float 的值。Float 类对象包含一个 float 类型的字段。此外,该类提供了多个方法,能在 float 类型与 String 类型之间互相转换,同时还提供了处理 float 类型时比较常用的常量和方法。
构造方法:
Float(double value):构造一个新分配的 Float 对象,它表示转换为 float 类型的参数。 Float(float value):构造一个新分配的 Float 对象,它表示基本的 float 参数。 Float(String s):构造一个新分配的 Float 对象,它表示 String 参数所指示的 float 值。
Double类
Double 类在对象中包装了一个基本类型 double 的值。Double 类对象包含一个 double 类型的字段。此外,该类还提供了多个方法,可以将 double 类型与 String 类型相互转换,同时 还提供了处理 double 类型时比较常用的常量和方法。
构造方法:
Double(double value):构造一个新分配的 Double 对象,它表示转换为 double 类型的参数。 Double(String s):构造一个新分配的 Double 对象,它表示 String 参数所指示的 double 值。
Boolean类
Boolean 类将基本类型为 boolean 的值包装在一个对象中。一个 Boolean 类的对象只包含一个类型为 boolean 的字段。
构造方法
Boolean(boolean boolValue);
Boolean(String boolString);
Byte类
Byte 类将基本类型为 byte 的值包装在一个对象中。一个 Byte 类的对象只包含一个类型为 byte 的字段。此外,该类还为 byte 和 String 的相互转换提供了方法,并提供了一些处理 byte 时非常有用的常量和方法。
构造方法:
1.Byte(byte value) :通过这种方法创建的 Byte 对象,可以表示指定的 byte 值。例如,下面的示例将 5 作为 byte 类型变量,然后再创建 Byte 对象。
2.Byte(String s):通过这个方法创建的 Byte 对象,可表示 String 参数所指定的 byte 值。例如,下面的示例将 5 作为 String 类型变量,然后再创建 Byte 对象。
System类
System 类位于 java.lang 包,代表当前 Java 程序的运行平台,系统级的很多属性和控制方法都放置在该类的内部。由于该类的构造方法是 private 的,所以无法创建该类的对象,也就是无法实例化该类。
System 类提供了一些类变量和类方法,允许直接通过 System 类来调用这些类变量和类方法
System类成员变量
1)PrintStream out
标准输出流。此流已打开并准备接收输出数据。通常,此流对应于显示器输出或者由主机环境或用户指定的另一个输出目标。例如,编写一行输出数据的典型方式是:
System.out.println(data);
其中,println 方法是属于流类 PrintStream 的方法,而不是 System 中的方法。
2)InputStream in
标准输入流。此流已打开并准备提供输入数据。通常,此流对应于键盘输入或者由主机环境或用户指定的另一个输入源。
3)PrintStream err
标准的错误输出流。其语法与 System.out 类似,不需要提供参数就可输出错误信息。也可以用来输出用户指定的其他信息,包括变量的值。
System类的成员方法:
1)arraycopy() 方法:该方法的作用是数组复制,即从指定源数组中复制一个数组,复制从指定的位置开始,到目标数组的指定位置结束
2)currentTimeMillis() 方法:该方法的作用是返回当前的计算机时间,时间的格式为当前计算机时间与 GMT 时间(格林尼治时间)1970 年 1 月 1 日 0 时 0 分 0 秒所差的毫秒数。
3)exit() 方法:该方法的作用是终止当前正在运行的 Java 虚拟机
3)gc() 方法:该方法的作用是请求系统进行垃圾回收,完成内存中的垃圾清除。至于系统是否立刻回收,取决于系统中垃圾回收算法的实现以及系统执行时的情况
4)getProperty() 方法:该方法的作用是获得系统中属性名为 key 的属性对应的值
Lambda表达式
注意:优点:代码简洁,开发迅速,方便函数式编程,非常容易进行并行计算。缺点:代码可读性变差,在非并行计算中,很多计算未必有传统的 for 性能要高,不容易进行调试
函数式接口:
Lambda 表达式实现的接口不是普通的接口,而是函数式接口。如果一个接口中,有且只有一个抽象的方法(Object 类中的方法不包括在内),那这个接口就可以被看做是函数式接口。
使用:
作为参数使用
访问变量,Lambda 表达式可以访问所在外层作用域定义的变量,包括成员变量和局部变量。
方法引用
方法引用可以理解为 Lambda 表达式的快捷写法,它比 Lambda 表达式更加的简洁,可读性更高,有很好的重用性。如果实现比较简单,复用的地方又不多,推荐使用 Lambda 表达式,否则应该使用方法引用。双冒号::运算符,该运算符用于“方法引用”,注意不是调用方法
接口和泛型
接口:
Collection接口:
Collection 接口是 List、Set 和 Queue 接口的父接口,通常情况下不被直接使用。
List集合:
List 是一个有序、可重复的集合,集合中每个元素都有其对应的顺序索引。List 集合允许使用重复元素,可以通过索引来访问指定位置的集合元素。List 集合默认按元素的添加顺序设置元素的索引,第一个添加到 List 集合中的元素的索引为 0,第二个为 1,依此类推。
Arraylist类:rrayList 类实现了可变数组的大小,存储在内的数据称为元素。它还提供了快速基于索引访问元素的方式,对尾部成员的增加和删除支持较好。使用 ArrayList 创建的集合,允许对集合中的元素进行快速的随机访问
LinkedList类:nkedList 类采用链表结构保存对象,这种结构的优点是便于向集合中插入或者删除元素。需要频繁向集合中插入和删除元素时,使用 LinkedList 类比 ArrayList 类效果高,但是 LinkedList 类随机访问元素的速度则相对较慢。这里的随机访问是指检索集合中特定索引位置的元素。
Set集合:
HashSet 类:
特点:
1、不能保证元素的排列顺序,顺序可能与添加顺序不同,顺序也有可能发生变化。
2、HashSet 不是同步的,如果多个线程同时访问或修改一个 HashSet,则必须通过代码来保证其同步。
3、 3、集合元素值可以是 null。
TreeSet类:
TreeSet 类同时实现了 Set 接口和 SortedSet 接口。SortedSet 接口是 Set 接口的子接口,可以实现对集合进行自然排序,因此使用 TreeSet 类实现的 Set 接口默认情况下是自然排序的,这里的自然排序指的是升序排序。
TreeSet 只能对实现了 Comparable 接口的类对象进行排序,因为 Comparable 接口中有一个 compareTo(Object o) 方法用于比较两个对象的大小。例如 a.compareTo(b),如果 a 和 b 相等,则该方法返回 0;如果 a 大于 b,则该方法返回大于 0 的值;如果 a 小于 b,则该方法返回小于 0 的值。