精华内容
下载资源
问答
  • 初始化对象成员属性的魔术方法
    2021-04-21 22:50:00

    第一个对象实例

    /*

    * 创建对象,并对 对象中的属性进行设置

    * PHP中把以两个下划线__开头的方法称为魔术方法(Magic methods)

    */

    class FirstClass

    {

    private $name = '';

    private $sex = 0;

    private $age = 0;

    //1.创建构造方法,对成员是属性初始化

    public function __construct($name='',$sex=1,$age=20)

    {

    $this->name = $name;

    $this->sex = $sex;

    $this->age = $age;

    }

    //查询器:__get()通过它可以在对象的外部获取私有成员属性的值

    public function __get($privatename)

    {

    if ($privatename == "age") {

    return "你的年龄是".$this->$privatename;

    } else {

    return $this->$privatename;

    }

    }

    //3.设置器:__set()通过它可以在对象的外部给私有成员属性设值

    public function __set($privatename, $value)

    {

    if ($privatename == "age")

    {

    if($value > 60){

    $this->$privatename = $value;

    }else{

    $this->$privatename = "您输入的年龄:".$value."不合格";

    }

    }else{

    $this->$privatename = $value;

    }

    }

    }

    运行实例 »

    点击 "运行实例" 按钮查看在线实例

    更多相关内容
  • 对象成员初始化*3.对象成员的访问*///导入类require'class/GirlFriend1.php';//实例化类,创建对象的过程$girlfriend1=newGirlFriend1();//var_dump($girlfriend1);echo$girlfriend1->name,'';//访问类中成员中...

    实例

    /**

    *1.对象的创建

    * 2.对象成员的初始化

    * 3.对象成员的访问

    */

    // 导入类

    require 'class/GirlFriend1.php';

    // 实例化类,创建对象的过程

    $girlfriend1 = new GirlFriend1();

    //var_dump($girlfriend1);

    echo $girlfriend1->name,'
    ';  // 访问类中成员中的属性变量

    echo $girlfriend1->getInfo(), '
    '; // 访问类中成员中的方法函数

    echo $girlfriend1->getInfo('金莲',30), '
    '; // 访问类中成员中的方法函数

    echo $girlfriend1->getStature([120,130,180]),'
    ';

    运行实例 »

    点击 "运行实例" 按钮查看在线实例

    实例

    class GirlFriend1

    {

    // 类中的成员: 属性(变量),方法(函数)

    // 类中用类似变量的方式定义类的属性

    //姓名,public 是访问控制,

    public $name = '冰冰姐';

    //年龄

    public $age = 18;

    // 三维

    public $stature = [90,80,90];

    //类中使用类似函数的方式来定义方法

    public function getInfo($name='', $age=0)

    {

    //        $this: 当前类被实例化之后的对象, -> 对象成员访问符

    $this->name = empty($name) ? $this->name : $name;

    $this->age = ($age == 0) ? $this->age : $age;

    return '姓名:' . $this->name . ', 年龄:' . $this->age. '
    ';

    }

    public function getStature($stature =[])

    {

    //        $this: 当前类被实例化之后的对象, -> 对象成员访问符

    $this->stature = empty($stature) ? $this->stature : $stature;

    return '胸围:' . $this->stature[0] . ', 腰围:' . $this->stature[1]. ',臀围:'. $this->stature[2].'
    ';

    }

    }

    运行实例 »

    点击 "运行实例" 按钮查看在线实例

    实例

    /**

    * 1.使用构造方式来初始化对象

    * 2. 对象的访问控制,public,private

    * 3. 对象属性的获取器/ getter 和 修改器 / setter

    */

    require 'class/GirlFriend2.php';

    $girlfriend2 = new GirlFriend2('金莲妹妹',23,[87,88,89]);

    //echo $girlfriend2->name,'
    ';

    echo $girlfriend2->getName('西门大官人');

    $girlfriend2->setAge(139);

    //echo $girlfriend2->getAge();

    运行实例 »

    点击 "运行实例" 按钮查看在线实例

    实例

    class GirlFriend2

    {

    //访问控制: private

    private $name;

    //年龄

    private $age;

    // 三维

    private $stature = [];

    // 声明构造方法: 对象属性的初始化,在类实例化的时候,自动调用

    public function __construct($name, $age, array $stature)

    {

    // private 访问符限制的属性仅在当前对象内部可以使用

    $this->name = $name;

    $this->age = $age;

    $this->stature = $stature;

    }

    //创建对外访问的公共接口

    public function getName($yourName='')

    {

    $msg = '非法访问';

    if (!empty($yourName) && $yourName == '武大郎') {

    $msg = $this->name;

    }

    return $msg;

    }

    //设置器

    public function setAge($age=0)

    {

    if ($age >=0 && $age <=120) {

    $this->age = $age;

    }

    echo '非法数据';

    }

    //获取器

    public function getAge()

    {

    return $this->age;

    }

    }

    运行实例 »

    点击 "运行实例" 按钮查看在线实例

    实例

    require 'class/GirlFriend3.php';

    $girlfriend3 = new GirlFriend3('冰冰姐',38,[98,128,188]);

    echo $girlfriend3->name,'
    ';

    echo $girlfriend3->age,'
    ';

    $girlfriend3->age = 45;

    echo $girlfriend3->age,'
    ';

    echo $girlfriend3->email,'
    ';

    运行实例 »

    点击 "运行实例" 按钮查看在线实例

    实例

    class GirlFriend3

    {

    //访问控制: private

    private $name;

    //年龄

    private $age;

    // 三维

    private $stature = [];

    //属性收集器

    private $data = [];

    // 声明构造方法: 对象属性的初始化,在类实例化的时候,自动调用

    public function __construct($name, $age, array $stature)

    {

    // private 访问符限制的属性仅在当前对象内部可以使用

    $this->name = $name;

    $this->age = $age;

    $this->stature = $stature;

    }

    //创建对外访问的公共接口

    // 类中用双下划线的方法是系统定义,由系统自动调用,叫魔术方法

    public function __get($name)

    {

    $msg = null;

    if (isset($this->$name)) {

    $msg = $this->$name;

    } elseif (isset($this->data[$name])) {

    $msg = $this->data[$name];

    } else {

    $msg = '无此属性';

    }

    return $msg;

    }

    //设置器

    public function __set($name, $value)

    {

    $this->$name = $value;

    }

    }

    运行实例 »

    点击 "运行实例" 按钮查看在线实例

    展开全文
  • 1、__construct 构造方法2、__destruct 析构方法3、__get 获取成员值4、__set 设定成员值5、__isset 判断成员值6、__unset unset成员值7、__clone 克隆对象8、__toString 输出类9、__call 调用不存在的方法10、__...

    1、__construct  构造方法

    2、__destruct  析构方法

    3、__get 获取成员值

    4、__set 设定成员值

    5、__isset 判断成员值

    6、__unset unset成员值

    7、__clone 克隆对象

    8、__toString 输出类

    9、__call 调用不存在的方法

    10、__autoload 自动加载类

    11、__sleep 对象串行化调用

    12、__wakeup 对象反串行化调用

    、、、

    目前只接触这么多,具体使用方法和说明和查阅手册,这里只做一个简单记录

    php面向对象类中常用的魔术方法

    php面向对象类中常用的魔术方法   1.__construct():构造方法,当类被实例化new $class时被自动调用的方法,在类的继承中可以继承与覆盖该方法,例: //__construct( ...

    python的魔术方法大全

    在Python中,所有以“__”双下划线包起来的方法,都统称为“Magic Method”(魔术方法),例如类的初始化方法 __init__ ,Python中所有的魔术方法均在官方文档中有相应描述,这 ...

    PHP 中 16 个魔术方法详解

    PHP 中 16 个魔术方法详解   前言 PHP中把以两个下划线__开头的方法称为魔术方法(Magic methods),这些方法在PHP中充当了举足轻重的作用. 魔术方法包括: __constru ...

    php中的常用魔术方法总结

    以下是对php中的常用魔术方法进行了详细的总结介绍,需要的朋友可以过来参考下 常用的魔术方法有:__Tostring () __Call() __autoLoad() __ clone() __GET ...

    PHP面向对象-----魔术方法

    PHP面向对象-----魔术方法 __get($name)--触发时机:当调用一个不访问的成员属性的时候,会自动触发,可以利用这个方法来完成对不可调用的属性进行调用,但是不能设置值 ___set($n ...

    PHP中的常用魔术方法

    魔术方法: 是指某些情况下,会自动调用的方法,称为魔术方法 php面向对象中,提供了这几个魔术方法,他们的特点都是 以双下划线__开头的 __construct()  构造方法 __destruct( ...

    php中12个魔术方法

    本文列举了php面向对象当中12个魔术方法,并对此进行一一详细介绍,希望对新手有所帮助. 1.构造方法: __construct() 参数:自定义 触发时机:new的一瞬间自动调用 作用:初始化成员属 ...

    PHP中的常见魔术方法功能作用及用法实例

    概述 在面向对象编程中,PHP提供了一系列的魔术方法,这些魔术方法为编程提供了很多便利.PHP中的魔术方法通常以__(两个下划线)开始,并且不需要显示的调用而是由某种特定的条件出发. 开始之前 在总结 ...

    深入理解javascript中实现面向对象编程方法

    介绍Javascript中面向对象编程思想之前,需要对以下几个概念有了解: 1. 浅拷贝和深拷贝:程序在运行过程中使用的变量有在栈上的变量和在堆上的变量,在对象或者变量的赋值操作过程中,大多数情况先是 ...

    随机推荐

    Mac锁屏

    http://www.dbform.com/html/2006/192.html 应用程序-实用工具-钥匙锁-菜单栏中的钥匙串访问-偏好设置-选中“在菜单栏中显示钥匙串”

    Oracle查询

    1.普通查询 select * from 表格 查询所有内容 select 列名,列名 from 表格查询某几列 2.条件查询 select * from 表格 where 条件 条件查询 selec ...

    USACO section1&period;1 Broken Necklace

    /* ID: vincent63 LANG: C TASK: beads */ #include #include #include&l ...

    iOS开发-相关文档

    关于调试,查看Xcode Overview文档相关部分:http://developer.apple.com/library/ios/documentation/ToolsLanguages/Conc ...

    c&plus;&plus; THUNK技术

    这里想说的是:代码中的关键点为用指令jmp pFunc跳转到你想要运行的函数pFunc. 指令"jmp xxxx"占5个字节,代码中用了个一字节对齐的结构体struct Thunk ...

    解决PhpStorm卡顿的问题

    以前的开发一直使用phpstorm.可谓是情有独钟,但是发现随着开发phpStorm逐渐变得卡顿,也试过其他的编译器,但是都感觉没有PhpSrom好用,网上百度了一下,看到不一样的回答.只要修改两个J ...

    pam密码策略

    PAM 的使用历史 PAM 是关注如何为服务验证用户的 API.在使用 PAM 之前,诸如 login(和 rlogin.telnet.rsh)之类的应用程序在 /etc/passwd 中查找用户名, ...

    GCD HDU - 2588

    输入 N 和 M (2<=N<=1000000000, 1<=M<=N), 找出所有满足1<=X<=N 且 gcd(X,N)>=M 的 X 的数量. Inpu ...

    &lbrack;MeetCoder&rsqb; Count Pairs

    Count Pairs Description You are given n circles centered on Y-aixs. The ith circle’s center is at po ...

    取出资源文件中的bitmap,并将其保存到TMemoryStream中,从资源里载入图象而不丢失调色板

    从资源里载入图象而不丢失调色板 procedure loadgraphic(naam:string);var  { I've moved these in here, so they exist on ...

    展开全文
  • Java 初始化的深认知(第二篇)Java 类初始化和对象初始化明解Java中new一个对象的详细过程,JVM执行了那些操作new一个对象的详细过程什么时候需要初始化一个类获得类的资源初始化对象 Dog dog = new Dog()创建一个...


    首先,大家看一下这段代码的执行顺序,你是否理解的如注释所写:

    //父类Animal
    class Animal {  
    /*8、执行初始化*/  
        private int i = 9;  
        protected int j;  
     
    /*7、调用构造方法,创建默认属性和方法,完成后发现自己没有父类*/  
        public Animal() {  
    /*9、执行构造方法剩下的内容,结束后回到子类构造函数中*/  
            System.out.println("i = " + i + ", j = " + j);  
            j = 39;  
         }  
     
    /*2、初始化根基类的静态对象和静态方法*/  
        private static int x1 = print("static Animal.x1 initialized");  
        static int print(String s) {  
            System.out.println(s);  
            return 47;  
        }  
    }  
     
    //子类 Dog
    public class Dog extends Animal {  
    /*10、初始化默认的属性和方法*/ 
        private int k = print("Dog.k initialized");  
     
    /*6、开始创建对象,即分配存储空间->创建默认的属性和方法。 
         * 遇到隐式或者显式写出的super()跳转到父类Animal的构造函数。
         * super()要写在构造函数第一行 */  
        public Dog() { 
    /*11、初始化结束执行剩下的语句*/
            System.out.println("k = " + k);  
            System.out.println("j = " + j);  
        }  
     
    /*3、初始化子类的静态对象静态方法,当然mian函数也是静态方法*/  
        private static int x2 = print("static Dog.x2 initialized");
     
    /*1、要执行静态main,首先要加载Dog.class文件,加载过程中发现有父类Animal, 
        *所以也要加载Animal.class文件,直至找到根基类,这里就是Animal*/       
        public static void main(String[] args) {  
     
    /*4、前面步骤完成后执行main方法,输出语句*/ 
            System.out.println("Dog constructor"); 
    /*5、遇到new Dog(),调用Dog对象的构造函数*/  
            Dog dog = new Dog();   
    /*12、运行main函数余下的部分程序*/            
            System.out.println("Main Left"); 
        }  
    }
    
    输出结果:
    static Animal.x1 initialized
    static Dog.x2 initialized
    Dog constructor
    i = 9, j = 0
    Dog.k initialized
    k = 47
    j = 39
    Main Left
    

    如果你的理解和注释的顺序有出处,那么说明你对Java对象创建的过程还不熟悉.那快看看我接下来写的吧 😄 😄 😄 😄 😄 😄

    Java 类初始化和对象初始化明解

    类的生命周期为:加载、连接(验证、准备、解析)、初始化、使用、卸载。
    首先,明确对象初始化类初始化是不一样的。

    对象初始化是什么?

    对象初始化是在类的生命周期第三个阶段初始化执行的,这个时期实例构造器<init>会收集初始化代码块实例变量赋值语句构造函数,然后进行赋初值操作。

    那么,什么是类初始化呢?

    类初始化是指,在jvm第一次创建一个对象时,类的构造器<clinit>实际执行的过程。
    连接准备阶段,类的构造器<clinit>会收集静态代码块静态成员变量赋值语句,然后进行赋初值,这就是类的初始化。但这样理解有些狭义,因为类里面还有构造方法,所以说类的初始化还应执行实例构造器<init>,完成对象初始化,这样来说,一个完整的类初始化就完成了。

    在Java类初始化过程中,要总共执行这些结构,分别是

    • 静态代码块初始化
    • 静态成员变量初始化
    • 代码块初始化
    • 实例变量初始化
    • 构造函数初始化

    Java中new一个对象的详细过程,JVM执行了那些操作

    new一个对象的详细过程

    1. 当虚拟机遇到一条new指令时候,首先去检查这个指令的参数是否能 在常量池中能否定位到一个类的符号引用(即类的带路径全名),并且检查这个符号引用代表的类是否已被加载、解析和初始化过,即验证是否是第一次使用该类。如果没有(不是第一次使用),那必须先执行相应的类加载过程(class.forname())。
    2. 在类加载检查通过后,接下来虚拟机将为新生的对象分配内存 。对象所需的内存的大小在类加载完成后便可以完全确定,为对象分配空间的任务等同于把一块确定大小的内存从Java堆中划分出来,目前常用的有两种方式,根据使用的垃圾收集器的不同使用不同的分配机制:
        (1)指针碰撞(Bump the Pointer):假设Java堆的内存是绝对规整的,所有用过的内存都放一边,空闲的内存放在另一边,中间放着一个指针作为分界点的指示器,那所分配内存就仅仅把那个指针向空闲空间那边挪动一段与对象大小相等的距离。
        (2)空闲列表(Free List):如果Java堆中的内存并不是规整的,已使用的内存和空间的内存是相互交错的,虚拟机必须维护一个空闲列表,记录上哪些内存块是可用的,在分配时候从列表中找到一块足够大的空间划分给对象使用。
    3. 内存分配完后,虚拟机需要将分配到的内存空间中的数据类型都 初始化为零值(不包括对象头)
    4. 虚拟机要对对象头进行必要的设置,例如这个对象是哪个类的实例(即所属类)、如何才能找到类的元数据信息、对象的哈希码、对象的GC分代年龄等信息,这些信息都存放在对象的对象头中。

    至此,从虚拟机视角来看,一个新的对象已经产生了。但是在Java程序视角来看,执行new操作后会接着执行如下步骤:

    1. 调用对象的init()方法,根据传入的属性值给对象属性赋值。
    2. 在线程栈中新建对象引用,并指向堆中刚刚新建的对象实例。

    对象虽然创建完了,但是在创建对象的过程中,可能会发生一些小意外。比如:在划分可用空间时,如果是在并发情况下,那么划分就不一定是线程安全的。因为有可能出现正在给A对象分配内存,指针还没有来得及修改,对象B又同时使用了原来的指针分配内存的情况,那么,解决这个问题有两种方案:

    1. 分配内存空间的动作进行同步处理:实际上虚拟机采用CAS配上失败重试的方式保证了更新操作的原子性。
    
    2.内存分配的动作按照线程划分在不同的空间中进行: 为每个线程在Java堆中预先分配一小块内存 ,称为本地线程分配缓冲(Thread Local Allocation Buffer, TLAB)。
    

    Java 对象的使用:对对象的访问定位

    我们的Java程序需要通过栈上的reference数据来操作堆上的具体对象。目前主流访问方式有 使用句柄访问(间接访问)直接指针访问 两种:

    1. 句柄访问:
    Java堆中将会划分出一块内存来作为句柄池,reference中存储的就是对象句柄位置,而句柄中包含了对象实例数据与类型数据各自的具体地址信息。
    在这里插入图片描述
    2. 直接指针访问:
    如果使用直接指针访问,那么Java堆对象的布局中就必须考虑如何放置访问类型数据的相关信息,而reference中存储的直接就是对象地址。
    在这里插入图片描述

    类加载

    Java类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using) 和 卸载(Unloading)七个阶段。其中准备、验证、解析3个部分统称为连接(Linking),如图所示:
    在这里插入图片描述
    加载、验证、准备、初始化和卸载这5个阶段的顺序是确定的,类的加载过程必须按照这种顺序按部就班地开始,而解析阶段则不一定:它在某些情况下可以在初始化阶段之后再开始,这是为了支持Java语言的运行时绑定(也称为动态绑定或晚期绑定)。以下陈述的内容都已HotSpot为基准。特别需要注意的是,类的加载过程必须按照这种顺序按部就班地“开始”,而不是按部就班的“进行”或“完成”,因为这些阶段通常都是相互交叉地混合式进行的,也就是说通常会在一个阶段执行的过程中调用或激活另外一个阶段。
    了解了Java类的生命周期以后,那么我们现在来回答一个问题:虚拟机什么时候才会加载Class文件并初始化类呢?

    类初始化时机

    那么,什么情况下虚拟机需要开始初始化一个类呢?这在虚拟机规范中是有严格规定的,虚拟机规范指明 有且只有 五种情况必须立即对类进行初始化(而这一过程自然发生在加载、验证、准备之后):
     (1)遇到new、getstatic、putstatic或invokestatic这四条字节码指令(注意,newarray指令触发的只是数组类型本身的初始化,而不会导致其相关类型的初始化,比如,new String[]只会直接触发String[]类的初始化,也就是触发对类[Ljava.lang.String的初始化,而直接不会触发String类的初始化)时,如果类没有进行过初始化,则需要先对其进行初始化。生成这四条指令的最常见的Java代码场景是:

    • 使用new关键字实例化对象的时候;
    • 读取或设置一个类的静态字段(被final修饰,已在编译器把结果放入常量池的静态字段除外)的时候;
    • 调用一个类的静态方法的时候。

    (2) 使用java.lang.reflect包的方法对类进行反射调用的时候,如果类没有进行过初始化,则需要先触发其初始化。

    (3) 当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化。

    (4) 当虚拟机启动时,用户需要指定一个要执行的主类(包含main()方法的那个类),虚拟机会先初始化这个主类。

    (5) 当使用jdk1.7动态语言支持时,如果一个java.lang.invoke.MethodHandle实例最后的解析结果REF_getstatic,REF_putstatic,REF_invokeStatic的方法句柄,并且这个方法句柄所对应的类没有进行初始化,则需要先出触发其初始化。

    注意,对于这五种会触发类进行初始化的场景,虚拟机规范中使用了一个很强烈的限定语:“有且只有”,这五种场景中的行为称为对一个类进行主动引用。除此之外,所有引用类的方式,都不会触发初始化,称为被动引用

    特别需要指出的是,类的实例化与类的初始化是两个完全不同的概念:

    • 类的实例化是指创建一个类的实例(对象)的过程;
    • 类的初始化是指为类中各个类成员(被static修饰的成员变量)赋初始值的过程,
    • 类生命周期中的一个阶段。
      3、被动引用的几种经典场景
        1)、通过子类引用父类的静态字段,不会导致子类初始化
        对于静态字段,只有直接定义这个字段的类才会被初始化,因此通过其子类来引用父类中定义的静态字段,只会触发父类的初始化而不会触发子类的初始化。
        2)、通过数组定义来引用类,不会触发此类的初始化
        3)、常量在编译阶段会存入调用类的常量池中,本质上并没有直接引用到定义常量的类,因此不会触发定义常量的类的初始化
    public class ConstClass{
    
        static{
            System.out.println("ConstClass init!");
        }
    
        public static  final String CONSTANT = "hello world";
    }
    
    public class NotInitialization{
        public static void main(String[] args){
            System.out.println(ConstClass.CONSTANT);
        }
    }/* Output: 
            hello world
     *///:~
    

    上述代码运行之后,只输出 “hello world”,这是因为虽然在Java源码中引用了ConstClass类中的常量CONSTANT,但是编译阶段将此常量的值“hello world”存储到了NotInitialization常量池中,对常量ConstClass.CONSTANT的引用实际都被转化为NotInitialization类对自身常量池的引用了。也就是说,实际上NotInitialization的Class文件之中并没有ConstClass类的符号引用入口,这两个类在编译为Class文件之后就不存在关系了。

    类加载过程

    1. 加载:
     在加载阶段(可以参考java.lang.ClassLoader的loadClass()方法),虚拟机需要完成以下三件事情:
      (1). 通过一个类的全限定名来获取定义此类的二进制字节流(并没有指明要从一个Class文件中获取,可以从其他渠道,譬如:网络、动态生成、数据库等);
      (2). 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构;
      (3). 在内存中(对于HotSpot虚拟就而言就是方法区)生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口;

    加载阶段和连接阶段(Linking)的部分内容(如一部分字节码文件格式验证动作)是交叉进行的,加载阶段尚未完成,连接阶段可能已经开始,但这些夹在加载阶段之中进行的动作,仍然属于连接阶段的内容,这两个阶段的开始时间仍然保持着固定的先后顺序。

    特别地,第一件事情(通过一个类的全限定名来获取定义此类的二进制字节流)是由类加载器完成的,具体涉及JVM预定义的类加载器、双亲委派模型等内容,详情请参见我的博文《双亲委派机制》

    2. 验证:
    验证是连接阶段的第一步,这一阶段的目的是为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。 验证阶段大致会完成4个阶段的检验动作:

    文件格式验证:验证字节流是否符合Class文件格式的规范(例如,是否以魔术0xCAFEBABE开头、主次版本号是否在当前虚拟机的处理范围之内、常量池中的常量是否有不被支持的类型)

    元数据验证:对字节码描述的信息进行语义分析,以保证其描述的信息符合Java语言规范的要求(例如:这个类是否有父类,除了java.lang.Object之外);

    字节码验证:通过数据流和控制流分析,确定程序语义是合法的、符合逻辑的;

    符号引用验证:确保解析动作能正确执行。

    3. 准备
     准备阶段是正式为类变量(static 成员变量)分配内存并设置类变量初始值(零值)的阶段,这些变量所使用的内存都将在方法区中进行分配。这时候进行内存分配的仅包括类变量,而不包括实例变量,实例变量将会在对象实例化时随着对象一起分配在堆中。其次,这里所说的初始值“通常情况”下是数据类型的零值,假设一个类变量的定义为:

        public static int value = 123;
    

    那么,变量value在准备阶段过后的值为0而不是123。因为这时候尚未开始执行任何java方法,而把value赋值为123的putstatic指令是程序被编译后,存放于类构造器方法()之中,所以把value赋值为123的动作将在初始化阶段才会执行。至于“特殊情况”是指:当类字段的字段属性是ConstantValue时,会在准备阶段初始化为指定的值,所以标注为final之后,value的值在准备阶段初始化为123而非0。

      public static final int value = 123;
    

    4. 解析
    解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程。(得到类或者字段、方法在内存中的指针或者偏移量,以便直接调用该方法),这个可以在初始化之后再执行。解析动作主要针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用点限定符7类符号引用进行。
     解析需要静态绑定的内容。

    5.初始化(先父后子)
     (1) 为静态变量赋值
     (2)执行static代码块
     (3)构造函数

    注意:static代码块只有jvm能够调用,如果是多线程需要同时初始化一个类,仅仅只能允许其中一个线程对其执行初始化操作,
    其余线程必须等待,只有在活动线程执行完对类的初始化操作之后,才会通知正在等待的其他线程。
    

    因为子类存在对父类的依赖,所以类的加载顺序是先加载父类后加载子类,初始化也一样。 不过,父类初始化时,子类静态变量的值也有有的,是默认值。
    最终,方法区会存储当前类类信息,包括类的静态变量类初始化代码定义静态变量时的赋值语句静态初始化代码块)、实例变量定义实例初始化代码定义实例变量时的赋值语句实例代码块和构造方法)和实例方法,还有父类的类信息引用

    补充:

    通过实例引用调用实例方法的时候,先从方法区中对象的实际类型信息找,找不到的话再去父类类型信息中找。
    如果继承的层次比较深,要调用的方法位于比较上层的父类,则调用的效率是比较低的,因为每次调用都要经过很多次查找。这时候大多系统会采用一种称为虚方法表的方法来优化调用的效率。
    所谓虚方法表,就是在类加载的时候,为每个类创建一个表,这个表包括该类的对象所有动态绑定的方法及其地址,包括父类的方法,但一个方法只有一条记录,子类重写了父类方法后只会保留子类的。当通过对象动态绑定方法的时候,只需要查找这个表就可以了,而不需要挨个查找每个父类。

    展开全文
  • 1.类的属性成员变量对象的创建创建对象的过程称之为实例,当一个对象被创建后,包含三个方面的特性对象聚丙属性方法,句柄用于区分不同的对象对象属性方法,与类中的成员变量和成员函数对应,obj = ...
  • 作用:就是为成员属性初始化格式:Function __construct([参数列表]){//方法体,通常用来对成员属性进行初始化赋值}2.析构函数__destruct()说明:在销毁一个对象之前执行的一些特定操作,例如:释放文件、关闭...
  • PHP 对象 魔术方法

    2021-03-23 23:02:35
    /**__construct()构造方法*在对象初始化时自动调用*__destruct()析构方法*在对象释放资源时自动调用*__get()取值*在取私有属性值时自动调用*__set()设置值*在设置私有属性值自动调用*__isset()判断值*在使用isset()...
  • 1.什么是魔术方法魔术方法指的是系统在特定的时机自动调用的方法。 2.访问权限 在介绍魔术方法之前,先介绍一下PHP中的访问权限: 在PHP中一般有三个权限修饰符,并且权限修饰符是可选项,常见的权限修饰符...
  • 1、内置成员 定义完类后直接就有的成员 class Father(): pass class Demo(Father): ''' 类的说明文档 ''' name='zhangsan' age=20 def say(self): print('say somthing') res=Demo.__dict__ print(res)#{...
  • ### 内置成员```python# 获取类/对象的所属成员 类/对象.__dict__res = Demo.__dict__ # 获取当前类的所属成员res = obj.__dict__ # 获取当前对象的所属成员# 获取类的文档信息 类/对象.__doc__res = Demo.__doc__...
  • __construct: 在创建对象时候初始化对象,一般用于对变量赋初值。 __destruct: 和构造函数相反,当对象所在函数调用完毕后执行。 __call:当调用对象中不存在的方法会自动调用该方法。 __get():获取对象不存在的...
  • **类:**用来描述具有相同的属性方法对象的集合—>车类 **对象:**通过类定义的数据结构实例—>我的车 **属性:**对象的描述信息---->车的零部件 **方法:**对象的行为—>车的功能(将零部件组装,...
  • Python常用魔术方法

    2020-12-08 09:21:05
    魔术方法在类或对象的某些事件出发后会自动执行,让类具有神奇的“魔力”。如果希望根据自己的程序定制自己特殊功能的类,那么就需要对这些方法进行重写。Python中常用的运算符、for循环、以及类操作等都是运行在...
  • 1、属性属性含义__name__类、函数、方法等的名字 __dir____module__类定义所在的模块名__class__对象或类所属的类 只是返回基类__bases__返回自己到object的类,类的基类元组,顺序为在基类列表中出现的顺序。...
  • 类的概念:类是具有相同属性和操作的一组对象的集合。它为属于该类的所有对象提供了统一的抽象描述,其内部包括属性和操作两个主要部分。...2.定义一个有成员属性和操作的类Class Person{成员属性........
  • 私有成员,只有在类的内部才能方法 2 私有成员和公有成员: 2.1 静态字段(静态属性)访问限制 公有静态字段:类可以访问;类内部可以访问;派生类中可以访问 私有静态字段:仅类内部可以访问; 2.2.1 公有静态...
  • 魔术方法实现重载PHP 通过魔术方法实现重载属性重载(属性拦截器)方法重载(方法拦截器)事件委托(方法重定向)实战案例(查询构造器)trait: 类功能横向扩展 PHP 通过魔术方法实现重载 魔术方法 作用 __...
  • php面向对象中的魔术方法中文说明1.__construct()实例化对象是被自动调用。当__construct和以类名为函数名的函数 同时存在时调用__construct,另一个不背调用。类名为函数名的函数为老版的构造函数。2.__destruct()当...
  • php反序列化魔术方法

    2022-07-03 22:39:00
    php反序列化魔术方法
  • 作用:初始化成员属性 参数:可以有,可以没有,取决于设定和逻辑 返回值:没有 注意:如果构造方法具有参数,且参数没有默认值,在实例化对象时,必须在类名后面的括号内添加实参 1-2析构方法:__destruct() 触发...
  • 文章目录1 魔术方法2 类的魔术方法2.1 基本的魔法方法和常用属性2.2 有关属性2.3 比较操作符2.4 算数运算符2.5 反运算2.6 增量赋值运算2.7 一元操作符2.8 类型转换2.9 上下文管理(with 语句)2.10 容器类型3 常用...
  • 1.对象克隆 clone PHP4面向对象功能一个很大的缺点,是将对象视为另一种数据类型,这使得很多常见的OOP方法无法使用,如设计模式。这些方法依赖于将对象作为引用传递给其他类方法,而不是作为值传递,而按值传递却...
  • 日常python学习笔记DAY 12—init初始化方法 在这里插入代码片''' 魔术方法: 魔术方法也和普通方法一样都是类中定义的成员方法 魔术方法不需要去手动调用的,魔术方法会在某种情况下,自动触发... #成员属性 name=None
  • 面向对象(三):python中的下划线与常用魔术方法属性
  • Python魔术方法

    2022-07-26 21:29:17
    就是获取成员,删除成员,修改成员相关联的魔术方法。特点不需要人工调用,在特定的时刻自动执行.我想和@@@@@@@熊楮墨去逛街。给张三做的蛋糕已经完成。bool方法已经被触发。‘我\n喜欢\t你’限定符号@>10。......
  • 在Python中,所有用" __ " 包起来的方法,都称为“魔术方法”(eg: __ len__, __ init__)。 魔术方法一般是为了让显示器调用的,自己并不需要调用它们。 一、特殊属性 魔术方法名称 功能 __ ...
  • Python中常用魔术方法

    2021-01-29 12:43:11
    阅读别人编写的Python代码时,经常会在他们定义的类中看到以“__”为开头和结尾的方法,经过进一步学习后才知道类中实现的这类方法被称为“魔术方法”。“魔术方法”在一些情况下会被自动的调用,通过一些简单的定义...
  • 文章目录特殊属性创建,初始化与销毁可视化类型转换索引与切片重复,连接与成员操作符循环with语句安全上下文![在这里插入图片描述]...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,903
精华内容 1,961
热门标签
关键字:

初始化对象成员属性的魔术方法

友情链接: spcaview-20051127.tar.gz