static
静态方法只能访问静态成员,不可以访问非静态成员。
静态方法中不能使用this,super关键字。
什么时候方法需要静态?当方法只访问静态成员时。
成员变量和静态变量的区别:
成员变量存在于堆内存中(因为整个对象都存储在堆中),静态变量存在于方法区中。
类里的static代码块,静态块?
public class StaticBlock {
static {
System.out.println("静态块");
}
{
System.out.println("构造块,在类中定义");
}
public StaticBlock() {
System.out.println("构造方法执行");
}
public static void main(String[] args) {
new StaticBlock();
new StaticBlock();
}
}
分析:代码块分为静态块、非静态块、构造函数块。
静态代码块是在类加载时自动执行的,非静态代码块是在创建对象时自动执行的代码,不创建对象不执行该类的非静态代码块。且执行顺序为静态代码块------非静态代码块----构造函数。
Static 块仅在该类被加载时执行一次!!
运行结果:
静态块
构造块,在类中定义
构造方法执行
构造块,在类中定义
构造方法执行
final关键字
1:这个关键字是一个修饰符,可以修饰类,方法,变量。
2:被final修饰的类是一个最终类,不可以被继承。
3:被final修饰的方法是一个最终方法,不可以被覆盖。
4:被final修饰的变量是一个常量,只能赋值一次。
位运算符
用于操作二进制位的运算符。
& , |, ^ , << , >> , >>>(无符号右移)
练习:对两个变量的数据进行互换。不需要第三方变量。
int a = 3,b = 5;
a = a + b; a = 8;
b = a - b; b = 3;
a = a - b; a = 5;
a = a ^ b;//
b = a ^ b;//b = a ^ b ^ b = a
a = a ^ b;//a = a ^ b ^ a = b;
计算2*8 可以用移位 2<<3 (左移n位表示变成原来的2^n倍)
public/private/protected/default(默认不写)
default:表示默认范围,就是在同一包下才可以访问。
作用域 当前类 同一package 子孙类 其他package
public √ √ √ √
protected √ √ √ ×
default √ √ × ×
private √ × × ×
内存
java分了5片内存。
1:寄存器。2:本地方法区。3:方法区。4:栈。5:堆
栈:存储的都是局部变量 ( 函数中定义的变量,函数上的参数,语句中的变量 );只要数据运算完成所在的区域结束,该数据就会被释放。
堆:用于存储数组和对象,也就是实体。
1:每一个实体都有内存首地址值。
2:堆内存中的变量都有默认初始化值。因为数据类型不同,值也不一样。
3:垃圾回收机制。
例:
A a=new A();
a就是句柄,是引用类型的变量只是一个普通变量,储存了引用类型的地址,存储在栈内存中。
new出来的对象是存放在堆内存中,要想调用它则要通过它的引用类型a中的地址进行调用。
抽象类
抽象关键字abstract和哪些不可以共存?final , private , static
抽象类中抽象方法的个数是:0-多个,也就是可以没有抽象方法。
设计模式
解决问题最行之有效的思想。是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。
java中有23种设计模式。
单例设计模式:★★★★★
解决的问题:保证一个类在内存中的对象唯一性。
比如:多程序读取一个配置文件时,建议配置文件封装成对象。会方便操作其中数据,又要保证多个程序读到的是同一个配置文件对象,就需要该配置文件对象在内存中是唯一的。
Runtime()方法就是单例设计模式进行设计的。
如何保证对象唯一性呢?
步骤:
1,因为创建对象都需要构造函数初始化,只要将本类中的构造函数私有化,其他程序就无法再创建该类对象;
2,就在类中创建一个本类的对象;
3,定义一个方法,返回该对象,让其他程序可以通过方法就得到本类对象。(作用:可控)
代码体现:
1,私有化构造函数;
2,创建私有并静态的本类对象;
3,定义公有并静态的方法,返回该对象。
//饿汉式
class Single{
private Single(){} //私有化构造函数。
private static Single s = new Single(); //创建私有并静态的本类对象。
public static Single getInstance(){ //定义公有并静态的方法,返回该对象。
return s;
}
}
//懒汉式:延迟加载方式。
class Single2{
private Single2(){}
private static Single2 s = null;
public static Single2 getInstance(){
if(s==null)
s = new Single2();
return s;
}
}
线程
线程sleep()和wait()区别:
sleep: 是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。
wait: 是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。
有关JVM
JVM加载class文件的原理机制:
在Java中,类装载器把一个类装入Java虚拟机中,要经过三个步骤来完成:装载、链接和初始化,其中链接又可以分成校验、准备、解析
装载:查找和导入类或接口的二进制数据;
链接:执行下面的校验、准备和解析步骤,其中解析步骤是可以选择的;
校验:检查导入类或接口的二进制数据的正确性;
准备:给类的静态变量分配并初始化存储空间;
解析:将符号引用转成直接引用;
初始化:激活类的静态变量,初始化Java代码和静态Java代码块