java学习
2019-05-07 09:25:37 0 举报
AI智能生成
java学习总结
作者其他创作
大纲/内容
语法
序列化
通过反射API可以获取程序在运行时刻的内部结构
使用序列化实现对象的拷贝
注解
文件
jdbc
查询
Statement
通用查询
PreparedStatement
执行参数化查询
CallableStatement
是用于存储过程
基本数据类型
整型
long(8个字节)
short(2个字节)
int(4个字节)
byte(1个字节)
浮点类型
float(4个字节)
double(8个字节)
char类型(2个字节)
boolean类型
内存中的存储
大小端存储
大端模式
数据的高字节保存在内存的低地址中,数据的低字节保存在内存的高地址中
小端模式
数据的高字节保存在内存的高地址中,数据的低字节保存在内存的低地址中
整型存储
以二进制补码形式存储
short存储为例子
short i=3; 存储形式0000 0000 0000 0011//0003
符号位:0为正数,1为负数
正数原码、反码、补码相同,负数反码除符号位外其他位取反,补码是原码取反后+1
浮点类型存储
整数部分转化为二进制,小数部分转化为二进制,然后整数部分与小数部分相加,float数值指数位+127,double数值指数位+1023
以20.5为例
20转化为二进制:10100
0.5转化为二进制:1
指数形式:1.01001E100 ;指数位加上127
存储形式: 0-10000011-01001 00000 00000 00000 000
float符号位(1位)+指数位(8位)+尾数位(23位)
double符号位(1位)+指数位(8位)+尾数位(52位)
关键字
static
被static修饰的成员变量和成员方法是独立于该类的,在类加载时就会被初始化,它不依赖于某个特定的实例变量,也就是说它被该类的所有实例共享。所有实例的引用都指向同一个地方,任何一个实例对其的修改都会导致其他实例的变化
作用对象
成员变量
static修饰的静态变量
在类加载时初始化完成
在内存中只有一个,JVM尽分配一次内存
所有实例共享静态变量,可以通过类名直接访问
实例变量
与实例同生共死
方法
不依赖任何实例,
代码块
局限
只能调用static变量
只能调用static方法
不能以任何形式引用this,super
static变量在定义时必须要进行初始化,且初始化时间要早于非静态变量
final
表示被final修饰的部分是不能给改变的
不想被改变的原因
效率
设计
使用final的三种情况
数据
目的:定义常量,能够减轻系统运行时的负担
作用地方
编译期常量,在类加载时已经完成初始化,所以永远不可改变
作为编译期常量,在编译期执行计算式
只能是基本数据类型,必须在定义时进行初始化
运行期初始化,不希望被改变
基本数据类型:不可变的是其内容
引用数据类型:是其引用不可变,引用指向的对象内容是可变的
方法
所有被final标注的方法都是不能被继承、更改的,所以对于final方法使用的第一个原因就是方法锁定,以防止任何子类来对它的修改
类
如果某个类用final修改,表明该类是最终类,它不希望也不允许其他来继承它。在程序设计中处于安全或者其他原因,我们不允许该类存在任何变化,也不希望它有子类,这个时候就可以使用final来修饰该类了
参数
参数被final修饰了,则代表了该参数是不可改变的
字符串
特性
string对象是不可变的,string类中每一个修改字符串的方法其实都是返回一个全新的string对象
创建string对象的方式
String string = new String(ok“”)
首先会在堆内存申请一块内存存储字符串ok,ok1指向其内存块对象。同时还会检查字符串常量池中是否含有ok字符串,若没有则添加ok到字符串常量池中。所以 new String()可能会创建两个对象
String string = “ok”
先检查字符串常量池中是否含有ok字符串,如果有则直接指向, 没有则在字符串常量池添加ok字符串并指向它.所以这种方法最多创建一个对象,有可能不创建对象
判断相等
==
比较类中的数值是否相等使用equals(),
比较类中的数值是否相等使用equals(),
equal
比较两个包装类的引用是否指向同一个对象时用==
equal
比较两个包装类的引用是否指向同一个对象时用==
Intern()方法
intern()是扩充常量池的一个方法,当一个String实例str调用intern()方法时,java会检查常量池中是否有相同的字符串,如果有则返回其引用,如果没有则在常量池中增加一个str字符串并返回它的引用
String常用方法
检查序列的单个字符
比较字符串
搜索字符串
提取子字符串
创建字符串副本
将所有字符全部转换为大写或小写
Java 语言提供对字符串串联符号("+")以及将其他对象转换为字符串的特殊支持
字符串串联是通过
StringBuilder
(或 StringBuffer
)类及其 append
方法实现的 字符串转换是通过 toString 方法实现的,该方法由 Object 类定义,并可被 Java 中的所有类继承
数组
定义
数组是一个简单的复合数据类型,它是一系列有序数据的集合,它当中的每一个数据都具有相同的数据类型
数组是一个特殊的对象
[代表了数组的维度,一个[表示一维两个[表示二维可以简单的说数组的类名由若干个'['和数组元素类型的内部名称组成
数组使用
声明数组、分配空间、赋值、处理
与其他容器的区别
效率、类型和保存基本类型的能力
数组是一种效率最高的存储和随机访问对象引用序列的方式
特点
数组是定长的,一旦初始化声明后是不可改变长度的
可以给其扩容
Arrays.copyOf()创建数组副本的同时将数组长度增加就变通的实现了数组的扩容
泛型
“参数化类型”
就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。
在定义时不确定类型,编译时根据具体的类型确定
根据传入的类型,泛华到不同的类型,本质上是同一个类的实例,但是泛化后,代表不同的对象
实例化时的传参
在使用泛型的时候如果传入泛型实参,则会根据传入的泛型实参做相应的限制,此时泛型才会起到本应起到的限制作用。如果不传入泛型类型实参的话,在泛型类中使用泛型的方法或成员变量定义的类型可以为任何的类型。
泛型的类型参数只能是类类型,不能是简单类型。
不能对确切的泛型类型使用instanceof操作。如下面的操作是非法的,编译时会出错
不能对确切的泛型类型使用instanceof操作。如下面的操作是非法的,编译时会出错
泛型接口
泛型接口定义
//定义一个泛型接口
public interface Generator<T> {
public T next();
}
public interface Generator<T> {
public T next();
}
泛型接口实现
未传入泛型实参
未传入泛型实参时,与泛型类的定义相同,在声明类的时候,需将泛型的声明也一起加到类中
传入泛型实参
在实现类实现泛型接口时,如已将泛型类型传入实参类型,则所有使用泛型的地方都要替换成传入的实参类型
类型通配符
? ;当操作类型时,不需要使用类型的具体功能时,只使用Object类中的功能。那么可以用 ? 通配符来表未知类型。
是类型实参,而不是类型形参
代表传入的某一个具体的类型,比如说:Integer, String等
泛型方法
与泛型类的概念区别
是调用泛型方法的时候确定具体的泛型类型
泛型类是在实例化泛型类的时候,志明具体的泛型类型
泛型方法的声明
子主题
1、public 与 返回值中间<T>非常重要,可以理解为声明此方法为泛型方法。
2、只有声明了<T>的方法才是泛型方法,泛型类中的使用了泛型的成员方法并不是泛型方法。
3、<T>表明该方法将使用泛型类型T,此时才可以在方法中使用泛型类型T。
4、与泛型类的定义一样,此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型
2、只有声明了<T>的方法才是泛型方法,泛型类中的使用了泛型的成员方法并不是泛型方法。
3、<T>表明该方法将使用泛型类型T,此时才可以在方法中使用泛型类型T。
4、与泛型类的定义一样,此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型
泛型指定边界
反射
代理
静态代理
通过手动编写代理类,代理关系在编译时就已确定
动态代理
在运行时动态生成代理类
java自身的动态代理实现
InvocationHandler
需手动实现一个处理类,作为代理类的的关联handler
这个handler中的invoke方法是实质调用委托对象方法,需传入委托对象和要调用方法所需参数
Proxy
代理类,用于生成代理对象,在程序运行时创建
如何通过代理类实现代理对象,利用代理对象调用真实对象的方法??
创建实例
Proxy.newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
Class<?>[] interfaces,
InvocationHandler h)
第一个参数:指定的类加载器
要实现的接口,是接口数组,通过Class.getInterfaces()获取
指定处理器(前面自己实现的)
真实方法调用
Subject realSubject = new RealSubject();
InvocationHandler handler = new DynamicProxy();
Subject subject = (Subject) Proxy.newProxyInstance(handler.getClass().getClassLoader(),
realSubject.getClass().getInterfaces(), handler);
subject.rent();
subject.hello("zhouyajun");
InvocationHandler handler = new DynamicProxy();
Subject subject = (Subject) Proxy.newProxyInstance(handler.getClass().getClassLoader(),
realSubject.getClass().getInterfaces(), handler);
subject.rent();
subject.hello("zhouyajun");
cglib动态代理实现
JDK动态代理所用到的代理类在程序调用到代理类对象时才由JVM真正创建,JVM根据传进来的 业务实现类对象 以及 方法名 ,动态地创建了一个代理类的class文件并被字节码引擎执行,然后通过该代理类对象进行方法调用
什么是代理?
一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问。代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理
类对象(Class)
Class类
Class类是在java源码中存在的实实在在的类,与class关键字是不一样的
Class类被创建后的对象就是Class对象,注意,Class对象表示的是自己手动编写类的类型信息
JVM再根据这个类型信息相关的Class对象创建我们需要实例对象或者提供静态变量的引用值
无论我们手动创建的实例有多少个,其对应的Class对象在jvm的堆中只有一个
Class对象的加载原理
当创建第一个静态成员引用时,加载这个被使用的类
字节码.class文件
通过类加载器实现
classloader
通过Class.getClassLoader()获取某各类的类加载器
在动态加载某各类时也可以指定类加载器-在动态代理中,利用Proxy实现代理对象时,Proxy.newProxyInstance的第一个参数需要指定代理类的类加载器
加载时会对.class文件进行验证
加载完成后,根据Class对象找到对应的类,然后进行实例化
Class.forName方法
调用forName方法获取Class对象将会导致类被加载
使用字面常量的方式获取Class对象的引用不会触发类的初始化
按照不同构造函数构造的实例对应该类的Class对象是否只有一个??是的
基础
获取Class对象
使用Class类的forName静态方法:
直接获取某一个对象的class
调用某个对象的getClass()方法
class实例化
使用Class对象的newInstance()方法来创建Class对象对应类的实例
先通过Class对象获取指定的Constructor对象,再调用Constructor对象的newInstance()方法来创建实例。这种方法可以用指定的构造器构造类的实例
获取构造器-Constructor对象
子主题
获取方法-返回的是一个方法数组
getDeclaredMethods()方法返回类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。
getMethods()方法返回某个类的所有公用(public)方法,包括其继承类的公用方法。
getMethod方法返回一个特定的方法,其中第一个参数为方法名称,后面的参数为方法的参数对应Class的对象
获取成员变量
getDeclaredField:所有已声明的成员变量。但不能得到其父类的成员变量
getFiled: 访问公有的成员变量
继承
定义
继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力。
父类
Java中不需要将方法声明为虚拟方法
子类
默认公有继承
子类构造器
super调用父类的方法
不支持多继承
多态
多态是同一个行为具有多个不同表现形式或形态的能力
静态绑定(编译时)
重载
它是根据参数列表的不同来区分不同的函数,通过编辑之后会变成两个不同的函数
动态绑定(运行)
继承
重写
重写
子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法。
向上转型
在多态中需要将子类的引用赋给父类对象,只有这样该引用才能够具备技能调用父类的方法和子类的方法。
抽象类
定义
使用了关键词abstract声明的类叫作“抽象类”。如果一个类里包含了一个或多个抽象方法,类就必须指定成abstract(抽象)。“抽象方法”,属于一种不完整的方法,只含有一个声明,没有方法主体。
特征
抽象类体现了数据抽象的思想,是实现多态的一种机制
不能被实例化,只能有引用,实例化应该由子类实现
它定义了一组抽象的方法,至于这组抽象方法的具体表现形式有派生类来实现
只要包含一个抽象方法的抽象类,该方法必须要定义成抽象类,不管是否还包含有其他方法
抽象类中可以包含具体的方法,当然也可以不包含抽象方法
子类中的抽象方法不能与父类的抽象方法同名
抽象方法必须由子类来进行重写
abstract不能与final并列修饰同一个类
abstract 不能与private、static、final或native并列修饰同一个方法
extends 进行继承
object(所有类的超类)
方法
String toString()
当打印引用,如调用System.out.println()时,会自动调用对象的toString()方法,打印出引用所指的对象的toString()方法的返回值,
boolean equals(Object obj)
定义
判断调用equals()方法的引用于传进来的引用是否一致,即这两个引用是否指向的是同一个对象。
特征
自反性:任何非空引用x,x.equals(x)返回为true
对称性:任何非空引用x和y,x.equals(y)返回true当且仅当y.equals(x)返回true
传递性:任何非空引用x和y,如果x.equals(y)返回true,并且y.equals(z)返回true,那么x.equals(z)返回true
一致性:两个非空引用x和y,x.equals(y)的多次调用应该保持一致的结果
约定:对于任何非空引用x,x.equals(null)应该返回为false。
int hashCode()
定义
散列码是由对象导出的一个整型值
约定
在Java应用程序程序执行期间,对于同一对象多次调用hashCode()方法时,其返回的哈希码是相同的,前提是将对象进行equals比较时所用的标尺信息未做修改
如果两个对象相等(依据:调用equals()方法),那么这两个对象调用hashCode()返回的哈希码也必须相等
两个对象调用hasCode()返回的哈希码相等,这两个对象不一定相等。
泛型数组列表
对象包装器与自动装箱
参数数量可变的方法
接口
定义
接口(Interface)是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现
特点
Java接口中的成员变量默认都是public,static,final类型的(都可省略),必须被显示初始化,即接口中的成员变量为常量(大写,单词之间用"_"分隔)
Java接口中的方法默认都是public,abstract类型的(都可省略),没有方法体,不能被实例化
Java接口中只能包含public,static,final类型的成员变量和public,abstract类型的成员方法
接口中没有构造方法,不能被实例化
一个接口不能实现(implements)另一个接口,但它可以继承多个其它的接口
Java接口必须通过类来实现它的抽象方法
当类实现了某个Java接口时,它必须实现接口中的所有抽象方法,否则这个类必须声明为抽象类
不允许创建接口的实例(实例化),但允许定义接口类型的引用变量,该引用变量引用实现了这个接口的类的实例
一个类只能继承一个直接的父类,但可以实现多个接口,间接的实现了多继承.
对象克隆
异常
定义
异常就是有异于常态,和正常情况不一样,有错误出错。在java中,阻止当前方法或作用域的情况,称之为异常。
分类
Throwable类
Error类
虚拟机异常
线程死锁
Exception类
RuntimeException异常(非检查异常)
空指针异常
数组下标越界异常
类型转换异常
算术异常
检查异常
文件异常
SQL异常
throws与throw关键字
throws出现在方法函数头,声明将要抛出何种类型的异常(声明)。;而throw出现在函数体
throws表示出现异常的一种可能性,并不一定会发生这些异常;throw则是抛出了异常,执行throw则一定抛出了某种异常对象。
两者都是消极处理异常的方式(这里的消极并不是说这种方式不好),只是抛出或者可能抛出异常,但是不会由函数去处理异常,真正的处理异常由函数的上层调用处理
捕获异常
面向对象
面向对象设计原则
单一职责原则
含义
一个类只负责一个功能领域的职责,引起类变化的原因只有一个
作用
用于控制类的粒度大小
开闭原则
含义
软件实体尽量在不修改源代码的情况下,实现扩展
软件实体可以是一个软件模块、由几个类组成的局部模块、一个独立的类
抽象化是关键,利用编程语言提供的抽象层接口,定义抽象业务
作用
使软件具有良好的扩展性
里氏代换原则
含义
所有引用基类(父类)的地方,必须透明的可以使用其子类对象
注意事项
子类必须实现父类中声明的所有方法
尽量把父类设计成抽象类或者接口
作用
程序员:使用基类定义对象,JVM:在运行时确定子类对象,并对其进行替换
依赖倒转原则
含义
抽象不应该依赖于细节,细节应当依赖于抽象,也就是应当依赖接口编程,而不是针对实现
注意事项
传递参数时或者关联关系时,尽量引用层次高的抽象层
使用接口或抽象类进行变量的声明、参数类型的声明、方法返回类型的声明
以及数据类型的转换,不要用具体的类做这些
一个具体的类应当只实现接口或抽象类中声明的方法
具体类的对象通过依赖注入的方式注入到其他对象中
依赖注入
当一个对象要与另一个对象发生关系时,通过抽象来注入到其他对象
依赖注入方式
构造注入
通过构造函数来传入具体类的对象
设值注入
通过setter方法来出入具体类的对象
接口注入
在接口中声明的业务方法来传入具体类的对象
作用
接口隔离原则
含义
使用多个专门的接口,而不使用单一的总接口,即客户端不应该使用那些他不依赖的接口
合成复用原则
含义
尽量使用对象组合,而不是继承达到复用代码的目的
关联关系
组合关系
聚合关系
继承会破坏系统的封装性
迪米特法则
一个软件实体应当尽可能少的和其他实体发生关系
对象相关的职责
对象本身所具有的的职责
对象自身所具有的一些数据和行为,可通过一些公开的方法来实现它的职责
创建对象的职责
和使用对象的职责
创建对象的方式
new关键字直接创建对象
通过反射机制创建对象
通过clone方法创建对象
通过工厂类创建对象
Java反射机制
是指在程序运行时获取已知名称的类或已有对象的相关信息的一种机制
包括类的方法、属性、父类等信息,还包括实例的创建和实例类型的判断等
在反射机制中使用最多的类是Class,Class类的实例表示正在运行的Java应用程序中的类和接口
forName(String className)返回与带有给定字符串名的类或接口相关联的Class对象
Class对象的newInstance()方法创建此对象所表示的一个心实例
java.lang.reflect
抽象
抽象类
定义
如果一个类没有足够的信息来描述一个具体的对象,而需要其他具体的类来支撑它,那么这样的类我们称它为抽象类
在面向对象领域由于抽象的概念在问题领域没有对应的具体概念,所以用以表征抽象概念的抽象类是不能实例化的。
抽象类体现了数据抽象的思想,是实现多态的一种机制
用法
抽象类不能被实例化,实例化的工作交由它的子类完成,只需要一个引用即可
抽象方法必须由子类进行重写
只要包含一个抽象方法的抽象类,该方法必须定义成抽象类,不管是否包含其他方法
抽象类中可以包含具体的方法,也可以不包含抽象方法
子类中的抽象方法不能与父类中的抽象方法重名
abstract不能与final并列修饰同一个类
abstract不能与private,static,final,native并列修饰一个方法
接口
定义
接口是用来建立类与类之间的协议,提供这一种形式,而没有具体的实现
接口是抽象类的延伸
使用
一个interface的方法只能为public
接口中可以定义成员变量,或者是不可变的常量,接口的成员变量会自动变为public static final,直接通过类名访问
接口中不存在实现的方法
实现接口的非抽象类必须要实现该接口的所有方法,抽象类不用
接口只能创建引用,不能被实例化
在实现多接口的时候,避免方法名的重复
抽象类和接口的区别
语法层次
抽象类
抽象类方式中,抽象类可以拥有任意范围的成员数据,同时也可以拥有自己的非抽象方法
接口
接口方式中,它仅能够有静态、不能修改的成员数据(但是我们一般是不会在接口中使用成员数据),同时它所有的方法都必须是抽象的。在某种程度上来说,接口是抽象类的特殊化
设计层次
抽象层次不同
抽象类是对整个类整体进行抽象,包括属性、行为
接口是对行为进行抽象
跨域不同
抽象类所跨域具有相似特点的类,抽象类是从子类中发现公关部分,然后泛华成抽象类,子类继承父类即可
接口可以跨域不同的类,实现他的子类可以不存在任何关系
设计层次不同
抽象类,是自下而上来设计的,先知道子类才能抽象出父类
接口根本不需要知道子类的存在,只需要定义一个规则,是从上而下的设计,至于什么子类、何时实现不用管
总结
抽象类在Java语言中所表示的是一种继承关系,一个子类只能存在一个父类,但是可以存在多个接口
设计理念的不同,抽象类所代表的是is-a的关系,接口代表的是like-a的关系
访问修饰符
public
protected
friendly
private
多态
什么是多态
父类型引用指向子类对象,在程序运行时才能确定指向的是具体的哪一个对象
指向子类的父类引用由于向上转型了,它只能访问父类中拥有的方法和属性,而对于子类中存在而父类中不存在的方法,该引用是不能使用的,尽管是重载该方法。若子类重写了父类中的某些方法,在调用该些方法的时候,必定是使用子类中定义的这些方法(动态连接、动态调用)
向上转型
多态类型
编译时多态
运行时多态
多态的实现条件
继承
重写
向上转型
实现的形式
接口
继承
内部类
作用
内部类可以用多个实例,每个实例都有自己的状态信息,并且与其他外围对象的信息相互独立
在单个外围类中,可以让多个内部类以不同的方式实现同一个接口,或者继承同一个类
创建内部类对象的时刻并不依赖于外围类对象的创建
内部类并没有令人迷惑的“is-a”关系,他就是一个独立的实体
内部类提供了更好的封装,除了该外围类,其他类都不能访问
与外围类的交互
分类
成员内部类
局部内部类
匿名内部类
静态内部类
类的唯一标识
全限定路径名+类名
0 条评论
下一页