类的属性
类的属性可分为成员变量和局部变量其相同点与不同点如下
- 相同点:
- 遵循变量的声明格式即 数据类型 变量名 = 初始化值;
- 都有作用域。
- 不同点:
- 声明的位置不同:成员变量声明在类里方法外,局部变量声明在方法内、形参列表中、方法块内;
- 成员变量访问权限修饰符有:public private protected 缺省(default),局部变量没有修饰符;
- 初始化值:成员变量如果在声明的时候不显示的赋值,那么不同数据类型会有不同的默认初始化值:
byte short int long >>>>> 0
float double >>>>>> 0.0
char >>>>>> 空格
boolean >>>> false
引用类型变量 >>>>>>> null
局部变量没有默认的初始化值,一定要显示的赋值如图所示。
- 二者在内存中存放的位置不同 :局部变量存放在栈空间中,成员变量存放在堆空间中。
访问权限修饰符
Java中有四种访问权限修饰符 public private protected default(缺省)置于类的成员定义前(如成员方法、成员变量),用于限定对象对该类成员的访问权限。
修饰符 | 类内部 | 同一个包 | 子类 | 任何地方 |
---|---|---|---|---|
private | yes | |||
default | yes | yes | ||
protected | yes | yes | yes | |
public | yes | yes | yes | yes |
- 对于类(class)的权限修饰符只有public 和default 。
- public 类可以在任意地方被访问。
- default 类只可以被同一个包内部的类访问。
方法的重载(overload)与重写(overwrite)
- 方法的重载发生在同一个类中且方法名相同,方法的参数列表不同(包含参数的个数、参数的类型不同),与方法的返回值以及方法的权限修饰符没有关系。
- 方法的重写发生在有继承关系的子类里,当父类里的方法对子类不适用时可以对父类的方法进行重写。当重写父类方法时的要求:
- 子类对重写方法的 “返回值类型、方法名、参数列表” 与父类的一样;
- 子类方法的访问修饰符要大于等于父类方法的访问修饰符;
- 子类抛出的异常不能大于父类抛出的异常或者不抛出异常。
ps:不能重写父类 static类型的方法,因为静态方法属于类本身。如果子类中也含有一个返回类型、方法名、参数列表均与之相同的静态方法,那么该子类实际上只是将父类中的该同名方法进行了隐藏,而非重写。
static 关键字
static 可以用来修饰属性、方法、代码块、内部类。
- 当 static 关键字修饰属性时被称之为类属性,由该类创建的对象都会共用这一属性,当其中一个对象对此属性修改时会导致其他对象也会发生改变;
- 当 static 修饰方法时被称之为类方法,可以直接通过类直接调用,也具有唯一性即由该类所创建的对象都会共用这一方法;
- 被 static 修饰的代码块也叫静态代码块,通常是把只进行一次的初始化操作放在代码块中以优化程序性能,避免重复开辟内存。static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次;
- static也可以用来修饰内部类,也就是静态内部类,可以避免非静态内部类持有外部类引用导致内存泄漏的问题。
JVM运行时数据区(内存)分为两部分,线程私有和线程共享两块区域;线程私有区分为程序计数器,本地方法栈,虚拟机栈,而线程共享区分为堆(heap)和方法区,堆主要用来存放new出来的对象,而方法区存放常量,静态变量,静态方法,类的信息等;这样即使对象没有被创建出来,但是类加载的时候类信息和静态方法已经存在方法区了,所以以下代码在运行时并不会报异常:
public class Base{
public static void log(){
System.out.print("call Base");
}
public static void main(String[] args){
Base test = null;
System.out.print(test.log());//此处调用不会报错
}
}
final关键字
在Java中声明类、属性、方法时,可以使用final关键字表示“最终”。
- 被final修饰的类不能被继承,可以提高安全性。具有代表性的有String 、System类等。
- 被final修饰的方法不能被重写如Object类中的getClass()方法;
- 被final修饰的变量(成员变量或局部变量)即称之为常量,只能被赋值一次。
ps: 当使用匿名内部类时,内部类中使用到了外面的局部变量要加final?
因为:局部变量会因为方法的执行完成而消失,而当内部类要使用时就会造成变量无法访问。当局部变量被final修饰时就会变成全局常量,我们知道常量的生命周期和类相关远远大于对象的生命周期这样就保证了变量的可访问性。
this super 的区别
- this 表示当前对象可以调用类的属性、方法、构造器。
- super:是父类存储空间标识,可以理解为父类对象引用,调用父类方法,变量。
this的使用:
- 构造方法中使用:通过this调用另一个重载的构造方法,用法是this(参数);该语句必须在构造方法体第一行,非构造方法不能使用;
- 当方法参数或者方法内局部变量与成员变量同名的情况下,此时成员变量会被屏蔽;要想访问成员变量必须使用this.成员变量名来访问;
- 在方法中可以通过this来表示该类的引用,从而调用该类的属性方法等
ps:因为this表示当前对象,故而不能在static修饰的方法或方法块内使用this。
super的使用:
- 在子类构造方法中需要调用父类构造方法,可以使用super(参数)的语句,参数可不传,但是这句代码必须在方法块第一行;
- 当子类方法中的局部变量或者成员变量与父类的成员变量重名时,可以使用super.变量名来引用父类成员变量;
- 当子类重写父类方法时,可以使用super(参数)来调用父类方法。
ps:因为super 表示父类对象的引用,故而不能在static修饰的方法或方法块内使用this。
代码块
代码块可分为普通代码块、构造代码块、静态代码块、同步代码块。
- 普通代码块:是在方法名后面用{}括起来的代码,不能单独存在,必须要紧跟方法名且用方法名调用该代码块;作用是限定变量的声明周期和提高效率;
- 构造代码块作用是把所有构造方法中相同部分提取出来:
- 可以有输出语句;
- 可以对类的属性、做初始化操作;
- 可以调用静态的变量或方法;
- 若有多个非静态代码块,那么会按照从上至下的顺序依次执行;
- 每次创建对象时都会执行一次且先于构造器执行。
- 静态代码块即用static修饰的代码块:
- 可以有输出语句;
- 可以对类的属性、做初始化操作;
- 不可以调用非静态的变量或方法;
- 若有多个非静态代码块,那么会按照从上至下的顺序依次执行;
- 静态代码块先于非静态代码块的执行;
- 静态代码块属于类,会在类加载的时候执行且只会执行一次。
- 同步代码块:在方法中用synchronized关键字修饰且用{}包括起来的代码,是一种多线程并发保护机制。
ps:除普通代码块的执行顺序是:静态代码块>构造代码块>构造方法,若同类型代码块有多个会从上至下依次执行。
ps:欢迎关注博主个人微信公众号!