(学习留存,如有侵权,请告知,立刻删除!)
一、@Override(覆盖也意“重写”)
@override可以翻译为“覆盖”也可以理解为“重写”,从字面上就可以知道,它是覆盖了一个方法并且对其进行了重写,以求达到不同的效果;对我们来说最熟悉的覆盖就是对接口中方法的实现,在接口中一般只是对方法进行了声明,而我们在实现时,就需要实现接口中声明的所有方法。除了这个典型的用法以外,我们在继承中也会用到该注解,子类覆盖父类中的方法,重写父类方法;
这里说到重写,有必要在讲讲重载,以及它们之间的区别:
重载(Overloading)
方法的重载是让类以统一的方式处理不同类型数据的一种手段,多个同名方法同时存在,但是具有不同的参数个数、参数类型、参数顺序、甚至返回值也可不一样;重载是一个类中多态性的一种非常典型的表现形式;而多态则是JAVA面向对象的一个非常显著的特点,除此以外,还有封装、继承以及抽象;
JAVA方法的重载,就是在类中可以创建多个方法,他们具有相同的方法名,但是具有不同的参数个数、类型、顺序,调用方法时通过传递给它们的不同参数个数、类型、顺序来决定具体使用哪个方法,这就是多态;
重载的时候,方法名要一样,但是参数个数、参数类型、参数顺序,至少要有一个不一样,返回值可以一样,也可以不一样,但是无法以返回值类型作为重载的区分标准,例如方法名、参数(个数、类型、顺序)都一样的情况下,返回值不同,这样不算重载;
重写方法的规则:
1、父类方法被默认修饰时(default权限修饰符),只能在同一包中被其子类重写,如果不在同一包中则不能重写;(后续我们讲JAVA的修饰符及其用法)
2、父类方法被protected/public修饰时,不仅在同一包中能被其子类重写,在不同包中也可被其子类重写;父类不能为private修饰(私有)
3、重写方法的参数列表必须与被重写方法的参数列表一致;
4、重写方法的返回值类型必须与被重写方法的返回值类型一致;
5、重写方法(子)的访问修饰符一定要大于或等于被重写方法的访问修饰符;(public>protected>default>private)
6、重写方法(子)抛出的异常一定不能是新的检查异常或者比被重写方法(父)申明更加广泛的检查型异常,但是可以是异常的子类;
7、被重写的方法不能被private修饰,否则子类不能重写;
8、子类重写父类方法,如果需要父类原方法,可以在子类方法体中使用super关键字,该关键字引用了当前类的父类;
9、重写是父类与子类之间多态性的一种表现形式;
10、子类重写父类方法时,子类对象如果调用该方法,那么就会使用子类的方法,父类被重写的方法就被屏蔽了;如果要用父类的方法,就要使用super关键字了;
11、子类重写父类方法时,父类对象用子类对象实例化后;例如: 父类 实例 = new 子类();实例可以调用父类中特有的方法,可以调用子类重写父类的方法,但是不可以调用子类私有的方法;
重载方法的规则:
1、方法名一样,参数列表不一致;
2、返回值可以不一样,也可以一样,只要参数列表不一致就可以了;
3、可以有不同的访问修饰符;
4、可以抛出不同异常;
5、重载是一个类中的多态性的表现形式;
重写与重载的特点:
Override:
1、覆盖(重写)的方法的方法名、参数列表(子)必须要和被覆盖(重写)的方法名、参数列表(父)完全匹配,才能达到覆盖(重写)的效果;
2、覆盖的方法(子)的返回值必须和被覆盖的方法(父)的返回值一致;
3、覆盖的方法(子)所抛出的异常必须和被覆盖的方法(父)所抛出的异常一致,或者是其异常的子类;也可以不抛出异常;
4、被覆盖的方法(父)不能为private,否则在其子类中只是新定义了一个方法,并没有对其进行覆盖;
5、子类方法不能缩小父类方法的访问修饰符;
6、存在父类与子类之间,或者接口与实现之间;
7、父类方法被定义为final不能被重写;
Overloading:
1、使用重载时只能通过不同的参数样式;例如,不同的参数类型,不同的参数个数,不同的参数顺序(当然,同一方法内的几个参数类型必须不一样,例如可以是fun(int, float), 但是不能为fun(int, int));
2、不能通过访问修饰符、返回值类型、抛出的异常进行重载;
3、方法的异常类型和数目不会对重载造成影响;
4、对于继承来说,如果父类中某方法的访问权限是private,那么就不能在子类中对其进行重载,如果定义的话,也只是定义一个子类所有的新方法,不会达到重载的效果,没有什么意义;
5、存在父类、子类或同类中;
该注解是“伪代码”,表示重写父类方法,只能在子类的方法体上出现,可以避免方法名和参数写错(写不写都可以);
写的好处:
1、可以当注释用,方便阅读;
2、子类方法体添加该注解,编译器会验证子类方法名、参数是不是父类所有,如果没有就会报错;如果没写这个注解,子类的方法名、参数与父类不同,编译器会默认该方法为子类所有,不会报错;
二、@Component(组件)
该注解是“通用注解”,表示所注解的类已经被Spring容器所管理,添加该注解的类会由普通的POJO类实例化到Spring容器中去,也就是相当于我们在Spring配置文件中写的<bean id="" class="" />,标记为@Component的类,在添加注解配置的情况下,系统启动的时候会被自动扫描,并把所注解的类添加到bean工厂中去(省去了配置文件中定义bean了);
持久层、业务层、控制层,分别采用@Repository、@Service、@Controller对三层中的类进行凝视,而用@Component对那些比较中立的类进行凝视,就是把这个类交给Spring管理;
1、作用在类上的注解有@Component、@Responsity、@Service以及@Controller;
当注解在类上时,表明这些类将交给Spring容器进行统一管理,当使用@Aurowired和@Resource时,表明我需要某个字段、setter方法,但是我不需要去new一个对象,只需要只用注解,Spring就会自动给我生产我需要的属性、方法或对象,这就是我们常说的依赖注入(DI)和控制反转(IOC);
IOC(inversion of control)控制反转模式;控制反转是将Spring组件间(component)的依赖关系从程序内部提到外部来管理;;
DI(dependency injection)依赖注入模式;依赖注入是指将组件的依赖通过外部以参数或其他形式注入;
而@Autowired、@Resource则是用来修饰字段、或setter方法,并注入;@Autowired、@Resource都可以用来装配bean,可以写在字段上,也可以写在setter方法上;
@Autowired默认按“类型(byType)”装配(注解属于Spring),默认情况下必须要求依赖对象bean存在,如果不存在则会报错,如果不想报错,可以允许null值,可以设置它的的required属性为false;
@Autowired是Spring注解;导包import org.springframework.beans.factory.annotation.Autowired;Spring属于第三方;
下面两种@Autowired只要使用一种即可
@Autowired
private UserDao userDao; // 用于字段上
@Autowired
public void setUserDao(UserDao userDao) { // 用于属性的方法上
this.userDao = userDao;
如:@Autowired(required = false),如果想使用名称(byName)装配,可以配合@Qualifier注解进行使用;
如:@Autowired(required = false)
@Qualifier("beanName")首字母小写
private BaseDao baseDao;
在未使用@Autowired之前,我们对一个bean配置属性时,是这样的:
<property name="属性名" value="属性值">
使用@Autowired注解自动装配,去IOC容器中去查找对应的bean,并装配给该对象的属性;
在使用@Autowired时,首先在容器中查询对应类型的bean;
1、如果查询结果刚好为一个,就将该bean装配给@Autowired指定的数据;
2、如果查询结果不止一个,那么@Autowired会根据名称来查找,可以定义一个注解@Qualifier("beanName");
3、如果查询结果为空,那么会抛出异常,解决办法是,使用required = false;
@Resource是JDK1.6支持的注解,默认按照“名称”装配,名称可以通过name属性进行指定,如果没有指定name属性,当注解写在字段上时,默认取“字段名”,按照名称查找;如果注解写在setter方法上默认取“属性名”进行装配;
当找不到与名称匹配的bean时才按照类型装配;但是需要注意“如果name一旦指定,就只会按照名称装配”;用@Resource可以减少代码与Spring之间的耦合,使代码看起来优雅;
@Resource是J2EE的注解;导包 import javax.annotation.Resource;J2EE是JAVA自己的东西;
@Resource(name = "baseDao")首字母小写
private BaseDao baseDao;
@Resource有两个重要的属性:name和type,而Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以,如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不制定name也不制定type属性,这时将通过反射机制使用byName自动注入策略;
注:最好是将@Resource放在setter方法上,因为这样更符合面向对象的思想,通过set、get去操作属性,而不是直接去操作属性;
@Resource装配顺序:
1、如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常。
2、如果指定了type,则从上下文中找到类似匹配的唯一bean进行装配,找不到或是找到多个,都会抛出异常。
3、如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常。
4、如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配;
下面两种@Resource只要使用一种即可
@Resource(name="userDao")
private UserDao userDao; // 用于字段上
@Resource(name="userDao")
public void setUserDao(UserDao userDao) { // 用于属性的setter方法上
this.userDao = userDao;
}
它们主要的区别就是装配类型不同,@Autowired默认按类型,@Resource默认按名称;
三、@Controller(控制器)
用于标注控制层组建,相当于struts中的action;(controller)
四、@Service(服务)
用于标注业务层(服务层)组件;(serviceImpl);@Service("beanName"),用来给服务层的类定义一个名字,SpringIOC会根据这个定义的“beanName”找到这个注解的类;注入dao层;
五、@Repository(存储库)
用于标注数据访问层(持久层)组件;(dao);@Repository("beanName"),用来给持久层的类定义一个名字,SpringIOC会根据这个定义的“beanName”找到这个注解的类;实现dao访问;
六、@SuppressWarnings
标注在类、字段、方法、参数、构造方法,以及局部变量上,告诉编译器忽略指定内部的警告,不用在编译完成后出现警告信息;
常用的警告:
@SuppressWarnings("unchecked")未经检查的操作
@SuppressWarnings("rawtypes")泛型
@SuppressWarnings("unused")未使用的代码、变量
@SuppressWarnings("serial")用于我们的实体类,序列化后没有加serialVersionUID,可以加上;