黑马程序员技术交流社区

标题: 关于构造代码块和static,明白了! [打印本页]

作者: 打工人    时间: 2012-10-18 20:34
标题: 关于构造代码块和static,明白了!
本帖最后由 冯海霞 于 2012-10-18 22:03 编辑

1、构造代码块中不能定义变量啥的吗?毕老师视频中讲static的时候举得例子:定义的Person类的对象国籍都是"CN",所以就考虑为了节省内存使用关键字描述所有对象的国籍的特征。
构造代码块不也是描述对象的共同特征吗?那我这样写代码咋就不对呢?
class Person()
{
{String contry="CN";
}
String name;
}
2、static修饰变量,能使对象在初始化的时候节省内存空间,那构造代码块也是能节省内存么?
作者: 丁旭    时间: 2012-10-18 20:45
构造代码块是用来进行实例属性的初始化的,不是为了为了节省内存的,也不是描述对象的共同特征的。
为了省内存应该使用静态变量。因为它们与类同在,都在方法区中,每个对象都可以共享静态属性。
作者: 打工人    时间: 2012-10-18 20:48
丁旭 发表于 2012-10-18 20:45
构造代码块是用来进行实例属性的初始化的,不是为了为了节省内存的,也不是描述对象的共同特征的。
为了省 ...

构造代码块给所有对象进行统一初始化不就是说描述共同特征么
作者: 马磊    时间: 2012-10-18 20:54
下面是一些解释,应该有些用:

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

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

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

(2)初始化实例环境

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

以上两个场景利用了构造代码块的两个特性:在每个构造函数中都运行和在构造函数中它会首先运行。很好地利用构造代码块的这两个特性不仅可以减少代码量,还可以让程序更容易阅读,特别是当所有的构造函数都要实现逻辑,而且这部分逻辑又很复杂时,这时就可以通过编写多个构造代码块来实现。每个代码块完成不同的业务逻辑(当然了,构造函数尽量简单,这是基本原则),按照业务顺序依次存放,这样在创建实例对象时JVM也就会按照顺序依次执行,实现复杂对象的模块化创建。
作者: 丁旭    时间: 2012-10-18 20:54
冯海霞 发表于 2012-10-18 20:48
构造代码块给所有对象进行统一初始化不就是说描述共同特征么

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

而其他成员,包括构造方法,都是属于对象的,在你的代码中,每个对象都有不同的country,虽然一开始都是CN,但是改动一个不会影响到另一个。
作者: 丁旭    时间: 2012-10-18 20:59
构造代码块之所以能给所有对象进行统一初始化,是因为在new一个对象开辟空间为属性赋默认值后,需调用构造方法进行初始化,但是在执行构造方法内的代码前,构造方法需要调用构造代码块为属性显式初始化。
作者: 王自强    时间: 2012-10-18 21:02
  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:11
{:soso_e129:}我好好研究研究。。。。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2