Java体系
1 | 基础部分(JavaSE): |
基本数据类型
1.整型
byte | 一个字节为8个二进制位,在计算机中,最高为用于表示符号,并且把0放在了正数中,所以byte类型的范围转换为十进制为-128—+127 |
---|---|
short | 一个short占2个字节,-32768—+32767 |
int | 一个int占4个字节,-2^31—+2^31-1 |
long | 一个long占8个字节,-2^15—+2^15-1 |
2.浮点型
float(单精度浮点数) | 4个字节 |
---|---|
double(双精度浮点数) | 8个字节 |
3.字符型
注意:java中默认编码集为Unicode编码集
char | 2个字节 |
---|---|
中文占2个字节,英文、符号、数字1个字节 |
4.布尔型
注意:C语言中bool类型可以和整型发生转变,但在Java中不可以发生转换
boolean | 1个比特位(bit) |
---|---|
引用数据类型:
枚举(enum),类(class),注解(@interface),数组([]),接口(interface)
注意:String本质上是类,也就是引用数据类型,但是它的值很特殊,值可以简单视为常量
变量与常量
常量:基本类型的值
变量是一个空间,可以只创建空间,里面不存放内容,变量空间创建后是没有默认内容的,空的空间不能使用
在常量区中,整数默认为int(32bit),浮点数默认为double(64bit),如果定义float a=3.4;出错,因为float存不下,想要存下要人为修改,改为float a=3.4f;字母大小写都可以,long也是同样的道理,超过int范围时,后加L,大小写都可以。
byte a=1;它可以的原因,自动把没用的截取。只要十进制的没超过byte类型的范围,就可以存进去。
常量存储在常量缓冲区中
字符
字符单引号,有且只有一位。字符串存在空串,双引号。
“”:空字符串
null:什么都没有,连空串都不是
类型转换
1.同种数据类型之间可以直接进行数据转换
2.不同数据类型之间需要进行数据转换,注意:大类型之间(基本数据类型和引用数据类型)通过包装类发生转换,基本和基本类型之间可以直接转换,引用类型和引用类型之间可以直接转换
小空间的可以直接转换到大空间内。int ->double 等等
大空间放在小空间的里面,强制转换,如int->byte,double ->byte等等,(需要转换为的数据类型)
1 | double a=129; |
整数与浮点数比较的为精确程度,浮点型精确度更高,可以直接转换,不是看空间,long->float可以
1.9和1强制转换都为1,小数部分直接砍掉,不是四舍五入。任何浮点型都可以存放整数。
字符型与其他类型转换:(自动转化)
1 | char a='a'; |
其他类型转换为其他会出错,Error:(7, 15) java: 不兼容的类型: 从byte转换到char可能会有损失,需要强制转化,整数在做计算时,都会变为32位或者64位,即使是byte类型或者short类型。
布尔类型很特殊,不能与其他基本类型转换
运算符
运算符:用来指明操作数的运算方式
算术运算 | +、-、*、/、%、++(自增)、–(自减) |
---|---|
赋值运算 | =、-=、+=、/=、%= |
关系运算 | <、>、<=、>=、==、!=,instanceof对象比较 |
逻辑运算 | &(逻辑与)、|(逻辑或)、!、^(异或)、&&(短路与)、||(短路或) |
位运算(用来计算二进制) | &(按位与)、|(按位或)、^(按位异或)、~(按位取反)、<<(按位左位移)、>>(按位右位移)、>>>无符号右位移 |
算术运算
算术运算的结果取决与参与运算的符号类型
x++等价于x=x+1
x++与x的值相同,++x的值为执行完的值
X+=10等价于X=X+10
赋值运算
1 | byte v=1; |
1 | byte v=1; |
深入理解内存原理:
先计算,后赋值
x++相当于x=x+1,先将x中的值取出,常量区取出1,进行计算,然后将结果再放回x空间
在进行值交换的时候,x本身会产生一个临时的副本空间(备份),++在变量的前面 ,先自增后备份,++在变量的后面,先备份后自增,会将临时副本空间的值赋给别人。之后临时空间就会被销毁了。
1 | double x=5; |
1 | double x=5; |
赋值又赋回来了,2被1覆盖掉,所以不变,一开始的1和最后的1不一样
1 | int m=1; |
笔试题:
1 | int m=1; |
逻辑运算前后必须是两个boolean型的结果
异或:两者相同为0,不同为1
短路与或 比 逻辑与或 性能稍好
1 | &&因为只要当前项为假,它就不往后判断了,直接认为表达式为假 |
位运算
位运算:将十进制数转换为二进制数,然后按照对应位置&、|、^,最后将得到的结果再转换为十进制
常量默认为32位
八进制最前面用0表示,用于与10进制区分,16进制开头用0X表示
计算机中所有的数都是用补码表示的,其中反码是表示形式,取反是一个计算过程(每一个位置都取反)
1 | **笔试题**: |
Java语法结构
顺序结构 | 代码顺序执行 |
---|---|
分支结构 | 单分支(if ……else……)、多分支(switch) |
循环结构 | while、do…while、for |
输入
Scanner引用数据类型,
1 | Scanner sc=new Scanner(System.in); |
随机数:Math.random()范围0-1之间的小数[0.0,1.0)
==与equals()的区别
基本类型比较用等号,引用类型在用==作比较的时候,比较的不是值,而是地址,因为引用类型存的就是地址
1 | public class Test { |
注意:值可以为byte、short、int、char、String(1.7版本以上),eunm(1.5版本以上),char可以转换为整数计算,实际上都为数值
1 | switch(值){ |
循环结构
循环:重复不停的做同样事情,而不是同件事情
栈内存:从声明开始,用完就会回收
for允许将3个必要条件都写在括号内,不是必须
1 | for(初始值;终点判定条件;变化量){ |
Math.pow(a,b);帮我们计算a的b次方,再进行输入时,a和b都为double类型
1 | //画星星 |
注意:写程序不能满足只写出来,要注重程序的可复用性
转义字符:\,可以转换特殊的字符,将身后的一个字符意思发生转换。
\n | 换行 |
---|---|
\r | 回车 |
\t | 制表符(输出内容按表格处理) |
回车与换行的区别:
1 | \r 回车是将光标移到一行的前面, \n 是移到下一行 。 |
1 | //判断素数 |
关于for循环中的break语句,满足就近原则,当在嵌套循环中使用时,满足就近原则,终止最近的循环
continue:中断本次循环,继续执行下一次循环
1 | while语句: |
1 | do……while()语句: |
do……while与while的区别:
do……while | 先执行代码,后判断,条件不满足至少执行一次 |
---|---|
while | 先判断,后执行,条件不满足就不执行 |
Java数组
数据和变量一样,都可以作为容器,数组可以存放一组数据类型相同的数据的组合。
数组本身是一个引用数据类型,数组内存储的类型可以是基本类型,也可以是引用数据类型(如字符串类型)
1 | 数组的定义(声明): |
数据的赋值(初始化):
1.静态初始化
1 | int[] array = new int[]{10, 20, 30, 40, 50}; |
JDK1.5版本—>J2SE—>JavaSE5.0
新特性:增强for循环
1 | for(自己定义的变量(为了接收数组内每一个元素):遍历的数组名字){ |
1 | //加强循环例子 |
增强for缺点:只能取值,不能存值,没有index索引,找不到元素到底是哪个
2.动态初始化
1 | 有长度,没有元素 |
注意:
1 | int[] m=new int[0]; |
动态初始化有长度,一开始未初始化则使用默认值,整数默认值为0,浮点数为0.0,字符型默认值为0对应的字符,布尔类型默认值为false,引用数据类型默认为null
1 | String[] m = new String[2]; |
数组长度:array.length
重点:基本数据类型和引用数据类型在内存结构上的区别
内存大概:
栈内存:
堆内存:
存储区:常量区、方法区(类)、静态区(static)
基本类型变量空间存储的为值,传递的就是值
引用类型变量空间存储的是地址(引用),传递的就是引用
所有的变量空间都存储在栈内存
变量空间可以存储基本数据类型,也可以存储引用数据类型
1 | 例子: |
数组作为栈内存中的小容器
注意:见到new关键字,相当于在堆内存中申请开辟一块新的空间。数组在堆内存的空间状态是一串连续的地址,堆内存的数组空间长度一旦确定,不能再次发生改变,另外数组在初始化时必须指定长度
数组X中存的实际上为HashCode,简单理解为首元素的地址
元素个数比较少,静态
元素个数很多,动态
例题:
1.交换两个数组的值:当两数组个数相等时:
1 | int[] a = {1, 2, 3, 4}; |
当两数组个数不等时:
交换数组地址:一次搞定,不受数组长度限制
1 | int[] c; |
2.保留非0数
1 | int[] a = {1, 2, 3, 0, 0, 4, 5, 0, 6, 0, 7}; |
3.创建一个数组,存储2-100之间的素数(质数)
1 | int[] a = new int[98]; |
这个思路是牺牲部分空间换取时间,另一种思路是提前确定素数个数,根据个数节省空间,但时间消耗更为严重
1 | //冒泡排序,完全根据“冒泡”表面意思来的 |
二维数组:
1 |
|
1 | 二维数组在内存中的存储: |
mian方法:
1 | public static void main(String[] args){ |
测试:
1 | System.out.println(args.length); |
Java—-面向对象的编程思想
类:抽象笼统的概念,用来描述一类事物,这类事物具有相同的特征和行为。
对象:具体的实体
(1)创建一个类 |
---|
(2)在类的里面,利用属性或方法去描述这个类 |
(3)创建一个当前类的对象,让对象调用属性/方法做事 |
属性描述:权限修饰符 [特征修饰符] 数据类型 属性名字 [=值];
属性默认是只有同包或者本类访问,主方法属于JVM虚拟机
对象的创建在哪里都可以,使用new关键字创建,通过 对象.去调用属性进行存值和取值或者方法
在内存中经JVM的ClassLoader类加载器加载到方法区,形成类的映射,这个映射并不是完整的类文件
new出来的对象存放在堆内存中,所以有默认值存在,依照各属性数据类型赋默认值
例子:注意输出结果
1 | Person p = new Person(); |
类中的方法描述:
权限修饰符 [特征修饰符] 返回值类型 方法名字(参数列表) [抛出异常] [{
方法体 }]
面向对象之方法参数返回值问题:(核心)
1 | public class Person { |
如果上述过程想让a发生改变,可在临时空间消失之前将10拿出来,即返回出来,添加return语句
1 | public int changeNum(int x) { |
如果内容是基本类型,传递的是值,形参改变,实参不变
如果内容是引用类型,传递的是引用,形参改变,实参跟着改变
注意:
String类型是一种特殊类型的引用类型,对String进行的任何修改,String都会新产生一个对象,存放修改后的String。
堆内存可以简单理解为仓库,其中只能存储,不能做处理数据的操作,所有的执行过程都不能在堆内存中执行
命名规则和规约
规则
字母、数字、符号、中文
字母 区分大小写
数字 不能开头
符号 _$
中文不推荐使用
规约
类名字:首字母大写 两个单词以上 每一个首字母大写:Test、TestOne……
属性/方法/变量:驼峰式命名规约 首字母小写 两个单词以上 第二个以后的每一个首字母大写 :test、testOne 、testOneTwo……
构造方法:与类名一致 ;类中唯一的大写字母开头的方法
静态常量: 全部首字母大写 通过_做具体说明:BOOKESTORE_ADMIN
包名:全部字母小写,java关键字都是小写,注意与关键字不要冲突
所有的名字最好见名知义,增强可读性
操作属性规约:
age——>存 setAge()、获取getAge()
私有属性对应方法:getName()、setName()……
方法重载overload
最常见的就是System.out.println();
概念:一个类中的一组方法,相同的方法名字,不同的参数列表,这样的一组方法构成了方法重载
作用:为了让使用者便于记忆和调用
参数的个数、参数的类型或者参数顺序有一个不同就是重载
方法参数传递,类型之间的转化问题:类型转换必须保证大数据类型必须一致,String为引用类型,char为基本类型,无法转换 。
char可以和int转换
1 | char x='a'; |
如果方法名字有一致,可以通过参数的数据类型定位方法
如果没有与传递参数类型一致的方法,可以找一个参数类型可以进行自动转换的
JDK1.5版本之后,出现了新写法
1 | 动态参数列表 |
x本质上就是一个数组,有length属性,有索引
1 | public void test(int... x){ |
动态参数列表的方法不能与相同意义数据类型的方法构成重载,因为本质上是一样的
动态参数列表在方法参数中只能存在一份,且必须放置在方法参数的末尾
构造方法
只有这一个方法名字大写字母,没有特征修饰符,返回值类型
作用:只有一个构建当前类的对象
注意:构造方法存在返回值,可以接收
写法:
1 | 权限修饰符 与类名一致的方法名(参数列表)[抛出异常]{ |
用法:通过new关键字调用
特点:
1.每个类都有构造方法,若自己在类中没有定义,系统会默认提供一个无参数的构造方法。若在类中自己定义了构造方法,则默认无参数的构造方法即被覆盖。
2.构造方法存在重载
为什么使用?
你可以在创建对象的同时做一些其他事情
例子:
1 | public class Person { |
建议:
在自己定义带参数的构造方法的同时,将系统不带参数的构造方法一并写出来构成构造函数的重载
传参与属性重名时,用this代替当前调用方法时的那个对象
1 | public class Person { |
程序块(代码块)
理解为一个方法,非常特殊,无参数无返回值无名字,也就无修饰符
作用:跟普通方法一样,做事情的
写法:
1 | { |
他是类的成员,写在类中
用法:块也需要调用才能执行,我们自己在每次调用构造方法之前,系统帮我们自动调用一次
特点:没有重载的概念,当存在多个代码块时,按照编写顺序执行
1 | public Person(String name, int age) { |
可以在块中写一些程序,我想要在创建对象之前执行
this关键字的使用
1.关键字。代替的是某一个对象(当前调用属性或方法的那个对象)
2.this代替的是一个对象,则可以调用属性和方法
3.调用属性和方法这一行代码可以放置在类中的任何成员位置
this可以在一个构造方法内调用另一个构造方法,但在一般方法中不能调用构造方法,因为有顺序,先执行构造方法才能调用一般方法,但在构造方法中调用其他构造方法是写法为this();省略了构造方法的名字,构造方法与类名一致,所以省略。
在构造方法中调用另一个构造方法中this(xx)必须放在第一行,在构造方法中不能来回调用
this方法之间来回调用,编译会通过,即写法可以,但在执行时会发生错误:StackOverflowError:栈溢出错误,新的临时空间一直产生,旧的临时空间还未释放
循环标记
标签在循环中可以改变循环执行的流程。而这种改变不是我们以前单独使用break或者是continue能够达到的
1 | outer1: |
类
类:包括属性、方法、构造方法、程序块(代码块)
修饰符:private:只有在当前类的内部才能访问(数组类编写)
权限修饰符
大小比较:public>protected>private
关系
泛化(继承、实现)
A is a B
存在父类和子类,类与对象就是抽象和具体的关系,使用继承可以减少代码冗余
语法:
子类继承父类,通过关键字extends实现
继承特点:
1.子类在继承父类后,可以调用父类中的(public protected限定的)属性和方法,当作自己的来使用
2.除此之外,子类可以添加自己独有的方法属性使用
3.子类从父类中继承过来的方法不能满足子类的需要,可以在子类中重写(覆盖)父类的方法
4.每一个类都有继承类,如果不写extends关键字,默认继承Object,写了的话就继承后面的那个类。
5.Java中的继承是单个存在的,每个类只能有一个继承类,在extends后面只能写一个类,目的是为了让类更加的安全。但可以通过传递的方式实现多继承的效果
6.Object类是任何一个引用类型的父类(都直接或者间接的继承Object),Object没有父类
1 | Object中的toString()方法 |
Object类public权限方法
toString() | 在打印输出时将一个对象变成一个字符串 |
---|---|
equals() | 用来比较两个对象的内容,底层为== |
hashCode() | 将对象在内存中的地址经过计算转化为int整数 |
getClass() | 获取对象对应类的类映射(反射) |
wait() | 线程进入挂起等待状态(存在重载) |
notify() | 线程进入唤醒状态 |
notifyAll() | 唤醒所有线程 |
finalize() protected | 类似于析构函数,GC时调用 |
clone() protected | 将对象拷贝一份的 |
7.继承在内存中的存储形式:
类似于洋葱,一层一层包裹起来,子类构造方法执行时父类的也会创建
8.this和super的使用:
this关键字,代替当前调用方法属性时的那个对象,不一定是当前类的
super代替的是当前执行方法时的对象的父类对象
都能调用一般属性和一般方法,可以调用构造方法,放在第一行
注意调用一般方法的时候可以来回互相调用(写法 编译好用),执行可能出现问题栈溢出异常
构造方法之间不能来回户想调用(编译就不好用),子类构造方法执行时会先调用构造方法,在子类构造中隐藏super(),如果来回调用,super方法就会被覆盖,父类无法调用构造方法,出错。也就说super和this可以同时出现,但在构造方法中同时出现是不行的
包含(组合、聚合、关联)
A has a B
组合:(如:人和大脑、人与心脏) | 整体关系,不可分割。要出现都出现,要消亡都消亡 |
---|---|
聚合:(如:汽车和车轮,电脑和主板) | 整体和部分的关系,其实能分割。关系不如组合紧密 |
关联:(如:人有汽车、人有电脑) | 整体和部分,可以分割,后来形成在一起的 |
Java描述:通过一个类的对象作为另一个类的属性
依赖(最常见的关系)
A use a B
不是整体和部分的关系,某一件事情产生了关系
临时组合在一起,这件事情做完关系即解散
Java程序体现的形式为:一个类的方法中使用到了另一个类的对象
(1)可以在方法中传递参数
(2)可以在方法中自己创建
修饰符
分类:
权限修饰符(从大到小):
public:公共的
protected:受保护的
默认不写:默认的
private:私有的
特征修饰符:
final:最终的,不可改变的
static:静态的
abstract:抽象的
native:本地的,本国的(hasCode方法就是这样的)
*transient:瞬时的,短暂的——–》序列化
synchronized:同步的,*修饰方法**的
volatile:*修饰属性**的,不稳定的
权限修饰符:
修饰什么?
1.权限修饰符能够修饰类、类中的属性和方法(程序块除外)和构造方法
2.权限修饰符在修饰类时只有两种(public、默认不写)
一个文件中可以编写多个类,但只允许有一个public类
3.权限修饰符都可以用来修饰类中的成员
特点:
四者都能在本类中访问
同包:package相同的才是同包,package路径不同的不算同包
public | 本类、同包、子类,当前项目中任意类的位置只要有对象都能访问 |
---|---|
protected | 本类、同包、子类范围内部通过子类对象访问,但父类访问不到,保护方法只能让子类调用 |
默认不写 | 本类、同包 |
private | 本类 |
特征修饰符:
修饰什么?
修饰变量、属性、方法、类
public final class Test{}
特点:
1.final:最终的,不可修改的。可以修饰变量、属性、方法、类
修饰变量:如果在定义变量时没有赋初值,给变量一次存值的机会,变量在栈内存空间内没有默认值。
特点:
一旦变量被存储了一个值,若用final修饰后不能改变,相当于常量。如果修饰的变量为基本数据类型,则变量内的值不让更改,修饰的为引用数据类型,则变量内的地址引用不让更改
修饰属性:全局变量,存储在堆内存的对象空间内的空间,属性如果没有赋值,有默认值存在的,属性用final修饰后,必须给属性赋初值,否则编译报错,特点与修饰变量一致
修饰方法:方法是最终的方法,不可更改。即不可以被子类重写(覆盖)
修饰类本身:表示类是最终的,不可修改。此类不能被其他的子类继承。
通常都是一些定义好的工具类
2.static:静态的
可以修饰属性、方法、块(块唯一拥有的东西)、修饰*内部类**
修饰后的所有特点都是一样的
(1)静态元素在类加载时就初始化了,很早,此时没有创建对象
(2)静态元素存储在静态元素区中,每个类都有自己的,每一个不冲突
(3)静态元素只加载一次,全部的类对象及类本身共享
(4)由于静态元素区加载时,有可能没创建对象,可以通过类名字直接访问
(5)垃圾回收只能回收栈内存和堆内存的,静态元素区GC(Garbage Collection)无法管理,可以粗暴的认为常驻内存
(6)非静态成员(堆内存对象里)中可以访问静态成员(静态区)
(7)静态成员可以访问静态成员(都存在静态区中)
(8)静态成员中不可以访问非静态成员。一个出发访问一堆相同名字的成员,静态成员属于类,非静态成员属于对象自己的
(9)this指代当前调用方法时的对象。静态成员属于类,所以静态成员 中不能出现this或super关键字
3.abstract:抽象的(不具体,只是个概念,没有具体执行)
只能修饰类、方法。是用来描述事物的,但不清晰
抽象方法:只有方法结构,没有方法体,使用abstract抽象
普通类不能含有抽象方法,在类中添加abstract使类变成抽象类
注意:抽象方法一定在抽象类或接口中,但抽象类中不是必须含有抽象方法的
特点:
研究思想:
(1)类里面有什么
可以含有属性,与正常的类没有区别
可以含有一般的方法,比一般类多的是允许含有抽象的方法
块是一种特殊的方法,可以含有
可以含有构造方法,包括重载
(2)类的使用
抽象类含有构造方法,但不能通过调用构造方法直接创建对象
抽象类只能通过子类单继承来做事
why不能掉用?
自己是”残次品“,可能创建出来的方法不能用
但必须有,这样子类才能用
(3)类与类的关系
抽象类可以直接单继承抽象类、具体类(用法通常不会出现)
具体类不可以直接单继承抽象类,需要把抽象方法具体化才行或具体类转化为抽象类
抽象类中没有具体成员全部都是抽象方法,即抽象到了极致,即发生了质的变化,叫做接口
接口不用class修饰,使用interface修饰,
1 | public interface 类名{ |
接口中的属性只能含有公有静态常量,即public static final
不能含有一般方法,只能含有公有的抽象方法,1.8之后可以使用default来修饰一般方法
不能含有大括号,所以静态和一般的代码块就没有了,块本身就是具体的
不能含有构造方法
接口只为了定义规则,不描述具体过程
接口只能通过子类多实现(implements)来做事
1 | public class A implements B,C,D){ |
与个别类的关系:
抽象类直接多实现接口
具体类不能直接多实现接口类,必须将接口中的抽象方法具体化或自己变成抽象类
接口不能继承别的类,他是最抽象的
*接口与接口之间是多继承的
4.native:本地的,源代码中看到就已经再也看不到后续代码了
后续调用其他的编程语言c/c++执行内存的操作。
注意:用native修饰的方法不是抽象方法,虽然也没有方法体,他是执行的过程是其他语言写的,看不见
Object类中的hashCode()
类的加载机制顺序
1.加载父类模板
2.父类产生自己的静态空间,按照顺序依次为属性、方法、静态块
3.执行父类静态块
4.加载子类模板
5.子类产生自己的静态空间,按照顺序依次为属性、方法、静态块
6.执行子类静态块
7.开辟对象空间
8.加载父类的非静态成员,按照顺序依次为属性、方法、块、构造方法
9.执行块、执行父类的构造方法
10.加载子类的非静态成员,按照顺序依次为属性、方法、块、构造方法
11.将对象空间的地址引用交给变量来存储
多态
同一个对象,体现出来的多种不同的形态(身份)将一种行为表现出不同的结果
想要实现多态的效果,首先存在继承关系
1体现:父类类型引用指向子类的对象。
例:Person p =new Teacher(); //这是个真老师,但体现出来的身份是人的身份
2结果:该引用体现的身份,该引用只能调到父类中定义的属性和方法
3.如果子类中将父类的方法重写了,那么调用方法后执行的结果是子类重写之后的那个结果(跟属性无关)
4.如果想要调用子类的独有的属性方法,需要将类型还原回真实类型,强制类型转换
Teacher t = (Teacher)p;
5.造型时(强制向下转型时)可能会出现运行异常(ClassCastException:类造型异常)
对象 instanceof 类:对象属于类或该类的子类,避免出现异常
看真实的对象
内部类
指的是在Java中可以将一个类定义在另一个类的内部,一般只有自己用的类写在自己类里面
内部类定义
(1)类的内部(与类成员层次一致)
(2)方法/块内部(与类成员相差一个层次,与方法的局部变量一个层次)
分类:
成员内部类、局部内部类、匿名内部类(成员匿名内部类、局部匿名内部类)、静态内部类(成员静态内部类static)
成员内部类:
1.成员内部类可以访问外部类的所有成员。
2.内部类属于外部类的,相当于外部类成员。
1 | Demo demo = new Demo();//创建外部类 |
3.当内部类成员与外部类的成员发生重名时,使用外部类.this.外部类成员来进行访问 Demo.this.name
4.小细节:在内部类存在后,源代码编译产生字节码,如Demo$InnerDemo.class
局部内部类:
定义在方法里面或块里面,相当于局部变量,方法执行完,类即被回收。只能用abstract或final修饰,其他不行构造方法不行
使用的变量只能是final的
匿名内部类:
不能用任何的修饰符来说修饰,匿名内部类没有构造函数
1 | public interface Test{ |
静态内部类:
成员静态内部类
不需要外部对象
静态成员不能访问非静态成员
public static class A{}
枚举类
引用类型:数组、类、抽象类、接口、枚举、注解
一个类中的对象,认为个数是有限且固定的(季节、天数……),可以挨个将每个对象一一列举出来
自己手动设计:
private构造方法
public static final 属性= new ……;
1 | public enum Day{ |
1.枚举类型都会默认继承Object类、Enum类
name:名字 ordinal:顺序(在枚举类的索引)
2.valueOf():通过给定的name获取对应的枚举对象
values():在Enum源码中没有,虚拟机加载时手动放的。获取全部的枚举对象,装在数组中返回。 Day[]
compareTo():可以比较两个枚举对象,返回int,整数表示,越靠近前面的数字越小,按照索引。
3.switch内部判断枚举的应用
4.可以在enum中描述自己的一些属性或方法,必须在enum类的第一行描述枚举对象的样子,可以定义自己的属性。需要提供构造方法,必须是私有的
1 | public enum Day{ |
Runtime类
提供了几个管理内存的方法
1 | Runtime r = Runtime.getRuntime(); |
小细节
1.Java在编写时,类名要大写。
2.在进行编译和运行时,默认不加修饰符,编译形成的文件为类名.class(Test.java–>Demo.class)。在加上public 后,强制要求类名必须要与文件名一致(Test.java–>Test.class),否则出错,这样编译出来的class文件就会与类名一致。
3.在进行输出时,System.out.println();自带换行, System.out.print();不带换行
4.方法重载:overload。一个类中的一组方法
方法重写(覆盖):override。子类重写父类的方法,发生在继承中
方法重写 | 方法重载 | |
---|---|---|
权限修饰符 | 子类可以大于等于父类 | 没有要求 |
特征修饰符 | final static abstract 父类方法为final,子类不能重写 ;父类方法为static,子类不存在;父类方法为abstract,子类必须重写(子类是具体的必须重写,否则子类是抽象类,可以不重写) | 没有要求 |
返回值 | 子类可以小于等于父类 | 没有要求 |
名字 | 子类与父类一致 | 一致 |
参数 | 子类与父类一致 | 必须不一致(个数、类型、顺序) |
异常 | 父类方法抛出运行时异常,子类可以不予理会;父类方法抛出编译时异常时,子类抛出异常的个数和类型都要小于等于父类 | 没有要求 |
方法体 | 子类的方法应该与父类不一致 | 应该不一致 |
5.类的个数变多,需要管理–》使用包,当package和import同时出现时,先写package后写import,包只能有一个,import可以有多个
6.设计类的关系遵循的原则:高内聚(自己的事情只与自己有关)低耦合(别人的事情与自己无关)
耦合度最高的为继承,然后包含,最后依赖
7.Java面向对象的四个特征(继承、封装、多态、(抽象))
封装:将一些数据或执行过程进行一个包装,目的是为了保护这些数据或执行过程的安全,方法本身就算是封装
8.堆内存的空间存在默认值,栈内存的没有默认值
异常
InputMisMatchException:输入类型不匹配(要求输入整数输入了字符),字符自动转换为整数,整数不能自动转换为字符
ArrayIndexOutOfBoundsException:数据索引越界异常
NegativeArraySizeException:运行时异常。创建数组时数组长度给了负数,数组的长度不合法
NullPointerException:空指针异常(空元素在使用时出现的)
NumberFormatException:数字格式化异常(abc无法转化为数字……)
ArithmeticException:(运行时异常,变异不会出错)数学异常 例(100/0)
ClassCastException:类造型异常(多态)
IllegalArgumentException:非法参数异常(int result = r.nextInt(0);)