1. 两个Integer用 == 比较是否相等
Integer a1 = 127;
Integer b1 = 127;
if(a1 == b1){
System.out.println("相等");
}else{
System.out.println("不相等");
}
Integer a = 128;
Integer b = 128;
if(a == b){
System.out.println("相等");
}else{
System.out.println("不相等");
}
输出结果 相等 不相等
结论: 就是Integer大与等于128的时候是不相等的; Jvm会自动维护8中基本类型的常量池,int常量池维护的大小是-128~127的,所以当Integer是127时,在自动装箱的过程中取得是常量池中的数据,所以两个是相等的,而超过了这个范围之后,自动装箱就会new Integer(128),这个时候就是重新创建的两个对象,就会不相等;
对于这种基本类型的对象来说==比较的是两个对象的引用地址,而不是两个对象内存的值;要想比较两个基本类型的值可以通过equals()方法比较
2. 是否可以在子线程进行startActivity()
btn0.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable() {
@Override
public void run() {
Intent intent = new Intent(context, MainActivity1.class);
startActivity(intent);
}
}).start();
}
});
经过测试,可以正常的启动MainActivity1。经过查阅源码后发现,Activity的startActivity方法,经过一层一层调用,并没有检测过线程,所以是可以在子线程中启动Activity的。
3. final关键字
首先,final 是一个非访问修饰符仅适用于变量,方法或类。
- 当final修饰 变量 时,被修饰的变量必须被初始化(赋值),且后续不能修改其值,实质上是常量;
- 当final修饰 方法 时,被修饰的方法不能被所在类的子类重写;
- 当final修饰 类 时,被修饰的类不能被继承,并且final类中的所有成员方法,都会被隐式的指定为final方法;但成员变量则不会变
何时使用final变量:
普通变量和final变量之间的唯一区别是我们可以将值重新赋值给普通变量;但是对于final变量,一旦赋值,我们就不能改变final变量的值。因此,final变量必须仅用于我们希望在整个程序执行期间保持不变的值。
(1). final修饰引用变量
final修饰引用变量的时候,不能重新赋值,但是可以更改引用对象的内部状态。注意这里不是重新赋值;final的这个属性叫做非传递性
//比如
final StringBuffer sb = new StringBuffer("initstring");
System.out.println(sb.toString());
sb.append(" append string");
System.out.println(sb.toString());
//输出
initstring
initstring append string
这个非传递性也适合数组,因为java中数组也是对象,fianl修饰的数组也叫final数组
- 其次,final修饰的变量可以创建时不初始化,但是必须在创建它的位置进行初始化 如下面
static final int CAPACITY;
public static void main(String argv[]){
CAPACITY = 3;
}
//输出报错
Compiler Error: cannot assign a value to final variable CAPACITY
静态变量的final变量要么创建的时候就初始化,要么在静态块中进行初始化
public static void main(String argv[]){
final int a;
a = 3;
System.out.println(a);
}
//输出结果
3
这里就是在创建的位置进行初始化,也可以直接这样写,原理是一样的。
final int a = 3;
(2). final修饰类
final与匿名内部类
匿名类(Anonymous Class)虽然说同样不能被继承,但它们并没有被编译器限制成final。另外要提到的是,网上有许多地方都说因为使用内部类,会有两个地方必须需要使用 final 修饰符:
- 在内部类的方法使用到方法中定义的局部变量,则该局部变量需要添加 final 修饰符
- 在内部类的方法形参使用到外部传过来的变量,则形参需要添加 final 修饰符
(3). fianl 修饰方法
- 被private修饰的方法会默认被指定为final方法
- 在java中永远不会看到同时被abstract和final一起修饰的方法;final是为了防止被子类重写,而abstrace是抽象方法为了让子类重写,所以这两个不会同时修饰同一个方法
3. java双亲委托机制简述
- 将某个特定的类接到类加载通知的时候,首先把加载任务委托给父类加载器,一次递归到顶层之后,如果父类能找到相应的类,则成功返回,若父类无法找到对应的类,就传递给子类。 如果A类引用了B类,则将使用A类的加载器加载B类
类加载器存在缓存,如果某个加载器以前成功加载过某个类后,再次接受到此类加载请求则直接返回,不再向上传递加载请求
-
上下文类加载器
-
对于类加载器而言,都保存有其父类加载器,也就是有parent字段,可以使用双亲委托,也就是自下而上的去委托给父类加载。
-
而对于有些类,- SPI(Service Provider Interface)有些接口是 Java 核心库所提供的,而 Java 核心库是由启动类加载器【Bootstrap类加载器】来加载的,而这些接口的实现却来自于不同的 jar 包(厂商提供),Java 的启动类加载器是不会加载其他来源的 jar 包【存在于classPath路径,由应用程序类加载器:Application Classloader加载(是BootStrap的子类)】,这样传统的双亲委托模型就无法满足 SPI 的要求。而通过给当前线程设置上下文类加载器,就可以由设置的上下文类加载器来实现对于接口实现类的加载。
4.finalize()方法
//VolatileThread.class
public class VolatileThread {
@Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("d调用了finalize");
}
}
//main.class
public static void main(String[] args) {
ArrayList<VolatileThread> list = new ArrayList<>();//1
VolatileThread a = new VolatileThread();//2
list.add(a);//3
a = null;//4
list.clear();//5
System.gc();//6
System.out.println("垃圾回收");
}
fianlize()方法是在某一个对象被gc回收的时候,该对象会调用这个方法。上面代码中,如果只赋值给a对象为null是不会调用VolatileThread对象的finalize()方法的,因为其还有list在引用,垃圾回收的时候不会回收此对象,当list.clear()之后, VolatileThread a;才真正属于无用对象,这时才会进行垃圾回收
4. synchronized 和 voliate;AtomicInteger
5. 线程池,几种线程池,和几个核心参数
线程池五个核心参数;
corePoolSize : 核心线程大小;线程池一直运行,核心线程就不会停止;
maxinumPoolSize: 最大线程池数量;非核心线程数=maxinumPoolSize - corePoolSize;
keepAliveTime:非核心线程的心跳时间;如果非核心线程在keepAliveTime的时间内没有运行任务,非核心线程就会消亡;
workQueue:阻塞队列,存放在阻塞中的线程队列;
defaultHandler:饱和策略;
ThreadFactory:线程工厂;新建线程工厂。
HashMap,HashTable,Set,List,等数据结构
Throwable和 Exception的区别和联系
6. java方法传参,
7. java内存模型,java内存分区,垃圾回收机制,几种引用(强,软,弱,虚)
红黑树
Android中什么是内存泄漏,什么是内存溢出,两者有啥区别,怎么查找内存泄漏
6. Android Binder跨进程通讯
Android性能和UI优化
Android的四种启动模式
Android签名,dex分包,handler,内存泄漏,recyclerview
Android onSavedInstanceState方法
内存不足时,由系统销毁一个Activity时,onSaveInstanceState() 会被调用。但是当用户主动去销毁一个Activity时,例如在应用中按返回键,onSaveInstanceState()就不会被调用
onSaveInstanceState(Bundle) 方法会在 Activity 被 kill 掉之前调用。假设 Activity B 被启动,Activity A 可能会因为资源回收的原因,被 Kill 掉,那么当从 Activity B 回到 Activity A 的时候,你可以从 onCreate(Bundle) 或者 onRestoreInstanceState(Bundle) 方法获得之前保存的状态(state)。
而直接启动Activity A onCreate(Bundle)方法中的bundle是为null的。
- 在屏幕旋转的时候也会调用
onSaveInstanceState(Bundle),并且onCreate(Bundle)中参数部不为null
savedInstanceState 只用来存储 Activity 有关系的数据,这些数据的生命周期和 Activity 相关。这种是数据可以认为是临时数据,并不是持久数据(persistent data)。一般情况下,它比较适合存储用户的临时表单数据之类的数据。如果有需要持久存储的数据,应该在 onPause() 方法中保存数据。不能在onStop()方法中保存,因为如果
事实上,onSaveInstanceState(Bundle) 方法并不是 Activity 生命周期的方法。
Android中activity,context,application有什么不同。
参考 Activity、Service和Application的Context的区别
ContextImpl用Android studio和eclipse查看差不到,需要在Android sdk中找,路径是android.app.ContextImpl中,