随笔⑨ java中的变量 --- 类变量(静态变量),final变量,成员变量,局部变量 java中的方法 --- 类方法(静态方法),final方法,成员方法(实例方法),构造方法

一:java中的变量 --- 类变量(静态变量),final变量,成员变量,局部变量

类变量(也叫静态变量)是类中独立于方法之外的变量用static 修饰静态变量随着类的加载而加载

final变量:用final关键字修饰,不能被修改。与static一起用可表示常量。

成员变量(也叫"实例变量"、"域"):也是类中独立于方法之外的变量,不过没有static修饰。可以不进行初始化,Java会自动进行初始化,如果是引用类型默认初始化为null,如果是基本类型例如int则会默认初始化为0。

局部变量是类的方法中的变量。必须要实例化,否则不同通过编译。局部变量运行时被分配在栈中,量大,生命周期短,如果虚拟机给每个局部变量都初始化一下,是一笔很大的开销,但变量不初始化为默认值就使用是不安全的。出于速度和安全性两个方面的综合考虑,解决方案就是虚拟机不初始化,但要求编写者一定要在使用前给变量赋值。

1 public class Variable{
2     static int allClicks=0;//类变量
3     String str="hello world";//实例变量
4     public void method(){
5         int i =0;//局部变量
6     }
7 }

 二:java中的方法 --- 类方法(静态方法),final方法,成员方法(实例方法),构造方法

① 类方法(静态方法):由static关键字修饰,与类对象无关。当类的字节码文件加载到内存,类方法的入口地址就会分配完成,所以类方法不仅可以被该类的对象调用,也可以直接通过类名完成调用。类方法的入口地址只在程序退出时消失。

因为类方法的入口地址的分配要早于实例方法的入口地址分配时间,所以在定义类方法和实例方法时有以下规则需要遵循:

  • 在类方法中不能引用实例变量:实例变量的定义类似实例方法,没有用static修饰的变量,实例变量的创建与实例方法的创建相同,也是在类的对象创建时完成,所以在类方法中是不能引用实例变量的,因为这个时候实例变量还没有分配内存地址。
  • 在类方法中不能使用super和this关键字:这是因为super和this都指向的是父类和本类的对象,而在类方法中调用的时候,这些指代的对象有可能都还没有创建。
  • 类方法中不能调用实例方法:原因同上。

实例方法(成员方法):当类的字节码文件加载到内存中时,类的实例方法并没有被分配入口地址只有当该类的对象创建以后,实例方法才分配了入口地址。从而实例方法可以被类创建的所有对象调用,还有一点需要注意,当我们创建第一个类的对象时,实例方法的入口地址会完成分配,当后续再创建对象时,不会再分配新的入口地址,也可以说,该类的所有对象共享实例方法的入口地址,当该类的所有对象被销毁,入口地址才会消失

  • 实例方法可以引用类变量和实例变量
  • 实例方法可以使用super和this关键字
  • 实例方法中可以调用类方法

final方法:由final关键字修饰,不能被子类覆盖。

构造方法:方法名与类名相同,没有返回值,可以重载。 如果在类中我们不声明构造函数,JVM会帮我们默认生成一个空参数的构造函数;如果在类中我们声明了带参数列表的构造函数,JVM就不会帮我们默认生成一个空参数的构造函数,我们想要使用空参数的构造函数就必须自己去显式的声明一个空参的构造函数

构造方法的作用:创建对象,对象初始化。

构造函数在继承中的特点:在继承中:

  • 子类会不会调用父类的函数?

  子类继承父类,子类对象初始化时父类的构造函数也会执行,因为子类需要使用父类中的属性,子类需要知道是如何初始化的,所以子类初始化必然会调用父类的构造函数(除非父类没有属性,那么这个类的描述也太差了点,或者没有必要去创建这个类了)。

  • 子类的构造函数与父类的构造函数有什么关系?

  子类的构造函数中默认的第一行有一条隐式语句super(),该语句会访问父类中的空参数构造函数,除非父类中没有空参数的构造函数,那么子类构造函数的第一行必须显式调用父类的构造函数,即super(int x,…) 。

  • 子类的构造函数需要注意些什么问题呢?

  子类的构造函数中,super()语句代表调用了父类的构造函数this()语句代表调用了子类自身的构造函数。需要注意的是,如果这两条语句显式写出来必须放在构造方法的第一行,而且这两条语句不能共存,一个构造函数中的第一行要么是this()要么是super()。

  • 为什么在第一行?因为需要首先进行初始化。
  • 为什么不能共存?因为this()代表的本类的其他构造函数,也会去调用super(),出现了this()就没有必要再出现super()了,重复调用没有意义。换言之,子类中至少有一个构造函数的开头为super(),当然可以隐式存在;也就是说至少有一个构造函数的开头不是this()

⑤ 构造函数的扩展

  • 所有的类都有构造函数么?构造函数可以被私有化么?

  既然构造函数用于创建对象并且初始化对象,由于java是面向对象的,我们创建类的目的就是为了创建对象或者创建其子类对象,所以必须要有构造函数。

  构造函数可以被私有化,一个类不想要外界创建其对象时,就可以将其构造函数私有化,本类中提供返回对象的方法,并且多数情况下提供的对象是唯一的,单例设计模式就是一个很好的例子,而当我们开发中需要保证对象唯一性的时候,往往就采取这种做法。

  • 构造代码块与构造函数有什么相似和不同?

  构造代码块用一对“{}”表示,代码块位置没有具体的要求,但必须与类的成员同等级别,在括号的区域内,可以对所有该类的对象进行初始化,也就是说该类对象创建时都会执行到该代码块,并且其优先于构造函数执行。构造函数如前面提到的是具有针对性的,而构造代码块是作用于所有本类对象的。

  • 构造方法每次都是构造出新的对象,不存在多个线程同时读写同一对象中的属性的问题,所以不需要同步 。
  • 如果父类中的某个方法使用了 synchronized关键字,而子类中也覆盖了这个方法,默认情况下子类中的这个方法并不是同步的,必须显式的在子类的这个方法中加上 synchronized关键字才可。当然,也可以在子类中调用父类中相应的方法,这样虽然子类中的方法并不是同步的,但子类调用了父类中的同步方法,也就相当子类方法也同步了。详见:http://blog.csdn.net/welcome000yy/article/details/8941644.
  • 接口里面的变量为常量,其实际是 public static final ;接口里面的方法为抽象方法,其实际是public abstract。
原文地址:https://www.cnblogs.com/lyr612556/p/7816742.html