资讯专栏INFORMATION COLUMN

直接明了的告诉你——对象与内存控制

canger / 1933人阅读

摘要:的垃圾回收机制是由一条后台线程执行的,其本身也是非常消耗内存的,因此,滥用创建对象,会导致性能大大下降,对内存的分配的了解就显得尤为重要变量分类局部变量形参存在于方法签名中定义的局部变量,有方法调用者为其赋值,随着方法的结束而消亡方法内部变

JVM的垃圾回收机制是由一条后台线程执行的,其本身也是非常消耗内存的,因此,滥用创建对象,会导致性能大大下降,对内存的分配的了解就显得尤为重要

变量分类 局部变量

形参:存在于方法签名中定义的局部变量,有方法调用者为其赋值,随着方法的结束而消亡

方法内部变量:在方法内部定义的局部变量,必须在方法内对其进行显示初始化,随着方法的结束而消亡

代码块内部的局部变量:在代码块内定义的局部变量,必须在代码块内对其显式初始化,随着代码块结束而消亡

成员变量

实例变量:非静态的成员变量,随着对象的产生,进行初始化等操作,对象结束变量也就消亡

类变量:静态的成员变量,带有static修饰符,随着类初始化产生,随着类消失而消失

在创建变量的时候,一定要合法的前向引用。其含义就是先定义的变量不能引用后定义的变量,反之则可以

变量的内存分配

在同一个JVM中每一个类只会存在一个Class对象,因此JVM只要分配一块内存空间给类变量就可以了,而实例变量则每次创建对象都要为其分配一块内存,几个实例就要创建几块内存空间

实例变量的初始化时机

定义变量的时候

代码块中

构造器中

定义实例变量时指定的初始值、初始化块中为实例变量指定初始值的语句的地位是平等的,当经过编译器处理后,他们都将被提取到构造器中,也就是说在编译后,初始化都会被放在构造器中按先后顺序进行初始化赋值

类变量初始化时机

同一个JVM中,类变量只能初始化一次

定义变量的时候

静态代码块

父类构造器

在创建Java对象的时候,都会先去执行该类的父类对象的非静态代码块和构造器,最后才是该类的非静态代码块和构造器

所谓的隐式调用和显式调用,其实就是有没有用super去调用父类的构造器的区别。

如果父类还没被初始化过,则会最先对类变量进行初始化

访问子类对象的实例变量

子类的方法可以访问父类的实例变量,这是因为子类继承父类就会获得父类的成员变量和方法,但父类的方法不能访问子类的实例变量,因为父类无法知道哪个子类继承他

而且子父类中的成员变量(类变量和实例变量)是相互独立的,父类中的成员变量不会被子类中同名的变量覆盖

class Base {
    static int count = 2;
}

class Mid extends Base {
    static int count = 20;
    
}

public class Sub extends Mid {
    static int count = 200;

    public static void main(String[] args) {
        // 创建一个Sub对象
        Sub s = new Sub();
        // 将Sub对象向上转型后赋为Mid、Base类型的变量
        Mid s2m = s;
        Base s2b = s;
        // 分别通过3个变量来访问count实例变量
        System.out.println(s.count);
        System.out.println(s2m.count);
        System.out.println(s2b.count);
    }
}

结果

200
20
2

当创建Sub的时候,会初始化Base、Mid和Sub三个对象,同时也就存在三个count变量了,也就是说有三块内存保存着这三个对象和count变量,以s2m变量为例,s2m拥有的地址是Sub对象的堆地址,但s2m变量类是是Mid,则会去寻找Mid下的变量值

也就说成员变量的值取决于声明该变量声明时是所用的类型

访问子类对象的方法

子类可以重写父类的方法,子类也可以通过super的方式调用父类的方法,在多态的情况下,子类重写的方法会覆盖掉父类的方法

class Base{
    int count =2;
    public void display(){
        System.out.println(this.count);
    }
}
class Derived extends Base{
    int count =20;
    @Override
    public void display() {
        System.out.println(this.count);
    }
}
public class FieldAndMethod {
    public static void main(String[] args) {
        Base b=new Base();
        System.out.println(b.count);
        b.display();
        Derived d=new Derived();
        System.out.println(d.count);
        d.display();
        Base db=new Derived();
        System.out.println(db.count);
        db.display();
        Base b2d=d;
        System.out.println(b2d.count);
    }
}

结果

2
2
20
20
2
20
2

一切在你执行这段代码之后,你就会明白一切了。

更多内容可以关注微信公众号,或者访问AppZone网站

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/65983.html

相关文章

  • 前端基础进阶(四):详细图解作用域链闭包

    摘要:之前一篇文章我们详细说明了变量对象,而这里,我们将详细说明作用域链。而的作用域链,则同时包含了这三个变量对象,所以的执行上下文可如下表示。下图展示了闭包的作用域链。其中为当前的函数调用栈,为当前正在被执行的函数的作用域链,为当前的局部变量。 showImg(https://segmentfault.com/img/remote/1460000008329355);初学JavaScrip...

    aikin 评论0 收藏0
  • 前端内存泄漏分析案例

    摘要:查找原因因为更新了的版本才出现内存泄漏的问题,所以有理由怀疑,就是新增加的功能导致的内存泄漏。同时还发现了也有内存泄漏的情况,通过同样的方式定位到了这个问题并最终解决。 在最近给客户交付的一个项目中,客户反映系统跑一段时间就会奔溃掉。我的第一直觉就是可能发生了内存泄漏。 复现bug 为了能够让bug复现,我让开发的小伙,先把模拟系统在本地跑起来。要知道,bug复现是很重要的。bug复现...

    CatalpaFlat 评论0 收藏0
  • 13 万字 C 语言从入门到精通保姆级教程2021 年版 (建议收藏)

    摘要:友情提示先关注收藏,再查看,万字保姆级语言从入门到精通教程。及大牛出天地开始有随之乃有万种语年英国剑桥大学推出了语言。 友情提示:先关注收藏,再查看,13 万字保...

    zombieda 评论0 收藏0
  • 记一次 JAVA 内存泄露分析

    摘要:展示如下场景再现经过分析,最后我们定位到是使用产生的内存泄露问题。下面通过一个,来简单讲下具体内存泄露的原因。这一次的内存泄露问题算是解决了。总结关于内存泄露问题在第一次排查时,往往是有点不知所措的。 记一次 JAVA 的内存泄露分析 摘要:本文属于原创,欢迎转载,转载请保留出处:https://github.com/jasonGeng88/blog 当前环境 jdk == 1.8 ...

    Tecode 评论0 收藏0
  • 【译】JavaScript面试问题:事件委托和this

    摘要:主题来自于的典型面试问题列表。有多种方法来处理事件委托。这种方法的缺点是父容器的侦听器可能需要检查事件来选择正确的操作,而元素本身不会是一个监听器。 showImg(http://fw008950-flywheel.netdna-ssl.com/wp-content/uploads/2014/11/Get-Hired-Fast-How-to-Job-Search-Classifieds...

    浠ラ箍 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<