1 java概念
1.1 J2EE javabean的概念
2、提供默认构造方法
3、提供getter和setter
4、实现serializable接口
Bean在Spring和SpringMVC中无所不在,将这个概念内化很重要,下面分享一下我的想法:
一、Bean是啥
1、Java面向对象,对象有方法和属性,那么就需要对象实例来调用方法和属性(即实例化);
2、凡是有方法或属性的类都需要实例化,这样才能具象化去使用这些方法和属性;
3、规律:凡是子类及带有方法或属性的类都要加上注册Bean到Spring IoC的注解;
4、把Bean理解为类的代理或代言人(实际上确实是通过反射、代理来实现的),这样它就能代表类拥有该拥有的东西了
5、我们都在微博上@过某某,对方会优先看到这条信息,并给你反馈,那么在Spring中,你标识一个@符号,那么Spring就会来看看,并且从这里拿到一个Bean或者给出一个Bean
二、注解分为两类:
1、一类是使用Bean,即是把已经在xml文件中配置好的Bean拿来用,完成属性、方法的组装;比如@Autowired , @Resource,可以通过byTYPE(@Autowired)、byNAME(@Resource)的方式获取Bean;
2、一类是注册Bean,@Component , @Repository , @ Controller , @Service , @Configration这些注解都是把你要实例化的对象转化成一个Bean,放在IoC容器中,等你要用的时候,它会和上面的@Autowired , @Resource配合到一起,把对象、属性、方法完美组装。
三、@Bean是啥?
1、原理是什么?先看下源码中的部分内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | Indicates that a method produces a bean to be managed by the Spring container. <h3>Overview</h3> <p>The names and semantics of the attributes to this annotation are intentionally similar to those of the {@code <bean/>} element in the Spring XML schema. For example: <pre class = "code" > @Bean public MyBean myBean() { // instantiate and configure MyBean obj return obj; }</pre> |
意思是@Bean明确地指示了一种方法,什么方法呢——产生一个bean的方法,并且交给Spring容器管理;从这我们就明白了为啥@Bean是放在方法的注释上了,因为它很明确地告诉被注释的方法,你给我产生一个Bean,然后交给Spring容器,剩下的你就别管了
2、记住,@Bean就放在方法上,就是产生一个Bean,那你是不是又糊涂了,因为已经在你定义的类上加了@Configration等注册Bean的注解了,为啥还要用@Bean呢?这个我也不知道,下面我给个例子,一起探讨一下吧:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | package com.edu.fruit; //定义一个接口 public interface Fruit<T>{ //没有方法 } /* *定义两个子类 */ package com.edu.fruit; @Configuration public class Apple implements Fruit<Integer>{ //将Apple类约束为Integer类型 } package com.edu.fruit; @Configuration public class GinSeng implements Fruit<String>{ //将GinSeng 类约束为String类型 } /* *业务逻辑类 */ package com.edu.service; @Configuration public class FruitService { @Autowired private Apple apple; @Autowired private GinSeng ginseng; //定义一个产生Bean的方法 @Bean (name= "getApple" ) public Fruit<?> getApple(){ System.out.println(apple.getClass().getName().hashCode); System.out.println(ginseng.getClass().getName().hashCode); return new Apple(); } } /* *测试类 */ @RunWith (BlockJUnit4ClassRunner. class ) public class Config { public Config(){ super ( "classpath:spring-fruit.xml" ); } @Test public void test(){ super .getBean( "getApple" ); //这个Bean从哪来,从上面的@Bean下面的方法中来,返回 的是一个Apple类实例对象 } } |
从上面的例子也印证了我上面的总结的内容:
1、凡是子类及带属性、方法的类都注册Bean到Spring中,交给它管理;
2、@Bean 用在方法上,告诉Spring容器,你可以从下面这个方法中拿到一个Bean
1.2 implements 字节流 Serializable的应用
一个对象序列化的接口,一个类只有实现了Serializable接口,它的对象才是可序列化的。因此如果要序列化某些类的对象,这些类就必须实现Serializable接口。而实际上,Serializable是一个空接口,没有什么具体内容,它的目的只是简单的标识一个类的对象可以被序列化。
serialization 允许你将实现了Serializable接口的对象转换为字节序列,这些字节序列可以被完全存储以备以后重新生成原来的对象。
什么情况下需要序列化:
1. 当你想把的内存中的对象写入到硬盘的时候。
2. 当你想用套接字在网络上传送对象的时候。
3. 当你想通过RMI传输对象的时候。
再稍微解释一下:
1. 比如说你的内存不够用了,那计算机就要将内存里面的一部分对象暂时的保存到硬盘中,等到要用的时候再读入到内存中,硬盘的那部分存储空间就是所谓的虚拟内存。在比如过你要将某个特定的对象保存到文件中,我隔几天在把它拿出来用,那么这时候就要实现Serializable接口。
2. 在进行Java的Socket编程的时候,你有时候可能要传输某一类的对象,那么也就要实现Serializable接口。最常见的你传输一个字符串,它是JDK里面的类,也实现了Serializable接口,这样做为的是将数据变为二进制来传输,所以可以在网络上传输。
3. 如果要通过远程的方法调用(RMI)去调用一个远程对象的方法,如在计算机A中调用另一台计算机B的对象的方法,那么你需要通过JNDI服务获取计算机B目标对象的引用,将对象从B传送到A,就需要实现序列化接口。
1.3 抽象类和抽象方法的一些概念
//抽象方法:只包含方法定义,但没有具体实现的方法,需要其子类或者子类的子类来具体实现。
//静态方法不能标记为 override、virtual 或 abstract,即静态方法都必须是具体的 /抽象类:含有一个或多个抽象方法的类称为抽象类,在声明时,类名前须添加"abstract"关键字
//抽象类中可以包含非抽象方法
//抽象类不能够被实例化,这是因为它包含了没有具体实现的方法,即可实例化的类一定不是抽象类,不包含未具体实现的抽象方法。
//子类继承抽象父类后,可以使用override关键字覆盖父类中的抽象方法,并做具体的实现。也可以不实现抽象方法,留给后代实现,这时子类仍旧是一个抽象类,必须声明为abstract
//继承的抽象方法不可以被隐藏 //隐藏:在子类中创建与父类中的方法具有相同签名(相同的方法名,相同的参数列表--参数类型和次序)的方法(可以带有"virtual"或"override"关键字)即可实现,但建议使用"new"关键字,以明确地隐藏。
//只能使用"override"关键字来覆盖(override)父类中标记为"virtual"、"abstract"或"override"的方法,而子类中标记为override的方法,也必须是父类中标记为"virtual"、"abstract"或"override"的方法。
//覆盖(override):必须使用override关键字,可以被覆盖的方法包括标记为abstract,virtual,和override的方法;
//隐藏:使用new关键字,也可不使用关键字,可以被隐藏的方法包括一般方法,和标记为virtual"或"override"的方法;
//重载(overload):不需要任何特殊的关键字//静态方法可以被隐藏或重载
1.4 OOP一些知识点
1 方法重写必须满足以下要求:
1 重写方法与被重写的方法必须方法名相同,参数列表相同。
2 重写方法与被重写的方法返回值类型必须相同或是其子类
3 重写方法不能缩小被重写方法的访问权限
2 重载和重写有什么区别和联系
重载涉及同一个类中的同名方法,要求方法名相同,参数列表不同,与访问类型访问修饰符无关
重写涉及的是子类和父类之间的同名方法,要求方法名相同、参数列表相同,返回值类型相同(或是其子类)、访问修饰符不能严于父类
3 抽象类的实现相关问题详解:
Calendar c = new Calendar(); 出现 new Calendar()就会执行实例化一个对象了。所以如果是抽象类就不能这样new的。要new 它没有abstract的子类。
抽象类是指不允许被实例化的类;抽象方法是没有方法体的方法。
1、抽象类可以不包括抽象方法,它反正不会去实例化,抽象类不能被实例化,也就是不能用new关键字去产生对象,抽象方法只需声明,而不需实现,抽象类的子类必须覆盖所有的抽象方法后才能被实例化,否则这个子类还是个抽象类,里面的方法是不是抽象的没有本质影响。
2、但是含有抽象方法的类绝不能被实例化,否则执行这个方法的时候,怎么办?
3、如果子类是非抽象的,那么它就必须实现父类中的抽象方法;否则,它继承来的抽象方法仍然没有方法体,也是个抽象方法,此时就与“含有抽象方法的类必须是抽象类”相矛盾了。
抽象类与接口紧密相关,它们不能实例化,并且常常部分实现或根本不实现。抽象类和接口之间的一个主要差别是:类可以实现无限个接口,但仅能从一个抽象(或任何其他类型)类继承。从抽象类派生的类仍可实现接口。可以在创建组件时使用抽象类,因为它们使您得以在某些方法中指定不变级功能,但直到需要该类的特定实现之后才实现其他方法。抽象类也制定版本,因为如果在派生类中需要附加功能,则可以将其添加到基类而不中断代码。
在实现抽象类时,必须实现该类中的每一个抽象方法,而每个已实现的方法必须和抽象类中指定的方法一样,接收相同数目和类型的参数,具有同样的返回值。
4 关于抽象类、抽象方法相关的概述
//抽象方法:只包含方法定义,但没有具体实现的方法,需要其子类或者子类的子类来具体实现。
//静态方法不能标记为 override、virtual 或 abstract,即静态方法都必须是具体的
/抽象类:含有一个或多个抽象方法的类称为抽象类,在声明时,类名前须添加"abstract"关键字
//抽象类中可以包含非抽象方法
//抽象类不能够被实例化,这是因为它包含了没有具体实现的方法,即可实例化的类一定不是抽象类,不包含未具体实现的抽象方法。
//子类继承抽象父类后,可以使用override关键字覆盖父类中的抽象方法,并做具体的实现。也可以不实现抽象方法,留给后代实现,这时子类仍旧是一个抽象类,必须声明为abstract
//继承的抽象方法不可以被隐藏
//隐藏:在子类中创建与父类中的方法具有相同签名(相同的方法名,相同的参数列表--参数类型和次序)的方法(可以带有"virtual"或"override"关键字)即可实现,但建议使用"new"关键字,以明确地隐藏。
//只能使用"override"关键字来覆盖(override)父类中标记为"virtual"、"abstract"或"override"的方法,而子类中标记为override的方法,也必须是父类中标记为"virtual"、"abstract"或"override"的方法。
//覆盖(override):必须使用override关键字,可以被覆盖的方法包括标记为abstract,virtual,和override的方法;
//隐藏:使用new关键字,也可不使用关键字,可以被隐藏的方法包括一般方法,和标记为virtual"或"override"的方法;
//重载(overload):不需要任何特殊的关键字//静态方法可以被隐藏或重载
5 抽象类至少包含一个抽象方法,抽象类无法实例化(即无法new),只能靠子类去实现父类的抽象方法,子类可以直接继承父类的非抽象方法。抽象方法无方法体,接口无方法体
第一章
封装4大权限控制符
private :成员变量和方法只能在其定义的类中被访问,具有类可见性
默认(friendly):成员变量和方法只能在同一个包里的类访问,具有包可见性
protected:成员变量和方法可以被同一个包里的类访问,被同一个项目中不同包的自类访问
public:成员变量和方法可以被同一个项目中的所有类访问,具有项目可见性。最大的访问权限
重载的三要素:
1在同一个类中
2方法名相同
3参数列表不同
方法体的作用(即大括号的作用):
java中抽象类中可以存在的抽象方法或接口中的方法不允许有方法体,但不属于方法体是空的。
java.awt.event包中的适配器类中方法体是空的。
2 区别相关
2.1 静态方法与非静态方法的区别
1 外部调用静态方法的时候,可以使用“类名.方法名”的形式,也可以使用“对象名.方法名”的形式。实例只有后边的形式。(静态方法不用创建对象)
2 静态方法在访问本类的成员时,只允许访问静态成员(即静态成员变量和静态方法),而不允许访问实例成员变量和实例方法;实例方法则无此限制。
2.2 字节流与字符流的区别
按照所操作的数据单元的不同,流可划分为字节流和字符流。
字节流操作的最小数据单元为8位的字节,而字符流操作的最小数据单元是16位的字符 。
字节流与字符流的区分非常简单,字节流建议用于二进制数据(如图片),而字符流用于文本,它们的用法几乎是完全一样的。
2.3 递归 循环 区别
递归与循环是两种不同的解决问题的典型思路。
递归算法:
优点:代码简洁、清晰,并且容易验证正确性。(如果你真的理解了算法的话,否则你更晕)
缺点:它的运行需要较多次数的函数调用,如果调用层数比较深,需要增加额外的堆栈处理,比如参数传递需要压栈等操作,会对执行效率有一定影响。但是,对于某些问题,如果不使用递归,那将是极端难看的代码。
循环算法:
优点:速度快,结构简单。
缺点:并不能解决所有的问题。有的问题适合使用递归而不是循环。如果使用循环并不困难的话,最好使用循环。
递归算法 和循环算法总结
1. 一般递归调用可以处理的算法,也通过循环去解决常需要额外的低效处理 。
2. 现在的编译器在优化后,对于多次调用的函数处理会有非常好的效率优化,效率未必低于循环。
引自:https://www.cnblogs.com/wcyBlog/p/3928803.html
2.4 接口与抽象类 区别
abstract的抽象类里面封装了很多公共的实现,子类是可以直接使用的,
interface只能给出接口,公共的实现子类需要重复实现,所以才会使用抽象类。
参数 | 抽象类 | 接口 |
默认的方法实现 | 它可以有默认的方法实现 | 接口完全是抽象的。它根本不存在方法的实现 |
实现 | 子类使用extends关键字来继承抽象类。如果子类不是抽象类的话,它需要提供抽象类中所有声明的方法的实现。 | 子类使用关键字implements来实现接口。它需要提供接口中所有声明的方法的实现 |
构造器 | 抽象类可以有构造器 | 接口不能有构造器 |
与正常Java类的区别 | 除了你不能实例化(new)抽象类之外,它和普通Java类没有任何区别 | 接口是完全不同的类型 |
访问修饰符 | 抽象方法可以有public、protected和default这些修饰符 | 接口方法默认修饰符是public。你不可以使用其它修饰符。 |
main方法 | 抽象方法可以有main方法并且我们可以运行它 | 接口没有main方法,因此我们不能运行它。(java8以后接口可以有default和static方法,所以可以运行main方法) |
多继承 | 抽象方法可以继承一个类和实现多个接口 | 接口只可以继承一个或多个其它接口 |
速度 | 它比接口速度要快 | 接口是稍微有点慢的,因为它需要时间去寻找在类中实现的方法。 |
添加新方法 | 如果你往抽象类中添加新的方法,你可以给它提供默认的实现。因此你不需要改变你现在的代码。 | 如果你往接口中添加方法,那么你必须改变实现该接口的类。 |
2.5 javase,javaee和javame的区别
javase 为java基础
javaee 为web工程开发
javame 为手机安卓开发
2.6 rs.close() 和 rs.getStatement.close()的区别
rs.close() 关闭的是resuletset;
rs.getStatement.close() 关闭的是statement;
当用jdbc获取数据库连接时,最好先rs.close(),然后再rs.getStatement.close() ;
2.7 c/s架构和b/s架构的区别
C/S 客户端/服务器 例如QQ,网络游戏,需要下载客户端才能访问服务器的程序,需要升级
B/S 浏览器/服务器 例如Intel,FireFox 不需要客户端,通过浏览器访问服务器,无需升级,永远是最新的版本
2.8 设计模式和设计原则的区别
设计模式的根本是设计原则,而设计原则又是为了达到实现一个“优秀”软件的行为准则
详情见
https://www.cnblogs.com/noteless/p/9897464.html
2.9 oop重载重写区别
重载:
5.2 静态代码块,内部类静态块,内部类代码块 执行顺序
如果主函数有调内部类,则执行 静态代码块>内部类静态块>内部类代码块
否则,则执行 静态代码块
参考:https://www.cnblogs.com/paul011/p/8574650.html
判断方法重载的依据:
1、 必须是在同一个类中
2、 方法名相同
3、 方法参数的个数、顺序或类型不同
4、 与方法的修饰符或返回值没有关系
请看以上依据,重载能且只能在同一个类中,父类和子类属于不同的两种类
重写:
1、必须是子类和超类的继承关系
区分点:
1 重载是在同一个类中,而重写在不同的类中
2 重写是方法名和参数顺序个数完全一致,重载只是方法名字相同,参数类型或者参数个数是不同的。
3 重载对权限没有要求,重写子类不能对父类有更严的权限,只能更加宽松或者相同
2.A final和static的区别
final:
final定义的变量可以看做一个常量,不能被改变;
final定义的方法不能被覆盖;
final定义的类不能被继承。
final static 就是再加上static的特性就可以了
static :
static 是在内存中分配一块区域,供整个类通用,所有的类的对象都享有它的共同的值,
修饰方法时调用的时候直接类调取即可
3 方法体的修饰
3.1 static 静态的
特点:使用该方法,此类必定是静态类;
其他类调用该类的时候必须用 类名.方法名
3.2 synchronized 同步锁
特点:防止多线程并发问题。
此方法加在静态方法是 类锁,
加在 非静态方法上是 对象锁。
具体用法参考设计模式 课程 8-2
3.3 volatile
特点:防止初始化的时候重排序问题
线程安全初始化
具体用法和场景参考设计模式 课程 8-3
3.4 native
简单地讲,一个Native Method就是一个java调用非java代码的接口。一个Native Method是这样一个java的方法:该方法的实现由非java语言实现,比如C。这个特征并非java所特有,很多其它的编程语言都有这一机制,比如在C++中,你可以用extern "C"告知C++编译器去调用一个C的函数。
详细参考:https://www.cnblogs.com/KingIceMou/p/7239668.html
3.5 final修饰类的时候表示该类不可被继承,
修饰方法的时候表示该方法不能被重写,
修饰属性的时候必须赋初始值,切只能初始化一次,
修饰成员变量是引用类型的时候如:map,list,则说明这个引用地址的值不能修改,但是这个引用对象里面的内容还是可以改变的。
public static void main(String[] args) { final Integer integer = new Integer(1); //integer = 2; //报错:无法为最终变量integer分配值; 原因:final修饰的基本数据类型不允许更改 final Map<String, String> map = new HashMap<String, String>(){{ this.put("a", "a"); }}; map.put("a","a");//没有报错,final修饰的Map允许的值更改,因为final修饰的是map的引用,而不是内容 //map = new HashMap<>();//报错:无法为最终变量map分配值 原因:final修饰的map无法修改其引用 }
4 其他
4.1 java中方法体即{}的作用
java中抽象类中可以存在的抽象方法或接口中的方法不允许有方法体,但不属于方法体是空的。
java.awt.event包中的适配器类中方法体是空的。
从语法中说,没有方法体必须是空的这一要求,只要是非抽象的方法,必须要有方法体,至于里面写不写代码,即空不空取决于你的需要。
4.2 new对象的作用
new调用了构造函数以后
构造函数会返回一个对象的实例
5 执行顺序
5.1 静态代码块 && mian方法 && 构造代码块 && 构造方法 执行顺序
静态代码块>mian方法>构造代码块>构造方法
参考:https://www.cnblogs.com/sophine/p/3531282.html
巩固:https://www.cnblogs.com/xunzhaorendaxia/p/11106137.html