1 final用于修饰变量
final变量只能赋值一次,赋值的方式有三种:
1)声明变量时直接赋值;
2)非静态成员变量在{}块中赋值,静态成员变量在static{}块中赋值;
3)非静态成员变量在构造方法中赋值。
三种赋值方式的顺序是1)、2)、3),若有一种方式先行赋值了,则后面的方式就不能再赋值,否则就会编译错误。
[java] view plain copy print?
public class FinalTest {
private final int a;
private static final int b;
private final static int c;
{
a = 2;
}
static {
b = 2;
c = 2;
}
public FinalTest() {
// a = 3;// The final field a may already have been assigned
// b = 3;// The final field FinalTest.b cannot be assigned
// c = 3;// The final field FinalTest.b cannot be assigned
}
}
2 final修饰类
final类不能被继承,因此不会有子类。final类中的方法不论是否有final修改,都是final的。
3 final修饰方法
final方法不能被override。若父类中的方法为final的,则子类不能override该方法,但可以调用该方法(父类的final方法)。
扩展资料:http://www.infoq.com/cn/articles/java-memory-model-6
--------------------------------------------------------------------------------------------------------------------------------
抽象类的理解及有关面试题
原创 2017年05月03日 22:06:33 258
抽象类的概述与特点
A:不懂,太抽象了
B:抽象类特点
a:抽象类和抽象方法必须用abstract修饰
*abstractclass 类名()
*publicabstract void eat()
b:抽象类不一定有抽象方法,有抽象方法的类一定是抽象类或者是抽象接口
c:抽象类不能实例化,那么抽象类如何实例化呢?
*按照多态的方式,由具体的子类实例化,其实这也是多态的一种,抽象类多态
d:抽象类的子类
*要么是抽象类要么重写抽象类中的所有抽象方法
抽象类的成员特点
a:成员变量:既可以是变量也可以是常量,abstract是否可以修饰变量?不可以
b:构造方法:有
*用于子类访问父类数据的初始化
c:成员方法:既可以是抽象的也可以是非抽象的
d:抽象类的成员方法特性
*抽象方法,强制子类做事情,执行标准,统一规则,(理解)
*非抽象方法,子类继承的事情,提高代码复用性
[java] view plain copy
public class abdemon {
public static void main(String[] args) {
//Animal a = new Animal()
//Cannot instantiate the type Animal
//抽象类不能实例化
//如果要抽象化必须实现(重写)抽象方法
Animal a = new Animal() {
public void eat() {
// TODO Auto-generated methodstub
System.out.println("抽象类实例化要实现抽象方法");
}
};
a.eat();
Animal b = new Cat();//由具体的子类实例化
b.eat();
}
}
abstract class Animal{
public abstract void eat();//抽象类不能实例化
public Animal(){ //用于子类访问父类数据的初始化
System.out.println("父类无参构造");
}
}
class Cat extends Animal{
public void eat() {
// TODO Auto-generated method stub
System.out.println("猫吃鱼");
}
}
面试题
*1一个抽象类如果没有抽象方法,可不可以定义为抽象类?如果可以,有什么意义
* 可以
* 这么做目的只有一个,就是不让其他类创建本类对象,交给子类完成
*2abstract不能和那些关键字共存
*——static和abstract//非法的修饰符组合
* 被abstract修饰的方法没有方法体
* 被static修饰的方法可以通过类名.调用,但是调用抽象方法是没有意义的
*————final和abstract
* 被abstract修饰的方法强制子类重写
* 被final修饰的方法不让子类重写
*————private和abstract
* 被abstract修饰的方法是为了让子类看到并强制重写
* 被private修饰的方法不让子类访问
Java允许抽象类中有private变量和private方法,因为按照抽象类的定义,抽象类与一般类的不同之外只在于它里面含有抽象的方法(也可能没有)。既然一般类中有private变量和private方法,抽象类中也能有。大家写一个抽象类就都明白了。
需要注意的是,抽象类中的abstract方法不能为private,因为它需要子类来继承它。
------------------------------------------------------------------------
Spring bean 生命周期
找工作的时候有些人会被问道Spring中Bean的生命周期,其实也就是考察一下对Spring是否熟悉,工作中很少用到其中的内容,那我们简单看一下。
在说明前可以思考一下Servlet的生命周期:实例化,初始init,接收请求service,销毁destroy;
Spring上下文中的Bean也类似,如下
1、实例化一个Bean--也就是我们常说的new;
2、按照Spring上下文对实例化的Bean进行配置--也就是IOC注入;
3、如果这个Bean已经实现了BeanNameAware接口,会调用它实现的setBeanName(String)方法,此处传递的就是Spring配置文件中Bean的id值
4、如果这个Bean已经实现了BeanFactoryAware接口,会调用它实现的setBeanFactory(setBeanFactory(BeanFactory)传递的是Spring工厂自身(可以用这个方式来获取其它Bean,只需在Spring配置文件中配置一个普通的Bean就可以);
5、如果这个Bean已经实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,传入Spring上下文(同样这个方式也可以实现步骤4的内容,但比4更好,因为ApplicationContext是BeanFactory的子接口,有更多的实现方法);
6、如果这个Bean关联了BeanPostProcessor接口,将会调用postProcessBeforeInitialization(Object obj, String s)方法,BeanPostProcessor经常被用作是Bean内容的更改,并且由于这个是在Bean初始化结束时调用那个的方法,也可以被应用于内存或缓存技术;
7、如果Bean在Spring配置文件中配置了init-method属性会自动调用其配置的初始化方法。
8、如果这个Bean关联了BeanPostProcessor接口,将会调用postProcessAfterInitialization(Object obj, String s)方法、;
注:以上工作完成以后就可以应用这个Bean了,那这个Bean是一个Singleton的,所以一般情况下我们调用同一个id的Bean会是在内容地址相同的实例,当然在Spring配置文件中也可以配置非Singleton,这里我们不做赘述。
9、当Bean不再需要时,会经过清理阶段,如果Bean实现了DisposableBean这个接口,会调用那个其实现的destroy()方法;
10、最后,如果这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的销毁方法。
以上10步骤可以作为面试或者笔试的模板,另外我们这里描述的是应用Spring上下文Bean的生命周期,如果应用Spring的工厂也就是BeanFactory的话去掉第5步就Ok了。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
bean factory 和factory bean 区别
1、 BeanFactory
BeanFactory定义了 IOC 容器的最基本形式,并提供了 IOC 容器应遵守的的最基本的接口,也就是 Spring IOC 所遵守的最底层和最基本的编程规范。在 Spring 代码中,BeanFactory 只是个接口,并不是 IOC 容器的具体实现,但是 Spring 容器给出了很多种实现,如DefaultListableBeanFactory 、 XmlBeanFactory 、 ApplicationContext 等,都是附加了某种功能的实现。
Java代码 收藏代码
packageorg.springframework.beans.factory;
importorg.springframework.beans.BeansException;
public interface BeanFactory {
String FACTORY_BEAN_PREFIX = "&";
Object getBean(String name) throws BeansException;
<T> T getBean(String name, Class<T> requiredType) throwsBeansException;
<T> T getBean(Class<T> requiredType) throwsBeansException;
Object getBean(String name, Object... args) throws BeansException;
boolean containsBean(String name);
boolean isSingleton(String name) throwsNoSuchBeanDefinitionException;
boolean isPrototype(String name) throwsNoSuchBeanDefinitionException;
boolean isTypeMatch(String name, Class<?> targetType) throwsNoSuchBeanDefinitionException;
Class<?> getType(String name) throwsNoSuchBeanDefinitionException;
String[] getAliases(String name);
}
2、 FactoryBean
一般情况下,Spring 通过反射机制利用 <bean> 的 class 属性指定实现类实例化 Bean ,在某些情况下,实例化 Bean 过程比较复杂,如果按照传统的方式,则需要在 <bean> 中提供大量的配置信息。配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。 Spring 为此提供了一个org.springframework.bean.factory.FactoryBean 的工厂类接口,用户可以通过实现该接口定制实例化 Bean 的逻辑。
FactoryBean接口对于Spring 框架来说占用重要的地位, Spring 自身就提供了 70 多个 FactoryBean 的实现。它们隐藏了实例化一些复杂 Bean 的细节,给上层应用带来了便利。从 Spring 3.0 开始, FactoryBean 开始支持泛型,即接口声明改为 FactoryBean<T>的形式:
Java代码 收藏代码
packageorg.springframework.beans.factory;
public interface FactoryBean<T>{
TgetObject() throws Exception;
Class<?> getObjectType();
boolean isSingleton();
}
在该接口中还定义了以下3 个方法:
T getObject():返回由FactoryBean 创建的 Bean 实例,如果isSingleton() 返回 true ,则该实例会放到Spring 容器中单实例缓存池中;
boolean isSingleton():返回由 FactoryBean 创建的 Bean 实例的作用域是 singleton 还是 prototype ;
Class<T> getObjectType():返回 FactoryBean 创建的 Bean 类型。
当配置文件中<bean> 的 class 属性配置的实现类是 FactoryBean 时,通过 getBean() 方法返回的不是 FactoryBean 本身,而是 FactoryBean#getObject() 方法所返回的对象,相当于FactoryBean#getObject() 代理了 getBean() 方法。
例:如果使用传统方式配置下面Car 的<bean> 时, Car 的每个属性分别对应一个<property> 元素标签。
Java代码 收藏代码
package com.baobaotao.factorybean;
public class Car {
private int maxSpeed ;
private String brand ;
private double price ;
public int getMaxSpeed () {
return this . maxSpeed ;
}
public void setMaxSpeed ( int maxSpeed ) {
this . maxSpeed = maxSpeed;
}
public String getBrand () {
return this . brand ;
}
public void setBrand ( String brand ) {
this . brand = brand;
}
public double getPrice () {
return this . price ;
}
public void setPrice ( double price ) {
this . price = price;
}
}
如果用FactoryBean 的方式实现就灵活点,下例通过逗号分割符的方式一次性的为 Car 的所有属性指定配置值:
Java代码 收藏代码
package com.baobaotao.factorybean;
import org.springframework.beans.factory.FactoryBean;
public class CarFactoryBean implements FactoryBean<Car> {
private String carInfo ;
public Car getObject () throws Exception {
Car car = new Car () ;
String [] infos = carInfo .split ( "," ) ;
car.setBrand ( infos [ 0 ]) ;
car.setMaxSpeed ( Integer. valueOf ( infos [ 1 ])) ;
car.setPrice ( Double. valueOf ( infos [ 2 ])) ;
return car;
}
public Class<Car>getObjectType () {
return Car. class ;
}
public boolean isSingleton () {
return false ;
}
public String getCarInfo () {
return this . carInfo ;
}
// 接受逗号分割符设置属性信息
public void setCarInfo ( String carInfo ) {
this . carInfo = carInfo;
}
}
有了这个CarFactoryBean 后,就可以在配置文件中使用下面这种自定义的配置方式配置 Car Bean 了:
<bean id="car"class="com.baobaotao.factorybean.CarFactoryBean"
P:carInfo="法拉利 ,400,2000000"/>
当调用getBean("car") 时, Spring 通过反射机制发现 CarFactoryBean 实现了 FactoryBean 的接口,这时 Spring 容器就调用接口方法 CarFactoryBean#getObject() 方法返回。如果希望获取CarFactoryBean 的实例,则需要在使用 getBean(beanName) 方法时在 beanName 前显示的加上 "&" 前缀:如 getBean("&car");
3、 区别
BeanFactory是个 Factory ,也就是 IOC 容器或对象工厂, FactoryBean 是个 Bean 。在 Spring 中,所有的 Bean 都是由 BeanFactory( 也就是 IOC 容器 ) 来进行管理的。但对FactoryBean 而言,这个 Bean 不是简单的Bean ,而是一个能生产或者修饰对象生成的工厂 Bean, 它的实现与设计模式中的工厂模式和修饰器模式类似。