java小贴士

1 值传递与引用传递

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
int num = 10;
String str = "hello"
//第一个例子:基本类型
void foo(int value) {
value = 100;
}
foo(num); // num 没有被改变

//第二个例子:引用类型
void foo(String text) {
text = "windows";
}
foo(str);
// str 也没有被改变,这个过程其实是先分配一块内存并创建一个新的引用text,再将text指向了str的值hello,text = "windows"这个操作又将text指向了值为windows的对象,因此str没有改变。第三个第四个例子也可以这样理解。

//第三个例子:提供了改变自身方法的引用类型
StringBuilder sb = new StringBuilder("iphone");
void foo(StringBuilder builder) {
builder.append("4");
}
foo(sb); // sb 被改变了,变成了"iphone4"。

//第四个例子:提供了改变自身方法的引用类型,但是不使用,而是使用赋值运算符。
StringBuilder sb = new StringBuilder("iphone");
void foo(StringBuilder builder) {
builder = new StringBuilder("ipad");
}
foo(sb); // sb 没有被改变,还是 "iphone"。

2 变量的存储位置

3 default

java8中,新增一个关键字default,它允许接口中的方法拥有方法体,实现该接口的类bu可以不实现该方法。这个关键字在集合框架中使用过。

1
2
3
4
5
public interface Default {
default public void method(){
System.out.println("method in interface");
}
}

1
2
3
4
5
6
7
8
9
10
11
12
public interface Iterable<T> {
Iterator<T> iterator();
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
default Spliterator<T> spliterator() {
return Spliterators.spliteratorUnknownSize(iterator(), 0);
}
}

4 transient

被transient修饰的变量不会被序列化

5 volatile

cas技术的应用,在ConCurrentHashMap中的使用

6 锁机制

synchronized与lock

7 线程间通信

轮询
join
countdownlatch
CyclicBarrier
返回结果 futuretask

8

如果在一个线程计算过程中不允许有更大的本地方法栈,那么JVM就抛出StackOverflowError

如果本地方法栈可以动态地扩展,并且本地方法栈尝试过扩展了,但是没有足够的内容分配给它,再或者没有足够的内存为线程建立初始化本地方法栈,那么JVM抛出的就是OutOfMemoryError。

9 handler机制

A. Android应用程序的消息处理机制由消息循环、消息发送和消息处理三个部分组成的。
B. Android应用程序的主线程在进入消息循环过程前,会在内部创建一个Linux管道(Pipe),这个管道的作用是使得Android应用程序主线程在消息队列为空时可以进入空闲等待状态,并且使得当应用程序的消息队列有消息需要处理时唤醒应用程序的主线程。
C. Android应用程序的主线程进入空闲等待状态的方式实际上就是在管道的读端等待管道中有新的内容可读,具体来说就是是通过Linux系统的Epoll机制中的epoll_wait函数进行的。
D. 当往Android应用程序的消息队列中加入新的消息时,会同时往管道中的写端写入内容,通过这种方式就可以唤醒正在等待消息到来的应用程序主线程。 E. 当应用程序主线程在进入空闲等待前,会认为当前线程处理空闲状态,于是就会调用那些已经注册了的IdleHandler接口,使得应用程序有机会在空闲的时候处理一些事情。

10 activity栈管理

AMS activitymanagerservice 负责
activityrecord taskrecord activitystack都是ams抽象出来的概念

11 网络

okhttp

12 concurrenthashmap

13 IPC

14 Future

FutureTask 实现了Future和Runnable,FutureTask本质还是一个runnable,但是FutureTask中有Callable的引用,在线程执行run时,会调用call,所以对于FutureTask来说,真正的执行位置是callable

AsyncTask也是使用了Future,有两个线程池,一个用于真正执行,有核心线程数和最大线程数的限制,另一个维护一个队列用于给任务排序。AsyncTask是序列执行任务的。一个应用中所有的AsyncTask共享同一个线程池。

15 访问修饰符

类访问修饰符有default和public两种,public是任何其他类都可以访问,default是只有包内可以访问,包内指同一级目录
方法和成员变量访问修饰符有public、protected、default、private四种:其中public是任何类都能访问到,protected是子类可以访问,default是包内可以访问,private是是有类内部可以访问
需要特殊注意的是内部类
内部类不管是普通内部类还是静态内部类都可以访问外部类的所有变量

16 类型转换

1
2
short i = 1;
i = i + 1;

上面代码有问题么?答案是有,需要强制类型转换

17 & &&

Java中&&和&都是表示与的逻辑运算符,都表示逻辑运输符and,当两边的表达式都为true的时候,整个运算结果才为true,否则为false。
&&的短路功能,当第一个表达式的值为false的时候,则不再计算第二个表达式;&则两个表达式都执行。
&可以用作位运算符,当&两边的表达式不是Boolean类型的时候,&表示按位操作。

18 面向对象