前几天整理的面经

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, 它的实现与设计模式中的工厂模式和修饰器模式类似。

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值