本文是我学习中遇到的知识盲区,作为学习笔记,如果有不对的地方,谢谢更正
静态变量或方法需要注意的点
- 随着类的加载而加载,声明周期与类一致
- 静态方法中不能使用this、super
- 多个静态代码块从上至下依次执行
- 静态代码快只随着类加载,运行期间只运行依次
代码中关于子父类代码执行顺序
符类静态成员变量
父类静态代码块
子类静态成员变量
子类静态代码块
父类普通代码块
子类普通代码块
父类构造函数
子类构造函数
运算符优先级,越往下优先级越低
类别 | 运算符 | 结合性 |
---|---|---|
后缀 | () [] -> . ++ - - | 从左到右 |
一元 | + - ! ~ ++ - - (type)* & sizeof | 从右到左 |
乘除 | * / % | 从右到左 |
一元 | + - | 从左到右 |
移位 | << >> | 从左到右 |
关系 | < <= > >= | 从左到右 |
相等 | == != | 从左到右 |
位与 | AND & | 从左到右 |
位异或 | XOR ^ | 从左到右 |
位或 | OR ` | ` |
逻辑与 | AND && | 从左到右 |
逻辑与 | OR ` | |
条件 | ?: | 从右到左 |
赋值 | = += -= *= /= %= >>= <<= &=(与等) ^=(异或) ` | `=(或等) |
int n =22; => 00010110
//n>>>1 n左移一位为 00001011 =11
n |= n>>>1 => 00010110
或(|)
00001011
00011111
31 //赋值给nn => 31
两个线程并发问题
1.A、B线程不并发,则A完全执行完毕,B在执行
2.A、B线程部分并发,则A完成部分后, B在执行
3.A、B线程并发,则A执行同时,B也在执行
JVM相关知识点
通过JVMJVM 类加载的五个阶段
- 加载
- 检查
- 准备
- 解析
- 初始化
JVM虚拟机的五大模块:
- 类装载器子系统
- 运行时数据区
- 执行引擎
- 本地方法接口
- 垃圾收集模块
类加载器
启动类加载器(BootStrap classLoder)
扩展类加载器(extension classLoder)
应用程序类加载器(application classLoder)
线程共享区 堆(heap),方法区
线程独占去,虚拟机栈,本地方法栈,程序计数器(PC寄存器)
虚拟栈中是一个个栈帧,
栈帧中包含:局部变量区,操作数栈,动态链接,方法出口
JVM运行时内存
分为新生代和老年代
实现线程间通知和唤醒
两种方式
- Condition.await/signal/signalAll
- Object.wait/notify/notifyAll
对象实例化方法
用户不能调用构造方法,只能通过new关键字自动调用 (x)
解析
1.使用new创建对象会自动调用构造方法
Person person=new Person();
2.使用Class类的newInstance方***调用构造方法
Person person=(Person) Class.forName(“com.Person”).newInstance();
3.用反射中的constructor类 的newInstance 调用构造方法
Constructor constructor=Person.class.getConstructor ();
Person person=constructor.newInstance();
2.3均属于反射机制
上面三中创建对象的时候回自动调用构造方法,
但不是所有的创建对象的时候会调用,比如clone方法(对象的复制),
序列化的时候也会创建对象,这是有jvm创建的,所以也不会调用
Java基础类型坑
Java中有常量池,有几种基础类型的包装类也应用了常量池技术,
包装类 | 常量池应用 | 常量池数据范围 |
---|---|---|
Byte | 是 | -128–127 |
Short | 是 | -128–127 |
Integer | 是 | -128–127 |
Long | 是 | -128–127 |
Character | 是 | 0–127 |
Boolean | 是 | true ,false |
Float | 否 | 无 |
Double | 否 | 无 |
Integer 缓存源码
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
high = h;
}
创建几个对象,输出结果?
Integer a =5; -> 相当于 Integer a = Integer.valueOf(5)
Integer b = new Integer(5);
System.out.println(a ==b);
System.out.println(a.equals(b));
创建几个对象,输出结果?
Integer c =129;
Integer d = new Integer(129);
System.out.println(c ==d);
System.out.println(c.equals(d));
创建几个对象,输出结果?
Integer aa = 5;
Integer bb=5;
Integer cc=131;
Integer dd = 131;
System.out.println(aa == bb);
System.out.println(aa.equals(bb));
System.out.println(cc == dd);
System.out.println(cc.equals( dd));
1答案 :创建一个对象
2答案 :创建两个对象 ,129 超出常量池缓存,则为创建新对象
3答案:创建2个对象 ,小于5 则引用常量池中,则应用和值都一样,而不在-128-127 则需要重新创建对象
使用equals 是进行值比较。
Short s1=1;s1=s1+1;和Short s1 = 1,s1 +=1; 两个操作有没有异常,为什么
答: Short s1=1;s1=s1+1;会报异常,s1 是short 类型,1 是int 类型,s1 + 1 运算后会变成 int 类型,java 整形默认类型为int 类型,昨晚运算,会自动上转型,将 int 类型赋值给short 类型为下转型,需要强制转换,所以会报异常
Short s1 = 1,s1 +=1;没有异常,因为 +=是赋值运算符,则1 是short 类型 ,short +short 还是short类型