Java中类方法(静态方法)和实例方法(非静态方法,也称为成员方法)的主要区别如下:
1、定义与修饰符:
csharp
public class Study {
/**
* 类方法:使用关键字 static 进行修饰。
*/
public static void classMethod() {
System.out.println("类方法");
}
/**
* 实例方法:不使用 static 修饰符
*/
public void instanceMethod() {
System.out.println("实例方法");
}
}
2、内存分配与调用方式:
类方法:在类加载时就已经被分配了内存空间,可以通过类名直接调用,不需要创建任何对象实例 实例方法:只有在创建了类的实例对象后才能调用,需要通过实例引用进行调用。
scss
public static void main(String[] args) {
//类方法使用
Study.classMethod();
//实例方法使用,先创建实例对象才可以调用
Study.instanceMethod(); // 报错
Study study = new Study();
study.instanceMethod();
}
3.访问权限:
类方法不能直接访问实例变量,只能访问类变量(静态变量),不能使用super、this关键字,因为类方法没有隐式的 this 引用指向具体的实例对象。 实例方法既可以访问类变量也可以访问实例变量,并且有一个隐式的 this 参数,可以直接操作对象的状态。
csharp
public static void classMethod() {
//不能直接访问
instanceMethod(); //报错
Study.instanceMethod(); //报错
}
public void instanceMethod() {
System.out.println("实例方法");
classMethod();
}
类方法可以被其他类直接访问,实例方法需要先创建类的实例对象
typescript
class Test1 {
public static void main(String[] args) {
Study.classMethod();
Study study = new Study();
study.instanceMethod();
}
}
4.生命周期与作用域:
类方法在整个应用程序的生命周期内只有一份拷贝,所有类的实例共享这份拷贝。 实例方法是每个类实例私有的,每次创建新对象时都会拥有该方法的一个独立副本。
5.继承与重写:
类方法不能被子类重写(Override),但可以被子类声明新的同名静态方法,这通常称为隐藏(Hide)父类的方法。 实例方法可以被子类重写。
6.加载顺序
csharp
public class ClassInitDemo extends ParentClass {
//成员变量
static int num = 100;
//构造代码块(普通代码块需要实例化对象后调用)
{
num += 100;
System.out.println("子类构造代码块:num =" + num);//300
}
//静态代码块 (类加载时执行,所以在一个类中只执行一次,new 两次类对象也只会在第一次执行)
static {
num += 100;
System.out.println("子类静态代码块:num =" + num);//200
}
//普通代码块 (需要实例化对象后调用)
@Override
void common () {
System.out.println("子类普通代码块");
}
//执行顺序 父类静态代码块-子类静态代码块-父类构造代码块-子类构造代码块
public static void main(String[] args) {
ClassInitDemo obj1 = new ClassInitDemo();
obj1.common();
}
}
class ParentClass {
{
System.out.println("父类构造代码块");
}
static {
System.out.println("父类静态代码块");
}
void common () {
System.out.println("父类普通代码块");
}
}
输出: 父类静态代码块 子类静态代码块:num =200 父类构造代码块 子类构造代码块:num =300 子类普通代码块