【韩顺平 零基础30天学会Java】类的成员有哪些?

📕属性

我习惯称它为全局变量,为什么说它是全局变量?
因为不管变量的 访问修饰符 是什么,类的方法体、构造器、代码块和内部类都可以通过 this 对其进行访问,除非它们被 static 修饰。
称它为全局变量又不准确,因为它被 final 修饰时,本质上是不可以改变的。
我为什么说被 final 修饰时本质上不可以改变?因为当全局变量为引用类型时,使用 final 修饰还是可以被改变的,例如下面这段代码:

class A{
    final int[] i = {1, 2};
    public void visit(){
    	this.i[0] = 32;			// 修改被 final 修饰的
    }
}
class Text{
    public static void main(String[] args) {
    	A o = new A();
        o.visit();
        System.out.println(o.f[0]);
    }
}

建议

  1. static 修饰的属性
    • 建议设置默认值
    • 建议不要与 private 搭配
    public static int i = 0;
    
  2. final 修饰的属性
    • 建议不要改动

📕方法

三种方法以及需要遵守的规范:

  1. abstract 修饰的抽象方法
    • 不准与 final 搭配
    • 不准与 static 搭配
    • 不准使用 {}
    abstract class A{
    	protected abstract void visit(){};
    }
    
  2. static 修饰的静态方法
    • 不准与 abstract 搭配
    • 建议不要与 private 搭配
    class A{
    	public static void visit(){};
    }
    
  3. 不被前两个修饰的普通方法

部分细节请看 OOP与AOP 关于成员方法的描述。

📕构造器

构造器根据参数分为无参和有参;
根据访问修饰符分为私有和公共;

  • 无参构造器
    当你在类里面没有定义构造器的时候,默认会生成一个无参构造器。
    默认的无参构造器如果没有声明会被有参构造器覆盖。

  • 有参构造器
    可以传参数实现对象的初始化设置

  • 私有构造器
    可以实现【单例模式】,从而保证类只有一个实例

  • 公共构造器
    可以被用于创建多个实例或提供一个模板

  • 构造器只能被访问修饰符修饰

构造器在哪些情况下会被执行?

  • 对象实例化时new强引用
  • Java反射机制 newInstance弱引用

详情请看 OOP与AOP关于构造器的描述。

📕代码块

  • 只有 static 可以修饰代码块

因此根据 static 分为:

  • 静态代码块
    每次 类加载 的时候被执行
  • 普通代码块
    每次 实例化对象 的时候被执行

💡静态代码块

那么哪些情况下会发生类加载❓

  • 实例化对象 new
  • 调用类的静态方法
  • 使用类的静态属性

只要类的元信息加载到方法区的常量池,就算一次类加载从而执行静态代码块。为了说明这种特性下面给出一个案例观察其有趣的执行方式:

class A{
    public static int count = 0;// 静态属性
    static {// 静态代码块
        ++A.count;
        System.out.println("第 "+A.count+" 次加载的静态代码块");
    }
    static void visit(){};// 静态方法
}
class Text{
    public static void main(String[] args) {
        new A();
        new A();
        // A.visit();
        // System.out.println(A.count);
    }
}

结论:当你实例化对象、调用类的静态方法或使用类的静态属性,那么就会执行类的静态代码块但之后再用这种方式(继续实例化对象、调用类的静态方法或使用类的静态属性)将无法执行静态代码块。

💡普通代码块

普通代码块与静态代码块不同,它在每次对象实例化时被执行。可以利用下面的代码来验证:

class A{
    public static int count = 0;
    static void visit(){};
    {
        ++A.count;
        System.out.println("第 "+A.count+" 次加载的普通代码块");
    }
}
class Text{
    public static void main(String[] args) {
        new A();
        new A();
        // A.visit();
        // System.out.println(A.count);
    }
}

📕内部类

  • 内部类可以在类的方法体里面定义
    在方法体里面定义类,可以不用写类的名字。在方法体定义的类,不能使用访问修饰符,可以使用 finalabstract 修饰。
    interface A{
    	public void visit();
    }
    class B{
    	public void visit(){
    		A a = new A(){// 匿名类
    			public void visit(){System.out.println("a 匿名类的 visit 方法被执行");};
    		};
    		a.visit();
    	}
    }
    class Text {
        public static void main(String[] args) {
            B b = new B();
            b.visit();
        }
    }
    

只要不是在方法体里面定义的,其修饰的类型比类的方法多,甚至可以在非抽象类里面使用 abstractinterface 修饰。
static 修饰的内部类,可以在类的外部直接创建,请看下面的案例:

class A {
    static class B{// 静态内部类
        public void visit(){System.out.println("11111");}
    }
}
class Text {
    public static void main(String[] args) {
        A.B b = new A.B();
        b.visit();
    }
}

那么内部类如何访问类的属性❓
可以通过class.this.property进行访问除了 static 修饰的内部类。

class A {
	int i = 0;
    class B{// 非静态内部类
        public void visit(){System.out.println(A.this.i);}
    }
}
class Text {
    public static void main(String[] args) {
        A a = new A();
        A.B b = a.new B();
        b.visit();
    }
}

如果你是无意刷到这篇文章并看到这里,希望你给我的文章来一个赞赞👍👍。如果你不同意其中的内容或有什么问题都可以在下方评论区留下你的想法或疑惑,谢谢你的支持!!😀😀

参考文献

  1. 【零基础 快速学Java】韩顺平 零基础30天学会Java_哔哩哔哩_bilibili
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hjhcos

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值