数值操作类型转换
class CompareReference{public static void main(String [] args){float f=42.0f;float f1[]=new float[2];float f2[]=new float[2];float[] f3=f1;long x=42;f1[0]=42.0f;}
}
A f1==f2
B x==f1[0]
C f1==f3
D f2==f1[1]
BC正确,选项B解释,java核心卷I中43页有如下表述:两个数值进行二元操作时,会有如下的转换操作: 如果两个操作数其中有一个是double类型,另一个操作就会转换为double类型。 否则,如果其中一个操作数是float类型,另一个将会转换为float类型。 否则,如果其中一个操作数是long类型,另一个会转换为long类型。 否则,两个操作数都转换为int类型。 故,x==f1[0]中,x将会转换为float类型。
B选项:x == f1[0],x是long类型,与float类型对比属于低精度,所以x要向高精度的float类型转型再比较,故相等;
C选项:f1 == f3,f3没有new创建,而是由f1赋值,所以f3地址是指向f1的,f1值改变,相当于改变f3值,所以相等。
关于Spring AOP的几种通知方式,下列说法错误的是
A. 前置通知会在执行目标方法之前运行。
B. 目标方法运行结束之后,无论有没有异常发生后置通知都会触发。
C. 目标方法出现异常后会触发异常通知,然后才会触发返回通知。
D. 环绕通知可以决定目标方法的调用也可以控制返回对象。
正确答案是:C。
在Spring AOP(面向切面编程)中,有几种不同类型的通知,每种通知都有其特定的调用时机和用途。具体如下:
- 前置通知(@Before):这种通知在目标方法执行之前运行。它们不会接收任何有关目标方法执行结果的信息,因为它们仅在方法执行前被调用。
- 后置通知(@After):这种通知在目标方法执行之后运行,不论目标方法是否成功完成或抛出异常,后置通知都将被触发。
- 返回通知(@AfterReturning):这种通知仅在目标方法成功完成后执行,并且可以访问返回值。
- 异常通知(@AfterThrowing):当目标方法抛出异常时,会触发异常通知。
- 环绕通知(@Around):环绕通知提供了对目标方法执行的完全控制。可以在方法调用前后执行自定义操作,并有能力控制是否执行目标方法以及是否修改返回值。环绕通知通过
ProceedingJoinPoint
来显式调用目标方法。
选项C中提到“目标方法出现异常后会触发异常通知,然后才会触发返回通知。”是错误的,因为异常通知和返回通知是两种不同的通知类型,它们的触发条件是不同的。异常通知仅在方法抛出异常时触发,而返回通知是在方法正常返回结果时触发。如果目标方法抛出了异常,那么返回通知将不会触发。因此,这两种通知之间没有先后顺序的关系,它们的触发取决于目标方法的执行结果是正常返回还是抛出异常。
@PostContruct、@PreDestroy
@PostConstruct
和 @PreDestroy
是 Java EE 5 引入的两个注解,用于在依赖注入完成后执行一些初始化操作,以及在对象销毁前执行一些清理操作。这两个注解通常用在 Spring 框架中,与 @Component
、@Service
、@Repository
等注解一起使用。
@PostConstruct
:这个注解用于标记一个方法,该方法会在依赖注入完成后自动被调用。这对于那些需要在对象创建后进行初始化操作的场景非常有用,例如打开数据库连接、加载配置文件等。
举例:
import javax.annotation.PostConstruct;@Service
public class MyService {@PostConstructpublic void init() {System.out.println("MyService 初始化完成");}
}
@PreDestroy
:这个注解用于标记一个方法,该方法会在对象销毁前自动被调用。这对于那些需要在对象销毁前进行清理操作的场景非常有用,例如关闭数据库连接、释放资源等。
举例:
import javax.annotation.PreDestroy;@Service
public class MyService {@PreDestroypublic void destroy() {System.out.println("MyService 销毁前执行清理操作");}
}
注意:@PostConstruct
和 @PreDestroy
注解需要与 Spring 框架一起使用,不能单独使用。
Spring 事务隔离级别
传播类型 | 如果当前无事务 | 如果当前有事务 |
---|---|---|
PROPAGATION_NEVER | 不创建新的事务,在无事务的状态下执行方法 | 抛异常 |
PROPAGATION_NOT_SUPPORTED | 不创建新的事务,在无事务的状态下执行方法 | 暂停当前事务,在无事务的状态下执行方法 |
PROPAGATION_SUPPORTS | 不创建新的事务,在无事务的状态下执行方法 | 使用当前事务 |
PROPAGATION_REQUIRED(默认) | 创建新的事务 | 使用当前事务 |
PROPAGATION_REQUIRES_NEW | 创建新的事务 | 暂停当前事务,创建新的独立事务 |
PROPAGATION_NESTED | 创建新的事务 | 创建新的内嵌事务 |
PROPAGATION_MANDATORY | 抛异常 | 使用当前事务 |
SpringApplication调用的run方法执行流程如下:
-
初始化监听器,以及添加到SpringApplication的自定义监听器。
-
发布ApplicationStartedEvent事件,如果想监听ApplicationStartedEvent事件,你可以这样定义:public class ApplicationStartedListener implements ApplicationListener,然后通过SpringApplication.addListener(…)添加进去即可。
-
装配参数和环境,确定是web环境还是非web环境。
-
装配完环境后,就触发ApplicationEnvironmentPreparedEvent事件。
-
如果SpringApplication的showBanner属性被设置为true,则打印启动的Banner。
-
创建ApplicationContext,会根据是否是web环境,来决定创建什么类型的ApplicationContext。
-
装配Context的环境变量,注册Initializers、beanNameGenerator等。
-
发布ApplicationPreparedEvent事件。
-
注册springApplicationArguments、springBootBanner,加载资源等
-
遍历调用所有SpringApplicationRunListener的contextLoaded()方法。
-
调用ApplicationContext的refresh()方法,装配context beanfactory等非常重要的核心组件。
-
查找当前ApplicationContext中是否注册有CommandLineRunner,如果有,则遍历执行它们。
-
发布ApplicationReadyEvent事件,启动完毕,表示服务已经可以开始正常提供服务了。通常我们这里会监听这个事件来打印一些监控性质的日志,表示应用正常启动了。
Collection 接口常用的方法
Collection接口定义了多种方法,这些方法适用于其所有的子接口和实现类,如List、Set和Queue。以下是Collection接口中一些常用的方法:
- add(E e):向集合中添加一个元素。
- addAll(Collection<? extends E> c):将指定集合中的所有元素添加到此集合。
- size():返回集合中的元素个数。
- isEmpty():判断集合是否为空。
- clear():移除集合中的所有元素。
- contains(Object o):判断集合中是否包含指定的元素。
- iterator():返回一个迭代器,用于遍历集合中的元素。
- toArray():将集合转化为数组。
- remove(Object o):从集合中移除指定元素的第一个出现。
- removeAll(Collection<?> c):从集合中移除所有存在于指定集合中的元素。
- retainAll(Collection<?> c):仅保留集合中那些也包含在指定集合中的元素;换句话说,删除集合中所有不在指定集合中的元素。
- containsAll(Collection<?> c):如果集合中包含指定集合中的所有元素,则返回 true。
综上所述,这些方法为集合操作提供了基础功能,使得开发者能够方便地对集合进行增删查改等基本操作。在使用Collection接口及其子接口和实现类时,这些方法是非常实用的工具。