JAVA基础
JAVA基础思维导图
面向对象三大特性封装
把一个对象的属性,和行为放到同一个类中就是封装继承
子类可以获得父类的属性和操作。
在java中常表示为isa的关系多态
是指一个事物,多种状态
比如一个动物可以是猫,狗
一个方法,可以有无参,1个参数,2个参数
也可使同一个方法,不同的表现编译时多态
主要值方法的重载运行时多态
继承重写向上转型类图
泛化实现聚合关联依赖知识点
数据类型String不可变的好处1。可以缓存hash值
因为String的hash值经常被使用,例如String用做HashMap的key。不可变的特性可以使得hash值也不可变,因此只需要进行一次计算。2。StringPool的需要
如果一个String对象已经被创建过了,那么就会从StringPool中取得引用。只有String是不可变的,才可能使用StringPool。3。安全性
String经常作为参数,String不可变性可以保证参数不可变。例如在作为网络连接参数的情况下如果String是可变的,那么在网络连接过程中,String被改变,改变String对象的那一方以为现在连接的是其它主机,而实际情况却不一定是。4。线程安全
String不可变性天生具备线程安全,可以在多个线程中安全地使用。String,StringBuffer
andStringBuilder1。可变性String不可变
主要是因为string受到了final的修饰另外两个可变
基于动态数组,
基础长度16也就是需要扩容时,它会new一个新数组,长度为原来的2倍2。线程安全
String,StringBuffer线程安全StringBuilder线程不安全String。intern()运算继承Object通用方法关键字泛型机制详解注解基础
java内置注解元注解注解与反射接口自定义注解深入理解注解
java8提供了那些新的注解注解支持继承吗?注解实现的原理注解的应用场景
配置化到注解化框架的演进继承实现到注解实现Junit3到junit4自定义注解和AOP通过切面实现解耦异常机制详解反射机制详解
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。Java反射机制在框架设计中极为广泛,需要深入理解。反射基础
反射就是把java类中的各种成分映射成一个个java对象
例如:一个类有:成员变量、方法、构造方法、包等等信息,利用反射技术可以对一个类进行解剖,把个个组成部分映射成一个个对象。Class类
Class类,Class类也是一个实实在在的类,存在于JDK的java。lang包中。Class类的实例表示java应用运行时的类(classansenum)或接口(interfaceandannotation)(每个java类运行时都在JVM里表现为一个class对象,可通过类名。class、类型。getClass()、Class。forName(类名)等方法获取class对象)。数组同样也被映射为为class对象的一个类,所有具有相同元素类型和维数的数组都共享该Class对象。基本类型boolean,byte,char,short,int,long,float,double和关键字void同样表现为class对象。
Class类也是类的一种,与class关键字是不一样的。
手动编写的类被编译后会产生一个Class对象,其表示的是创建的类的类型信息,而且这个Class对象保存在同名。class的文件中(字节码文件)
每个通过关键字class标识的类,在内存中有且只有一个与之对应的Class对象来描述其类型信息,无论创建多少个实例对象,其依据的都是用一个Class对象。
Class类只存私有构造函数,因此对应Class对象只能有JVM创建和加载
Class类的对象作用是运行时提供或获得某个对象的类型信息,这点对于反射技术很重要(关于反射稍后分析)类加载类的加载机制流程
1。加载链接
2。连接3。初始化4。使用5。卸载类的加载
1。类编译2。类加载类的结构放在栈区类的实例放入堆区反射的使用
基于此我们如何通过反射获取Class类对象以及类中的成员变量、方法、构造方法等Class类对象的获取
在类加载的时候,jvm会创建一个class对象
class对象是可以说是反射中最常用的,获取class对象的方式的主要有三种
根据类名:类名。class
根据对象:对象。getClass()
根据全限定类名:Class。forName(全限定类名)
TestpublicvoidclassTest()throwsException{获取Class对象的三种方式logger。info(根据类名:User。class);logger。info(根据对象:newUser()。getClass());logger。info(根据全限定类名:Class。forName(com。test。User));常用的方法logger。info(获取全限定类名:userClass。getName());logger。info(获取类名:userClass。getSimpleName());logger。info(实例化:userClass。newInstance());}Class类的方法
forName()
(2)为了产生Class引用,forName()立即就进行了初始化。
ObjectgetClass()
getName()
getSimpleName()
getCanonicalName()
isInterface()
getInterfaces()
getSupercalss()
newInstance()
getFields()
getDeclaredFieldsgetName、getCanonicalName与getSimpleName的区别
getSimpleName:只获取类名
getName:类的全限定名,jvm中Class的表示,可以用于动态加载Class对象,例如Class。forName。
getCanonicalName:返回更容易理解的表示,主要用于输出(toString)或log打印,大多数情况下和getName一样,但是在内部类、数组等类型的表示形式就不同了。Constructor类及其用法Field类及其用法
Field提供有关类或接口的单个字段的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)字段或实例字段。
同样的道理,我们可以通过Class类的提供的方法来获取代表字段信息的Field对象,Class类与Field对象相关方法如下:
方法返回值方法名称方法说明
FieldgetDeclaredField(Stringname)获取指定name名称的(包含private修饰的)字段,不包括继承的字段
Field〔〕getDeclaredField()获取Class对象所表示的类或接口的所有(包含private修饰的)字段,不包括继承的字段
FieldgetField(Stringname)获取指定name名称、具有public修饰的字段,包含继承字段
Field〔〕getField()获取修饰符为public的字段,包含继承字段
voidset(Objectobj,Objectvalue)将指定对象变量上此Field对象表示的字段设置为指定的新值。
Objectget(Objectobj)返回指定对象上此Field表示的字段的值
ClassgetType()返回一个Class对象,它标识了此Field对象所表示字段的声明类型。
booleanisEnumConstant()如果此字段表示枚举类型的元素则返回true;否则返回false
StringtoGenericString()返回一个描述此Field(包括其一般类型)的字符串
StringgetName()返回此Field对象表示的字段的名称
ClassgetDeclaringClass()返回表示类或接口的Class对象,该类或接口声明由此
Field对象表示的字段
voidsetAccessible(booleanflag)将此对象的accessible标志设置为指示的布尔值,即设置其可访问性Method类及其用法
Method提供关于类或接口上单独某个方法(以及如何访问该方法)的信息,所反映的方法可能是类方法或实例方法(包括抽象方法)。
方法返回值方法名称方法说明
MethodgetDeclaredMethod返回一个指定参数的Method对象,Stringname,ClassparameterTypes)该对象反映此Class对象所表示的类或接口的指定已声明方法。
Method〔〕getDeclaredMethod()返回Method对象的一个数组,这些对象反映此Class对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。
MethodgetMethod返回一个Method对象,它反映此Class对(Stringname,ClassparameterTypes)象所表示的类或接口的指定公共成员方法。
Method〔〕getMethods()返回一个包含某些Method对象的数组,这些对象反映此Class对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共member方法。反射机制的执行流程
反射获取类实例反射获取方法调用method。invoke()方法反射调用流程小结
最后,用几句话总结反射的实现原理:1。反射类及反射方法的获取,都是通过从列表中搜寻查找匹配的方法,所以查找性能会随类的大小方法多少而变化;
2。每个类都会有一个与之对应的Class实例,从而每个类都可以获取method反射方法,并作用到其他实例身上;
3。反射也是考虑了线程安全的,放心使用;
4。反射使用软引用relectionData缓存class信息,避免每次重新从jvm获取带来的开销;
5。反射调用多次生成新代理Accessor,而通过字节码生存的则考虑了卸载功能,所以会使用独立的类加载器;
6。当找到需要的方法,都会copy一份出来,而不是使用原来的实例,从而保证数据隔离;
7。调度反射方法,最终是由jvm执行invoke0()执行;SPI机制详解什么是SPI机制
SPI(ServiceProviderInterface),是JDK内置的一种服务提供发现机制,可以用来启用框架扩展和替换组件,主要是被框架的开发人员使用,比如java。sql。Driver接口,其他不同厂商可以针对同一接口做出不同的实现,MySQL和PostgreSQL都有不同的实现提供给用户,而Java的SPI机制可以为某个接口寻找服务实现。Java中SPI机制主要思想是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要,其核心思想就是解耦。
当服务的提供者提供了一种接口的实现之后,需要在classpath下的METAINFservices目录里创建一个以服务接口命名的文件,这个文件里的内容就是这个接口的具体的实现类。当其他的程序需要这个服务的时候,就可以通过查找这个jar包(一般都是以jar包做依赖)的METAINFservices中的配置文件,配置文件中有接口的具体实现类名,可以根据这个类名进行加载实例化,就可以使用该服务了。JDK中查找服务的实现的工具类是:java。util。ServiceLoader。SPI机制的简单示例SPI机制的广泛应用JDBCDriverManager
在JDBC4。0之前,我们开发有连接数据库的时候,通常会用Class。forName(com。mysql。jdbc。Driver)这句先加载数据库相关的驱动,然后再进行获取连接等的操作。而JDBC4。0之后不需要用Class。forName(com。mysql。jdbc。Driver)来加载驱动,直接获取连接就可以了,现在这种方式就是使用了Java的SPI扩展机制来实现。1。JDBC接口定义
首先在java中定义了接口java。sql。Driver,并没有具体的实现,具体的实现都是由不同厂商来提供的。
2。mysql实现postgresql实现
在mysql的jar包mysqlconnectorjava6。0。6。jar中,可以找到METAINFservices目录,该目录下会有一个名字为java。sql。Driver的文件,文件内容是com。mysql。cj。jdbc。Driver,这里面的内容就是针对Java中定义的接口的实现。
同样在postgresql的jar包postgresql42。0。0。jar中,也可以找到同样的配置文件,文件内容是org。postgresql。Driver,这是postgresql对Java的java。sql。Driver的实现。
3。使用方法
上面说了,现在使用SPI扩展来加载具体的驱动,我们在Java中写连接数据库的代码的时候,不需要再使用Class。forName(com。mysql。jdbc。Driver)来加载驱动了,而是直接使用如下代码:
Stringurljdbc:xxxx:xxxx:xxxxxxxx;ConnectionconnDriverManager。getConnection(url,username,password);。。
原理:上面的使用方法,就是我们普通的连接数据库的代码,并没有涉及到SPI的东西,但是有一点我们可以确定的是,我们没有写有关具体驱动的硬编码Class。forName(com。mysql。jdbc。Driver)!
上面的代码可以直接获取数据库连接进行操作,但是跟SPI有啥关系呢?上面代码没有了加载驱动的代码,我们怎么去确定使用哪个数据库连接的驱动呢?这里就涉及到使用Java的SPI扩展机制来查找相关驱动的东西了,关于驱动的查找其实都在DriverManager中,DriverManager是Java中的实现,用来获取数据库连接
其中loadInitialDrivers的作用是:从系统变量中获取有关驱动的定义。使用SPI来获取驱动的实现。遍历使用SPI获取到的具体实现,实例化各个实现类。根据第一步获取到的驱动列表来实例化具体实现类。
首先调用driversIterator。hasNext()方法,这里会搜索classpath下以及jar包中所有的METAINFservices目录下的java。sql。Driver文件,并找到文件中的实现类的名字,此时并没有实例化具体的实现类(ServiceLoader具体的源码实现在下面)。然后是调用driversIterator。next();方法,此时就会根据驱动名字具体实例化各个实现类了。现在驱动就被找到并实例化了。
SPI机制CommonLoggingSPI机制插件体系
其实最具spi思想的应该属于插件开发,我们项目中也用到的这种思想,后面再说,这里具体说一下eclipse的插件思想。
Eclipse使用OSGi作为插件系统的基础,动态添加新插件和停止现有插件,以动态的方式管理组件生命周期。一般来说,插件的文件结构必须在指定目录下包含以下三个文件:
METAINFMANIFEST。MF:项目基本配置信息,版本、名称、启动器等build。properties:项目的编译配置信息,包括,源代码路径、输出路径plugin。xml:插件的操作配置信息,包含弹出菜单及点击菜单后对应的操作执行类等
当eclipse启动时,会遍历plugins文件夹中的目录,扫描每个插件的清单文件MANIFEST。MF,并建立一个内部模型来记录它所找到的每个插件的信息,就实现了动态添加新的插件。
这也意味着是eclipse制定了一系列的规则,像是文件结构、类型、参数等。插件开发者遵循这些规则去开发自己的插件,eclipse并不需要知道插件具体是怎样开发的,只需要在启动的时候根据配置文件解析、加载到系统里就好了,是spi思想的一种体现。SpI机制Spring中的SPI机制
在springboot的自动装配过程中,最终会加载METAINFspring。factories文件,而加载的过程是由SpringFactoriesLoader加载的。从CLASSPATH下的每个Jar包中搜寻所有METAINFspring。factories配置文件,然后将解析properties文件,找到指定名称的配置后返回。需要注意的是,其实这里不仅仅是会去ClassPath路径下查找,会扫描所有路径下的Jar包,只不过这个文件只会在Classpath下的jar包中。SPI机制深入理解SPI机制通常怎么使用
1。定义标准
定义标准,就是定义接口。比如接口java。sql。Driver
2。具体厂商或者框架开发者实现
厂商或者框架开发者开发具体的实现:在METAINFservices目录下定义一个名字为接口全限定名的文件,比如java。sql。Driver文件,文件内容是具体的实现名字,比如me。cxis。sql。MyDriver。写具体的实现me。cxis。sql。MyDriver,都是对接口Driver的实现。
3。程序猿使用
我们会引用具体厂商的jar包来实现我们的功能:
ServiceLoaderloadedDriversServiceLoader。load(Driver。class);获取迭代器IteratordriversIteratorloadedDrivers。iterator();遍历while(driversIterator。hasNext()){driversIterator。next();可以做具体的业务逻辑}SPI与API的区别
第一个SPI和API的区别?
SPI接口位于调用方所在的包中
概念上更依赖调用方。组织上位于调用方所在的包中。实现位于独立的包中。常见的例子是:插件模式的插件。API接口位于实现方所在的包中
概念上更接近实现方。组织上位于实现方所在的包中。实现和接口在一个包中。
第二个什么时候用API,什么时候用SPI?
SPI机制实现原理SPI机制的缺陷
1。不能按需加载,需要遍历所有的实现,并实例化,然后在循环中才能找到我们需要的实现。如果不想用某些实现类,或者某些类实例化很耗时,它也被载入并实例化了,这就造成了浪费。
2。获取某个实现类的方式不够灵活,只能通过Iterator形式获取,不能根据某个参数来获取对应的实现类。
3。多个并发多线程使用ServiceLoader类的实例是不安全的。
今夏想变帅的男生,试试这3款发型,剪完帅气显年轻哈喽,大家好,我是阿潮!男生想要变帅,先从发型入手,欢迎来到阿潮的男生发型分享频道相信对于有一点点追求时尚的男生来说,不仅穿衣得体,而且对自己的发型都有一定的要求;……
国内公认五大性价比最好护肤品曝光!建议看看有没有你正在用的国内公认五大性价比最好护肤品曝光!建议看看有没有你正在用的这几个我真是看着包装一般般但是实力是真牛掰便宜还好用对我来说已经够了就像那诗丽缤纷橙花面霜熬夜……
凌晨2点,杜兰特突曝离谱言论!勇士雷霆很意外,球迷不要脸了关于杜兰特球迷们一直以来的印象就是情商比较低,他的各种离谱言论也让人看得非常奇葩。之前在离开勇士队立马黑库里的行为也为他引来了相当大的麻烦,而这次在接受采访中阿杜也再次爆出来了……
整理涵盖很全很广的前端知识点HTML、CSS相关html5新特性、语义化语义化标签:headernavmainarticlesectionasidefooter语义化意味着顾名思义,HTML5的语义……
刚刚抄底完腾讯,段永平又出手了!这次是2万亿巨头大家记得前几天,几乎在腾讯跌到最低点时,段永平出手抄底了吗?而今天,段永平又出手了,这次是茅台。段永平买茅台看10年,比存银行要好一点3月29日早间,段……
15种导致便秘的食物便秘的定义是什么?便秘是一个常见的问题,人们发现很难排便。便秘在医学上被定义为每周排便少于三次。如果一个人每周排便少于一次,他们被认为是严重的便秘。腹胀、胀气……
大洛佩斯28分雄鹿大胜公牛,德罗赞40分雄鹿客场127106击败公牛,和76人、凯尔特人同为49胜30负升至东部第三。公牛跌到第六。米德尔顿中投,霍勒迪突破上篮,之后大洛佩斯连拿3球,波蒂斯补篮,米德尔顿、阿伦……
玲珑,嵖岈山今天2022年3月9日,河南之行的第3天,上午8时扫码进嵖岈山景区南大门,本以为嵖岈山不大,却不想一游就是近6个小时,直到中午1点多才翻山游到北大门,走到东门再回到南门,已是下……
入春别只会穿卫衣,试试这2件的上衣,百搭舒适又时髦温暖的春天,让人第一时间想到的就是卫衣,它百搭舒适又好穿,但是在众多的单品里面,也别总会穿卫衣,还有很多时尚的单品等着你来选择,比如:衬衫、开衫、针织衫、牛仔衫等等。卫衣……
中药十四种药性功效分类1透疹荆芥、薄荷、牛蒡子、蝉蜕、升麻、葛根、紫草既能透疹又能炒炭止血的药物是荆芥既能透疹又能疏肝解郁的药物是薄荷既能透疹又能解毒散肿的药物是牛蒡子既能透疹又能明目退翳的药物是蝉……
人间看花指南自然仙骨有天香蜡梅(文中照片除红花蜡梅外,均为作者拍摄)看花是件人生乐事,就和吃饭、喝水一样,也是人生不可或缺的内容。尤其喜欢看那些生长在大地上的树木开花,年年花都一样开,年年都要去看一样……
当猛犸象遇见元宇宙加州的拉布里沥青池被认为是世界上骨化石蕴藏最丰富的地方,这里保留着4万多年来不断陷入其中的成千上万的动物骨骼和植物的化石。只不过在21世纪,可怕的恐狼和剑齿猫不再在拉布里沥青池……