java中易遗忘的知识,不定时更新……

如果有人问你: "子类继承父类所有非私有(private)的属性和方法这句话对吗?", 如果你回答对的, 那我只能说too young too simple!

关于代码块和成员变量初始化的问题你清楚吗?请看这里

修饰符的问题

  为什么说这句话不对了, 只要你搞清楚了4个访问修饰符的应用范围你就知道了

  public: 任何地方都能访问

  private: 类访问符(自己取得名字), 只要在本类中的都可以访问, 其他类中不可以访问

  默认: 即不加修饰符的时候, 这时候是包访问符, 只要在本包中的都可以访问, 其他包不可以访问(其他包中的子类也不可以访问, 这也正是和protected的区别)

  protected: 默认+非同包的子类, 即可以在本包和非同包的子类中访问, 在非同包的非子类中不可以访问

  可以自己写个案例验证一下, 也有助于自己更好的理解, 那我再问: "实现类'继承'父接口的所有非私有的属性和方法对吗?", 如果你受到上面的启发脱口而出'不对', 那你就要仔细思考一下了. 首先这个问题就有问题, 因为接口中的属性默认被public static final修饰, 接口中的方法默认被public abstract修饰, 所以接口中没有私有的属性和方法, 所以说"实现类'继承'父接口中所有的属性和方法"是对的. 

  怎么验证呢?

    static: 验证在实现类中是否能被类名直接调用

    final: 验证在实现类中是否能修改属性的值

    abstract: 试着在接口中写一个具体的方法

    public: 这个就不用说了吧

  

代码块的问题

  掌握java中的代码块有时对我们是很有帮助的, 主要有静态块(格式为static{doSomething})和构造块(格式为{doSomething}), 他们都是定义在类中的, 很简单, 通过下面的一个例子相信你就会完全了解了

public class CodeBlock {
    private String code = "code";
    
    static{
        System.out.println("我是静态代码块");
    }
    
    {
        System.out.println("我是构造代码块");
    }
    
    public CodeBlock(){
        System.out.println("我是无参构造方法");
    }
    
    //输入说明一切, 当然用调试模式看的更清楚
    public static void main(String[] args) {
        System.out.println("开始执行main方法");
        new CodeBlock();
        System.out.println("-----------分割线-----------");
        new CodeBlock();
    }
}
View Code

 

  自己执行一下, 看一下输出结果你就会发现结论是这样的: 静态块在加载类的时候执行, 而且只执行一次. 构造块在每次调用构造方法的时候都会执行, 所以构造块在构造方法之前执行. 他们执行的优先级: 静态块 > main方法 > 构造块 > 构造方法.

  可是我为什么要在这里加一个成员变量呢?我不知道你有没有这样的疑惑, 因为这和我接下来要讲的有关. 在讲之前先扯点淡, 我们都知道java中的变量在使用之前是要初始化的, 那么你真的清楚成员变量是在什么时候初始化的么?(老鸟请无视), 不要问我局部变量何时初始化的, 那可不就是在执行到他的时候初始化的嘛!好, 回到刚才代码块的这个案例中.

  没有用static修饰的成员变量也叫'实例变量', 对, 你从他的名字可能已经猜到了实例变量初始化的时机: 实例变量和构造块类似, 每次调用构造方法的时候都会执行初始化, 更具体的是在调用构造方法并调用完父类的构造方法之后, 不过他的优先级比构造块高点, 所以结合代码块一起看, 他们的优先级是: 静态块 > main方法 > 实例变量 > 构造块 > 构造方法.

static理解

  但是如果成员变量被static修饰呢?这时候就应该叫类变量了, 顾名思义, 类变量在类加载的时候就被初始化了. 在类中被static修饰的成员(变量, 方法, 代码块)在类加载的时候就被初始化并放到内存中, 系统会在内存中专门开辟出一块区域来存储他们, 以后就算创建类的实例, 静态成员也还是在那儿. 也就是说, 静态成员在类初始化一次后, 系统就不会为他们开辟新的内存空间. 而每new一个类的对象, 系统就会重新在堆内存中开辟一个新空间来存放该类的实例对象, 并且栈中也会有一个新的引用变量去指向它. 一个类的静态成员是被这个类的所有实例所共享的. 讲到这又想起来一个问题: 在静态方法中不能直接调用非静态方法. 因为静态方法随着类的加载而被加载到了内存中, 而非静态方法(实例方法)是在创建类的实例后才被加到内存中的, 所以假如在静态方法中直接调用非静态方法, 静态方法: "咦, 我要调用的这个方法不存在啊!", 但是在静态方法中new一个对象来调用非静态方法是肯定可以的. 关于static可以参考这里, 我觉得解释的比较好. 如果你还是有点懵懵的, 那就来个例子, 再加深一下理解. 

  碗类:

public class Bowl {
    Bowl(int marker){
        System.out.println("碗的数量"+marker);
    }
    
    void f1(int marker){
        System.out.println("f1方法"+marker);
    }
}
View Code

  碗柜类:

public class Cupboard {
     Bowl bowl3 = new Bowl(3);
    static Bowl bowl4 = new Bowl(4);
    
    Cupboard(){
        System.out.println("这是碗柜的无参构造");
        bowl4.f1(2);
    }
    
    void f3(int marker){
        System.out.println("这是f3方法, 数量"+marker);
    }
    
    static Bowl bowl5 = new Bowl(5);
}
View Code

  桌子类:

public class Table {
    static Bowl bowl1 = new Bowl(1);
    Table(){
        System.out.println("table的无参构造");
        bowl2.f1(1);
    }
    void f2(int marker){
        System.out.println("f2的数量"+marker);
    }
    static Bowl bowl2 = new Bowl(2);
}
View Code

  测试:

/**
 * 通过本例了解对象的创建过程及先后顺序
 * 在加载类StaticInitialzation时, 静态成员变量table被初始化, 从而导致table所
 * 对应的类Table被加载, table中也有静态成员变量, 所以也会被加载, 非静态成员变量(实例变量)是在
 * 调用构造方法的时候初始化, 所以在Cupboard中调用构造方法时(调用了构造方法, 但还没有执行
 * 构造方法里面的主体代码, 使用调试可以很清楚地看到)才初始化bowl3
 */
public class StaticInitialzation {
    public static void main(String[] args) {
        System.out.println("创建碗柜");
        new Cupboard();
        System.out.println("再创建一个碗柜");
        new Cupboard();
        table.f2(1);
        cupboard.f3(1);
        
    }
    
    static Table table = new Table();
    static Cupboard cupboard = new Cupboard();
    
    static{
        System.out.println("我是静态块");
    }
}
View Code

  自己试一下, 看输出的结果和自己想的是否一样, 打断点调试会比较有帮助.

 

后面还会更新其他的……

转载于:https://www.cnblogs.com/pdzbokey/p/6210047.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
中易广告联盟v9.0是一款优秀的广告投放管理平台。随着互联网和移动设备的发展,广告联盟在数字营销中扮演着重要的角色。中易广告联盟v9.0应运而生,为广告主和网站主提供了全方位的广告服务和管理工具。 首先,中易广告联盟v9.0具有强大的广告投放功能。广告主可以通过平台选择合适的广告形式,例如横幅广告、插页广告、视频广告等,对目标受众进行定向投放。广告联盟还提供了精准的广告报告和分析功能,帮助广告主实时监测广告效果,并进行优化调整,从而提高投放效果。 其次,中易广告联盟v9.0提供了丰富的广告资源和广告位管理功能。平台汇集了大量的网站主,他们可以通过联盟平台轻松管理自己的广告位。同时,中易广告联盟v9.0也通过智能匹配和竞价系统,将广告主的广告与适合的广告位进行匹配,实现广告投放的高效和精准。 另外,中易广告联盟v9.0还注重用户体验和安全。广告联盟通过广告审核制度,保证广告内容的合法性和真实性,防止恶意软件和欺诈广告的出现。同时,广告联盟也着重优化广告页面的加载速度,以提升用户的体验和减少失望。 总体而言,中易广告联盟v9.0是一款功能强大、资源丰富、安全可靠的广告投放管理平台。通过该平台,广告主和网站主能够快速、有效地进行广告投放和管理,实现更好的营销效果和经济效益。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值