java基础知识整理.docx
《java基础知识整理.docx》由会员分享,可在线阅读,更多相关《java基础知识整理.docx(16页珍藏版)》请在冰豆网上搜索。
java基础知识整理
Java技术知识体系整理
一.Java基础
1.final
final关键字可修饰类,方法和变量
1)final修饰变量:
变量一旦获得了初始值就不能改变,即只能。
初始化一次。
a.final因为系统会对成员变量进行初始化,所以修饰的成员变量必须由程序员显示指定初始值。
初始化方法:
类变量在声明或者静态初始化块中指定初始值,只能是这两种方法;实例成员变量可以在声明、非静态初始化块或者构造器中指定初始值,只能是这三种方法中的一种
b.final修饰局部变量。
因为系统不会对局部变量做初始化,所以使用final修饰局部变量,既可以在声明时指定默认值,也可以在后面代码中进行赋值,但是只能赋值一次
c.final修饰基本类型和引用类型的区别。
Final修饰基本数据类型时,不能对基本类型变量重新赋值,引用类型保存的仅仅是引用,只要指向的地址不变即可,引用的对象可以改变。
d.可执行宏替换的final变量
满足以下条件就不再是一个变量,而是一个直接量:
使用final修饰,在定义时指定了初始值,初始值可以在编译时确定下来,可以是直接定义时赋值、或者基本的算术表达式、字符串连接运算也可以,不能访问普通变量、方法,宏变量就是在编译时会将所有用到该变量的地方直接替换为该变量的值,简单的说,宏变量就是当成常量用;实例变量只能在定义时指定初始值才能是宏变量。
2)final修饰方法
final修饰的方法可以被继承,不能被重写,可以被重载,不希望子类重写父类的方法可用,
3)final修饰的类
Final修饰的类不能有子类,即不能被继承,最终类
2.八大数据类型包装类:
Integer在-127-128之间相同的值是同一对象,不在此范围的相同的值也是不同的对象
Java7增加了静态的compare方法比较大小
Java8支持无符号算术运算
3.Javanative用法;
Jnijavanativeinterface本机编程接口,
native关键字说明其修饰的方法是一个原生态方法,方法对应的实现不是在当前文件,而是在用其他语言(如C和C++)实现的文件中。
Java语言本身不能对操作系统底层进行访问和操作,但是可以通过JNI接口调用其他语言来实现对底层的访问。
JNI是Java本机接口(JavaNativeInterface),是一个本机编程接口,它是Java软件开发工具箱(javaSoftwareDevelopmentKit,SDK)的一部分。
JNI允许Java代码使用以其他语言编写的代码和代码库。
InvocationAPI(JNI的一部分)可以用来将Java虚拟机(JVM)嵌入到本机应用程序中,从而允许程序员从本机代码内部调用Java代码。
是为了解决java性能弱问题,在java中只定义接口,然后使用c等执行效率高的编程语言实现,并在java中调用该接口,解决java执行效率低下的问题
native用法:
1.编写带有native声明的方法的Java类(java文件)
2.使用javac命令编译编写的Java类(class文件)
3.使用javah-jni****来生成后缀名为.h的头文件(.h的文件)
4.使用其他语言(C、C++)实现本地方法
5.将本地方法编写的文件生成动态链接库(dll文件)
4.Object
Java.lang.Object是任何类的父类,默认继承Object
toString()方法:
默认是运行时类名className@Hex(hashcode)
equals()方法,比较是否指向同一个对象,可以通过重写方法比较值是否相等。
Hashcode方法。
返回对象的hashcode值。
默认情况根据对象地址来计算,即system.identityhashcode(Objecto)的值,但是很多类都重写hashcode方法
Clone方法。
需要实现Cloneable接口,重写clone方法。
只是浅克隆,克隆的是原有对象的副本,而引用类型变量只是复制了引用地址,仍然指向一个对象。
深克隆,递归克隆,保证所有引用类型的变量所引用的对象都被复制了。
Finalize方法进行资源清理
GetClass方法,返回对象的运行时类
Wait方法
Notify方法
对象比较是否相等基本数据类型可以用==比较
Object类型比较的是引用的内存地址是否相等
5.Java关键字
Java所有关键字都是小写,大写的BOOLEAN,TRUE,FALSE等都不是关键字,共有50个关键字
其中goto、const也被称为保留字,保留字的意思,目前还没用作关键字,但是可能在未来的java版本中用作关键字
6.标识符
标识符就是用于给程序中变量、类、方法命名的符号。
Java的标识符必须以字母、下划线、$开头,后面可以跟数字、字母(不限于英文字母,也可以是中文、日文字符等)、下划线、$
注意的点:
不能以数字开头
不能是java关键字和保留字
不能包含空格
只能包含$,不能包含@#等其他特殊字符
7.数据类型分类
Java是强语言类型(stronglytyped)。
强类型的含义是:
所有的变量必须先声明后使用
指定类型的变量只能接受类型与之匹配的值
Java数据类型分为基本类型和引用类型
基本类型:
boolean类型:
boolean数值类型:
整数值类型int,short,long,byte,char
浮点值类型:
float,double
Web部分
引用类型:
类、接口、数组类型。
及空类型(null)。
引用类型就是对一个对象的引用,对象包括实例和数组两种,实际上,引用类型变量就是一个指针,只是java不使用指针这个说法。
编译型语言和解释型语言
编译型语言在运行前先把程序翻译成机器语言并保存下来,运行时直接执行;
解释型语言不保存机器语言代码,在运行时才逐条翻译成机器语言执行(边解释边执行)
Java如何实现跨平台性的
Java是典型的解释型语言,java首先由编译器生成字节码(bytecode).class文件,然后由jvm去执行字节码文件,不同的平台安装类型符合的jvm,然后由jvm执行class文件实现跨平台性
8代理和反向代理proxy
代理就是客户端不直接访问服务器,而是先访问代理服务器,代理服务器再访问目标服务器,并将结果打包返回给客户端
正向代理:
对服务器而言,代理服务器就是客户端,隐藏了真实的客户端,简单说,正向代理就是代理客户端vpn,http代理
反向代理:
对客户端而言,代理服务器就是目标服务器,隐藏了真实的目标服务器,简单说,反向代理就是代理服务器nginx反向代理,负载均衡,集群,vip等
9.数组
数组也是一种数据类型,是一种引用类型,一个数组只可以存一种数据类型,一旦初始化,长度不能变int[].定义数组时只是定义了一个引用变量,不能指定数组大小,还未分配内存空间,必须初始化后,分配内存空间才可使用。
初始化:
分配内存空间并赋值。
只要分配了内存就一定有初始值。
初始值可以为0或者空(null)。
初始值可以有系统自动分配,或者程序员指定初始值
初始化分为静态初始化和动态初始化
静态初始化:
初始化时由程序员指定每个数组元素的值,系统判断数组长度newObject[]{};
动态初始化:
初始化时程序员指定数组长度,由系统分配初始值newObject[2];
动态初始值:
整数类型(byte,int,short,long)0,浮点型(float,double)0.0,字符型(char)‘\u0000’,
Boolean型false,引用型(类,接口和数组)null
内存中的数组。
在创建引用型对象时,实际会创建一个引用变量和一个实际的对象,引用变量存在方法栈内存中,而实际的对象存在堆内存中。
方法执行时,每个方法都会建立自己的内存栈,在这个方法内定义的变量将会逐个放入到这块栈内存中,方法结束后,方法栈也销毁,所有在方法中定义的局部变量都时放在栈内存中的;而创建的对象是放在堆内存中,只有当一个对象没有任何引用变量指向他时,才会被销毁。
数组的引用变量存在栈内存,数组对象存在堆内存中
Java没有多维数组
Java.util.Arrays提供的常用方法
binarySearch(type[]a,typekey)二分查找法,使用二分法查找key在数组中的索引,前提是a数组已经按升序排列,如果不存在则返回负数
binarySearch(type[]a,intfromIndex,inttoIndex,intkey)只查找fromIndex到toIndex的数组元素
type[]copyOf(type[]original,intlength)数组复制,如果length大于原数组长度,则新数组的前length个元素就是原数组的元素,后面补充冲0、false或者null。
如果length小于原数组元素,则新数组就是原数组前length个元素
type[]copyOfRange(type[]original,intfrom,intto)只复制从from到to的元素
booleanequals(type[]a,type[]a2)两个数组长度相同而且数组元素一样则返回true
voidfill(type[]a,typeval)把数组a的元素都赋值为val
voidfill(type[]a,intfromIndex,inttoIndex,typeval)填充从fromIndex到toIndex索引的元素
voidsort(type[]a)对数组a进行排序
StringtoString(type[]a)将数组元素转换为一个字符串,多个数组元素用,和空格隔开
Java8增强了Arrays的功能,为Arrays类增加了一些工具方法,这些工具方法利用多cpu并行的能力来提高设置和排序的功能
voidparallelPrefix(array[],XxxBinarOperatorop)使用指定的计算公式计算得到的结果作为新的元素
voidsetAll使用指定的生成器为所有数组元素赋值
voidparallelSetAll增加了并行能力,可以利用多cpu并行来提高性能
parallelSort并行排序
10.变量
成员变量指的是在类里定义的变量,
包括实例变量和类变量,类变量就是用static修饰的变量,实例变量就是没有用static修饰的变量。
区别:
生命周期不一样,类变量从该类的准备阶段起开始存在,与类的生命周期相同。
实例变量从该实例被创建开始存在,到该实例被销毁。
局部变量是在方法或代码块里定义的变量
成员变量无需显示的初始化,系统会在类准备阶段或者创建该实例时分配内存空间,进行默认初始化,0,false、null
局部变量定义后,必须显示的初始化,系统不会为局部变量执行初始化
11.对象
对象的创建
对象的创建有点类似数组,例如Personp=newPerson();实际创建了两个,一个是p引用变量,一个是Person对象,引用p被放在本地方法栈里,而对象person则被放在堆内存里,p存放的事person对象的地址,指向堆中的该对象。
。
生命周期:
引用变量在方法结束后就销毁,对象只有当没有任何引用变量指向该堆内存里的对象时垃圾回收机制负责销毁,因此如果希望垃圾回收机制销毁某个对象,只需将所有指向该对象的引用变量赋值为null即可
静态方法不能访问非静态成员方法或变量
12.方法
1)方法必须依赖类或实例,
2)方法的参数传递机制是值传递,就是将实际参数值的副本传入方法内,而参数本身不受影响。
对于引用类型的参数,传递的是引用,本质还是对同一个对象的改变
3)对于形参可变的方法,个数可变形参必须放到最后一个参数,所以一个方法中最多只有一个可变形参。
4)重载。
相同的类,相同的方法名,不同的参数列表(参数个数不同或者参数类型不同。
返回值或者修饰符必须相同,否则报编译错误
5)重写。
子类重写父类的方法,方法名、返回值、参数列表必须完全相同(返回值可以是父类返回值的子类,参数如果是子类,就是重载)
重写不能使用比被重写方法更严格的访问权限
重写方法不能抛出更大范围的异常类型
重写实现了运行时多态,重载实现了编译时多态,静态方法编译器不提供主动重写,但是重写方法编译器不报错,但是不支持多态。
13.面向对象
类修饰符:
publicfinalabstract,如果省略public,则默认是包访问权限。
1)默认访问控制符时default,包访问权限的。
2)关于instanceof判断对象是否是一个类或者其制子类的实例
前提:
前面的obj所属的类和后面的类有前后继承关系,否则报编译错误,而当obj所属的类是后面的类及其子类的时返回true,否则返回false。
3)java类中的五种成员:
成员变量、方法、构造器、静态代码块、内部类(接口和枚举)
4)通过实例访问静态方法时,实际也是类在访问静态方法,举例:
声明某个实例为空对象,调用类方法,编译运行正常
NullPointException。
一个null对象访问实例成员会引发的异常
5)对于static,静态的类成员,包含类方法,静态代码块,内部类和枚举类,不能访问实例成员。
6)构造器
a.Java类必须包含一个以上的
构造器。
b.一旦程序员提供了自定义的构造器,系统就不再提供默认构造器
c.子类集成父类时,默认调用父类的无参构造器,子类最少要调用一次父类构造器,如果父d.类没有无参构造器,子类必须显示制定父类构造器,否则报编译错误
e.This.super等必须放在构造体的第一行且不能同时存在
f.构造器不能被继承
g.系统查找成员变量的顺序:
方法局部变量-本类成员变量-直接父类变量···依次往上追溯,直到java.lang.Object
h.构造器执行顺序调用子类构造器之前必然会先调用父类构造器一次,所以,创建任何java对象,最先执行的总是object类的构造器
i.子类创建对象时,系统将同时为从父类继承的所有实例变量分配内存
7)多态
编译时类型与运行时类型不一样称为多态。
成员变量没有多态
初始化块总是比构造器先执行,或者放在构造器的最前面。
前提:
编译时必须存在的方法
引用类型强制转换,如果没有任何继承关系的类型无法进行转换,编译错误。
继承时is,组合是has
14.数据类型包装类
IntInteger
longLong
shortShort
floatFloat
doubleDouble
byteByte
charcharacter
booleanBoolean
包装类型的变量是引用类型的变量,但是包装类的实例可以与数值类型的值进行比较。
包装类引用之间的比较是比较是否指向一个对象,如果是则相等。
但是有一种情况,自动装箱Integer在-128-127范围内采用缓存数组,在该范围内的自动装箱时同一个数组下表元素,所以相等。
15.java的常用包
Java的核心类都放在java包及其子包下,java扩展的许多类都放在javax包及其子包下。
几个常用的包如下
Java.lang这个包包含了java语言的核心类,String,Math,System,Thread等,无需import导入,系统会自动导入这个包下的所有类
Java.util包含了java的大量工具类和集合框架类
Java.io
J
Java.text
Java.sql
16.String
直接使用字符串常量”hello”和newString(“hello”)的区别
首先,jdk1.8将String常量池从方法区中的运行时常量池分离到堆中了,String常量池中存放的是String对象,由String类维护。
使用直接量时,如果字符串常量池中已经存在该字符串,则直接返回引用,不创建新对象,否则在常量池中新增string对象,并返回;newString(”hello”)时,因为”hello”是直接量,所以会先在常量池中创建对象,然后在堆中创建String对象。
常量池(constantpool)专门用于管理在编译时被确定并保存在已编译的.class文件中的一些数据,它包括了关于类,方法、接口中的常量,还包括字符串常量
Jvm常量池保证相同的字符串直接量只有一个,不会产生多个副本
Java会使用常量池来管理曾经使用过的字符串直接量,比如执行Stringa=”java”,语句之后,常量池中就会缓存一个字符串java,如果程序再次执行Stringb=”java”,系统会让b直接指向常量池中的java字符串,因此b==a将会返回true
Intern方法,如果常量池中存在相同字符串的对象,则返回常量池中的对象,否则返回本对象引用
String和八大包装类都时不可变类。
为什么要设计成不可变类:
immutable,
成员变量设计成private,final来修饰,构造函数进行初始化,如果是引用变量,在内部不应该不改变其值,外部也不能修改值。
应该重写equals和hashcode,引用变量返回时应该返回新的对象的引用
17抽象类和抽象方法
1)用abstract修饰,有抽象方法只能被定义成抽象类,
2)抽象类可以不包含抽象方法。
抽象方法不能拥有方法体。
3)抽象类不能被实例化,抽象类的构造器不能用于创建实例,主要用于子类调用
4)抽象类的子类,如果没有全部实现父类包含的抽象方法,或者没有全部实现接口包含的抽象方法,只能定义成抽象类
5)抽象类只能被继承,而final类不能被继承,抽象方法必须由子类实现,而final方法子类不能重写,final和abstract是互斥的,不能同时修饰。
6)abstract不能修饰成员变量,和局部变量,不能修饰构造器
7)abstract和static不能同时修饰方法,,但是可以用来修饰内部类。
Abstract不能和private同时修饰方法
8)抽象类体现了模板模式的设计。
即编写一个父类,父类提供了多个子类的通用方法,并把一个或多个方法留给子类实现,这就是模板模式
19接口
1)接口是一组公共行为规范。
Jdk1.8以后提供有默认方法可以有方法实现,其他方法不能有实现。
Jdk8以后可以定义类方法、默认方法、内部类。
2)变量:
publicfinalstatic可以定义变量,会自动加上final和static,必须在声明的时候初始化,没有构造器和初始化块
3)普通方法:
publicabstract会自动加上且只能是publicabstract,类方法和默认方法必须实现。
4)内部类、接口、枚举自动使用publicstatic
5)默认方法publicdefault,不能加static,只能要接口的实现类的实例调用
6)类方法:
publicstatic,不能加static,直接接口调用。
7)接口用途:
定义变量;
调用接口中定义的常量
被其他类实现
为java只能单继承做的补充
8)一个类实现了一个或多个接口,必须全部实现接口所定义的所有抽象方法,否则必须定义成抽象类。
实现类的实现方法只能是public,因为接口的只能是public
9)接口和抽象类的区别。
接口是一种公共行为规范,体现的是规范和实现分离的哲学,定义了一系列继承者必须实现的方法,规定了实现者必须向外提供的方法,当在一个程序中使用接口时,接口是多个模块间的耦合标准,当在多个程序之间使用接口时,接口时多个程序之间的通信标准
抽象类时多个子类的共同父类,
接口只能包含抽象方法,静态方法,默认方法,抽象类则没有限制
接口只能定义静态常量;
接口不包含构造器和初始化块
子类可以实现多个接口,只能继承一个抽象类
10)面向接口编程
规范和实现分离,降低程序间的耦合。
提高可扩展型和可维护性
简单工厂模式:
接口对象由工厂类创建,降低耦合。
命令模式:
某个方法需要完成某一行为,但是具体的行为无法确定,比如对一个数组做遍历,但是遍历的处理逻辑还没想好,或者是可变的,怎么办?
可以定义一个接口,接口定义一个队数组元素的处理方法,在调用的时候把接口对象也传过去,接口对象对需要遍历的数组做逻辑处理
19内部类
1)非静态内部类对象必须寄生在外部类对象中,也就是创建非静态内部类之前必须先创建外部类,而外部类对象可以不创建内部类对象,有内部类就一定有外部类
2)内部类成员可以直接访问外部类的私有数据,但是外部类不能访问内部类的成员
3)匿名内部类适合创建仅需要使用一次的类,比如命令模式需要传入的command对象专门定义两个实现类意义不大因为可能仅需要使用一次,这种情况下使用匿名类更方便。
4)内部类比外部类可以多使用三个修饰符:
private,protected,static
5)非静态内部类不能拥有静态成员
6)静态内部类不可以访问外部类非静态成员,可以包含静态成员和非静态成员
7)在外部类以外地方创建内部类对象。
OutClass.InnerClassp=newOutClass().newInnerClass();
8)非静态内部类的构造器必须由外部类对象调用,所以,在继承非静态内部类时,必须传入一个外部类对象才能调用内部类的构造器。
9)静态内部类用法简单,不需要先先创建外部类,外部类有点像包空间,InnerClassa=newOutClass.InnerClass();当程序需要使用内部类时,应该优先考虑使用静态内部类
10)内部类可以被继承,但是不能被重写,因为外部类类名作为命名空间,而子类名不同。
11)局部内部类定义在方法中,不能用static和访问修饰符修饰,派生只能在方法内。
12)匿名内部类,局部内部类访问的局部变量必须用final修饰,jdk1.8取消了这个限制,但在被局部和匿名内部类使用时仍然按照final变量使用。
20枚举类
JDK1.5增加了switch对枚举类型的支持jdk1.7增加了对string类型的支持
EnumpublicenumenumName继承了java.lang.enum,而不是你object,默认用final修饰,不能派生,枚举构造器默认private,只能private,枚举实例publicstaticfinal,
枚举类的方法:
compareTo,name,toString,ordinal,values,valueof
枚举类的实例只能是枚举值
枚举类应该是不可变类,所以成员变量应该是privatefinal,实例应该是publicfinalstatic
枚举类可以实现接口,如果不同枚举类的实例想要对抽象方法分别有不同的实现,那么就有了抽象枚举类的概念,此时,枚举类不会用final修饰,而是默认abstract修饰,实例采用匿名内部类的方式实现抽象方法
同时,可以在枚举类红直接定义抽象方法,此时也是抽象枚举类,在初始化实例时必须实现抽象方法
21各jdk版本有哪些重大升级
22垃圾回收机制
1)垃圾回收机制只负责回收堆内存中的对象,不会回收任何物理资源(如数据库连接,网络io等)
2)程序无法精确控制垃圾回收的运行,垃圾回收会在合适的时候进行,当对象永久性失去引用后,系统就会在合适的时候回收它所占的内存
3)在垃圾回收机制回收任何对象之前,总会先调用对象的finalize方法,该方法可能使该对象重新复活(让一个引用变量重新引用该对象),从而导致垃圾回收机制取消回收,
4)对象在堆中的状态:
可达状态,可恢复状态,不可达状态,一个对象