A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 打工人 金牌黑马   /  2012-10-18 20:34  /  1385 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 冯海霞 于 2012-10-18 22:03 编辑

1、构造代码块中不能定义变量啥的吗?毕老师视频中讲static的时候举得例子:定义的Person类的对象国籍都是"CN",所以就考虑为了节省内存使用关键字描述所有对象的国籍的特征。
构造代码块不也是描述对象的共同特征吗?那我这样写代码咋就不对呢?
class Person()
{
{String contry="CN";
}
String name;
}
2、static修饰变量,能使对象在初始化的时候节省内存空间,那构造代码块也是能节省内存么?

评分

参与人数 1技术分 +1 收起 理由
韩军博 + 1

查看全部评分

8 个回复

倒序浏览
构造代码块是用来进行实例属性的初始化的,不是为了为了节省内存的,也不是描述对象的共同特征的。
为了省内存应该使用静态变量。因为它们与类同在,都在方法区中,每个对象都可以共享静态属性。
回复 使用道具 举报
丁旭 发表于 2012-10-18 20:45
构造代码块是用来进行实例属性的初始化的,不是为了为了节省内存的,也不是描述对象的共同特征的。
为了省 ...

构造代码块给所有对象进行统一初始化不就是说描述共同特征么
回复 使用道具 举报
下面是一些解释,应该有些用:

在通过new关键字生成一个实例时会先执行构造代码块,然后再执行其他代码,也就是说:构造代码块会在每个构造函数内首先执行(需要注意的是:构造代码块不是在构造函数之前运行的,它依托于构造函数的执行),明白了这一点,我们就可以把构造代码块应用到如下场景中:

(1)初始化实例变量(Instance Variable)

如果每个构造函数都要初始化变量,可以通过构造代码块来实现。当然也可以通过定义一个方法,然后在每个构造函数中调用该方法来实现,没错,可以解决,但是要在每个构造函数中都调用该方法,而这就是其缺点,若采用构造代码块的方式则不用定义和调用,会直接由编译器写入到每个构造函数中,这才是解决此类问题的绝佳方式。

(2)初始化实例环境

一个对象必须在适当的场景下才能存在,如果没有适当的场景,则就需要在创建对象时创建此场景,例如在JEE开发中,要产生HTTP Request必须首先建立HTTP Session,在创建HTTP Request时就可以通过构造代码块来检查HTTP Session是否已经存在,不存在则创建之。

以上两个场景利用了构造代码块的两个特性:在每个构造函数中都运行和在构造函数中它会首先运行。很好地利用构造代码块的这两个特性不仅可以减少代码量,还可以让程序更容易阅读,特别是当所有的构造函数都要实现逻辑,而且这部分逻辑又很复杂时,这时就可以通过编写多个构造代码块来实现。每个代码块完成不同的业务逻辑(当然了,构造函数尽量简单,这是基本原则),按照业务顺序依次存放,这样在创建实例对象时JVM也就会按照顺序依次执行,实现复杂对象的模块化创建。

评分

参与人数 1技术分 +1 收起 理由
韩军博 + 1 很给力!

查看全部评分

回复 使用道具 举报
冯海霞 发表于 2012-10-18 20:48
构造代码块给所有对象进行统一初始化不就是说描述共同特征么

您觉得不同对象的共同特征是什么呢?
再说您写的代码也不对啊。class Person后面怎么能有括号呢?
定义类的书写格式错了
回复 使用道具 举报
static变量只与他所在的类有关,并在编译时分配内存,而与类的对象无关。
比如类A里有个static s, 那么任何一个类A的对象都可以修改他,并且是共享式修改。 可以认为这个静态就是共享的意思。

而其他成员,包括构造方法,都是属于对象的,在你的代码中,每个对象都有不同的country,虽然一开始都是CN,但是改动一个不会影响到另一个。
回复 使用道具 举报
丁旭 中级黑马 2012-10-18 20:59:24
7#
构造代码块之所以能给所有对象进行统一初始化,是因为在new一个对象开辟空间为属性赋默认值后,需调用构造方法进行初始化,但是在执行构造方法内的代码前,构造方法需要调用构造代码块为属性显式初始化。
回复 使用道具 举报
  1. 构造函数(被动):随着对象的创建而执行。
  2.         作用:给特定的类进行初始化。
  3. 构造代码块(被动):对象一建立就执行,无论放在构造函数前或后,都先于构造函数执行!
  4.         作用:给类的所有对象进行统一初始化。
  5. 静态代码块(被动):随着类的加载而执行,只执行一次。并优先于主函数执行!
  6.         所用:给类进行初始化。
  7. 主函数(被动):程序入口。
  8. 静态成员(主动):随着类的加载而加载,然后存在于方法区中,随着类的消失而消失。生命周期最长。静态函数被调用才执行。

  9. 对象的初始化过程?
  10. Person p=new Person("wzq",22);做了哪些事情
  11. 1,因为new用到了Person.class,所以会先找到该文件,并将其加载到内存中。
  12. 2,执行该Person类中的static代码块,给Persion.class进行初始化
  13. 3,在堆内存中开辟空间,分配内存地址。(栈内存中为p开辟空间)
  14. 4,在堆内存中建立对象的特有属性(成员变量),并进行默认初始化-->private int age=0;
  15. 5,对属性进行显式初始化-->private String name = ren;
  16. 6,对对象进行构造代码块初始化;
  17. 7,对对象进行对应的构造函数初始化-->"wzq",22 初始化对象name=wzq,age=22;
  18. 8,将堆内存地址赋给栈内存中的p变量
复制代码

点评

不错!总结的很详细!  发表于 2012-10-18 21:07

评分

参与人数 1技术分 +1 收起 理由
韩军博 + 1 很给力!

查看全部评分

回复 使用道具 举报
{:soso_e129:}我好好研究研究。。。。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马