staic
static修饰属性:类变量/类成员
类变量与成员变量的区别:
成员变量:内存分配时机:实例化的时候,在内存中位置:堆中,彼此独立;访问方式:只能通过对象访问
类变量:内存分配时机:实加载的时候,在内存中位置:方法区,所有实例共享;访问方式:可以通过对象访问,也可以通过类名直接访问(推荐)
上代码:
public class Test7 {
//每个实例都有一份,
// 实例就是一个类可以new出多个对象,对象也可以叫实例一个概念
int i = 10;
//在内存中j只有一份,被所有实例共享
static int j = 10;
public static void main(String[] args) {
Test7 t1 = new Test7();
t1.i++; //访问自己数据 11
t1.j++; //访问内存同一份数据 11
System.out.println(t1.i); //11
Test7 t2 = new Test7();
t2.i++; //访问自己数据 11
t2.j++; //访问内存同一份数据 12
Test7.j++;//访问内存同一份数据 13
System.out.println( Test7.j);
}
}
static修饰方法:类方法
类方法: 在同一个类中,静态方法只能访问其他的静态资源(包括方法和属性)类与类之间,静态方法可以通过对象访问,也可以通过类名直接访问(推荐) 静态方法中不能使用this,super
成员方法:在同一个类中,成员方法所有资源(包括静态的和非静态的)都可以访问类与类之间,只能通过对象访问
public class Test7 {
public static void f(){
System.out.println("f");
}
public void ff(){
System.out.println("f");
}
public static void main(String[] args) {
//静态方法
Test7.f();
//实例方法通过new对象
Test7 test7 = new Test7();
test7.ff();
test7.f();//也可以通过实例访问类方法
}
}
static修饰代码块:静态代码块
静态代码块的作用:初始化类,类加载时候执行,只执行1次。
非静态代码块的作用:初始化对象(和构造函数相同),实例化对象的时候执行,每次实例化都会执行。
上代码:
public class Test7 {
public static void main(String[] args) {
Child child1 = new Child();
Child child2 = new Child();
}
}
class Base{
/**
* 静态代码块在构造器执行之前执行
* 类加载时执行,并且只执行一次
*/
static {
System.out.println("调用父类静态代码块");
}
/**
* 非静态代码块在,在构造器之前
*/
{
System.out.println("调用父类非静态代码块");
}
public Base() {
System.out.println("调用父类构造器");
}
}
class Child extends Base{
/**
* 静态代码块在构造器执行之前执行
* 类加载时执行,并且只执行一次
*/
static {
System.out.println("调用子类静态代码块");
}
/**
* 非静态代码块在,在构造器之前
*/
{
System.out.println("调用子类非静态代码块");
}
public Child() {
System.out.println("调用子类构造器");
}
}
打印结果:
调用父类静态代码块
调用子类静态代码块
调用父类非静态代码块
调用父类构造器
调用子类非静态代码块
调用子类构造器
调用父类非静态代码块
调用父类构造器
调用子类非静态代码块
调用子类构造器
总结:
1.所有静态代码块先执行,只执行一次。先是父类后市子类。
2.每次创建对象都会调用父类非静态代码块调用父类构造器。
静态方式是否能重写
同名静态方法调用哪个不是取决于对象的实际类型,而是看引用的类型,所以静态方法不认为能够重写
public class Test8 {
public static void main(String[] args) {
A a = new B();
a.ff();
a.f();
}
}
class A{
public static void f(){
System.out.println("父类静态方法f");
}
public void ff(){
System.out.println("父类非静态方法ff");
}
}
class B extends A{
public static void f(){
System.out.println("子类静态方法f");
}
public void ff(){
System.out.println("子类非静态方法ff");
}
}
打印结果:
子类非静态方法ff
父类静态方法f
this
this是指向自己的指针,只能用在非静态的方法里。
- 通过this,访问同一个类里的其它成员(非静态)
- 访问同一个类中的其它构造:构造函数的第1行:this(参数列表)
- 访问同一个类中的除了构造以外的其它非静态成员:this.属性名; - this.方法名(参数列表)
this可以省略的情况:
- 访问同一个类中的除了构造以外的其它非静态成员,this可以省
- this不可以省略的情况:
- 访问同一个类中的其它构造,this不能省
- 代码中区分同名的局部变量和成员变量, this不能省
/**
* 微信公众号:Java后端分享
* 个人站点:http://www.njlife123.com
*/
public class Test9 {
int i;
int j;
public Test9() {
super();
}
public Test9(int i) {
this.i = i;
}
public Test9(int i, int j) {
//调用一个类的其他构造器不能省略
this(i);
this.j = j;//不能省略
}
public void f1(){
System.out.println("f1");
//调用一个类的其他方法可以省略
this.f2();
System.out.println(this.i);//可以省略
}
public void f2(){
System.out.println("f2");
}
}
super
- super:指向父类的指针,只能用在非静态的方法里。
- super调用父类的构造:构造函数的第1行:super(参数列表)
- super调用父类的其它属性:super.属性; super.方法名(参数列表)
上代码:
/**
* 微信公众号:Java后端分享
* 个人站点:http://www.njlife123.com
*/
class E {
int i =10;
public void f(){
System.out.println("调用父类的方法");
}
}
class D extends E{
int i =20;
public void f(){
System.out.println("子类的方法");
super.f();//调用父类的方法
System.out.println(i);
System.out.println(super.i);//调用父类的属性
}
}
public class Test10 {
public static void main(String[] args) {
E e = new D();
e.f();
}
}
打印结果:
子类的方法
调用父类的方法
20
10
Process finished with exit code 0
垃圾回收
garbage collect: 简称 gc
哪些对象可以被回收:当一个对象没有被程序中处于活动状态的部分所引用时,此对象就成为了一个垃圾对象或者说无用对象,java虚拟机会不定时去检测这样的对象,检测到无用对象则会释放其所占的内存:
T t=new T();//创建了一个对象
t=null;//上面创建的对象不能够被程序引用,成为了垃圾对象。虚拟机在执行下次检测的时候,会将其所占的内存释放掉。
垃圾回收的通知机制:当虚拟机即将回收一个对象的时候,会调用这个对象的finalize方法通知它,以便让此对象做一些清理工作(关闭文件,释放数据库连接等等)
System类中有一个方法:gc(); 作用:建议虚拟机执行一次垃圾回收。是否执行以及何时执行都是不确定的。