在构建创造对象时调用的函数。(只针对对象构造,无对象,不构造)
作用:
可以给对象进行初始化。创建对象都必须要通过构造函数初始化。 一个类中如果没有定义过构造函数,那么该类中会有一个默认的空参数构造函数,如果在类中定义了指定的构造函数,那么类中的默认构造函数就没有了。
特点:
1.函数名与类名相同。(首字母大写) 2.不用定义返回值类型。 3.没有具体的返回值。 例如:
Person(String n,int a) { age=a; name=n; }一般函数和构造函数有什么区别呢?
构造函数:对象创建时,就会调用与之对应的构造函数,对对象进行初始化。 构造函数:对象创建后,会调用只调用一次。 一般函数:对象创建后,需要函数功能时才调用。 一般函数:对象创建后,可以被调用多次。
什么时候定义构造函数呢?
在描述事物时,该事物已存在就具备的一些内容,这些内容都定义在构造函数中。 一个类中可以有多个构造函数。(多个构造函数以重载的形式出现)
构造函数的内存图解 注意: 构造函数是要进栈的。调用一次后弹栈,初始化完毕。
Person p = new Person(“xiao”);调用Person 首先会系统默认初始化 然后,构造函数的初始化再来一次 最后,自定义的构造函数再走一次
细节1:
Person(String n) Public void Person(String n) //加上一个void就变成了方法可以同时拥有 第一个是构造函数初始化,只能使用一次 第二个是方法 可以多次使用
细节2:
在方法中不可以调用构造函数,因为构造函数只针对对象,无对象,不构造
细节3:
构造函数前面加上void 变成一般函数 不再是构造函数
细节4:
构造函数中自动有return;语句
当Person per = new Person(“旺财”); 定义一个对象结束后,其中的name属性的值还是null。因为以上的构造函数,进栈后,在栈中有一个name的局部变量,然后就自己给自己赋值。与堆里面的name属性无关,故name的值仍然是null。
正确做法是,用 this 表现是是对象的 name。 当成员变量和局部变量同名时,可以用this区分。this:代表当前对象。this就是所在函数所属对象的引用。this . name =>per.name。简单说,哪个对象调用了this所在的函数,this即代表该对象的引用。
public void speak() { System.out.println(this.name+":"+this.age); } Person(String name,int age) { this.age=age; this.name=name; }以上都是有this的,加了this即引用当前对象。如果没有this时,如果堆内存没有这个变量,回到栈内存中找。
构造函数调用另一个重构的构造函数
Person(String name,int age) { this(name); this.age=age; } Person(String name) { this.name=name; }其中的内存图解为: 以上为执行到程序person p = new Person(“旺财”,30);在调用构造函数时,执行以下语句时的内存图解。
this(name);—>this.name=name;以上构造函数调用另一个构造函数时,有一个需要注意的点:this只能定义在构造函数的第一行。因为初始化动作要先执行。而且不能两个构造函数不能互相调用,有这样会形成递归,可能造成栈内存溢出。
Person(String name,int age) { this(name); this.age=age; }这样是对的。
Person(String name,int age) { this.age=age; this(name); }而这样是错的。
this的应用 只要类中用到本类的属性,就可以用this.属性表示。
static的特点
1 static是一个修饰符 用于修饰成员 2 static修饰的成员被所有对象所共享 3 static优先于对象存在 因为static成员随着类的加载就已经存在了 4 static修饰的成员多了一种调用方式 就可以直接被类名所调用(类名调用:person. name) 5 static修饰的数据是共享数据 对象中存储的是特有数据 被static修饰的变量称为静态变量或类变量
成员变量和静态变量(类变量)的区别?
1.两个变量的生命周期不同
成员变量随着对象的创建而存在,随着对象的被回收而释放。 静态变量随着类的加载而存在,随着类的消失而消失。
2.调用方式不同
成员变量只能被对象调用。 静态变量可以被对象调用,还可以被类调用。
3.别名不同
成员变量也称为实例变量。 静态变量称为类变量。
4.数据存储位置不同。
成员变量数据存储在堆内存的对象中,所以也叫对象的特有数据. 静态变量数据存储在方法区(共享数据区)的静态区,所以也叫对象的共享数据.
静态使用的注意事项:
1,静态方法只能访问静态成员。(非静态既可以访问静态,又可以访问非静态)(因为静态随着类存在而存在,而非静态成员随对象存在而存在,而类先存在,后存在对象,故静态方法无法访问非静态变量) 2,静态方法中不可以使用this或者super关键字。 3,主函数是静态的。 (只能调用静态的函数和变量,调用非静态的函数和变量可以用对象调用(创建一个对象来调用这个函数)。)
class Demo1 { int num = 4; public static void main(String[] args) { new Demo1() .show(); //匿名对象 } public void show() { System.out.println(num); } }主函数特殊之处:
1.格式是固定的。 2.被JVM识别和调用。
public static void main(String[] args)public:因为权限必须是最大的。 static:不需要对象的,直接用主函数所属类名调用即可。 void:主函数没有具体的返回值。 main:函数名,不是关键字,只是一个jvm识别的固定的名字。 String[] args:这是主函数的参数列表,是一个数组类型的参数,而且元素都是字符串类型。
注意:
1、(String[] args)是main的参数列表,可以给主函数传参数,一般不传参数啦,所以一般为null。 2、main函数的格式是固定的,public static void main(String[] args) ,其中可变的是args,即参数名。
注意: 1、左上为栈,右上为堆,下面为方法区(数据共享区)。 2、在方法区中左边为非静态方法区,右边为静态方法区。 3、在方法区中都是函数(方法)的代码。以便调用。调用时进栈,调用完毕则出栈。
静态什么时候用?
1.静态变量 a) 当分析对象中所具备的成员变量都相同时,这时这个成员可以被静态修饰。 b) 只要这个数据在对象中是不同的,就是对象的特有数据,必须存储在对象中,是非静态的。 c) 如果是相同的数据,对象不需要修改,只需要使用即可,不需要存储在对象中,定义成静态的。
2.静态函数 a) 函数是否用静态修饰,就参考一点,就是该函数功能是否有访问到对象中的特有数据。 简单点说,从源代码看,该功能是否需要访问非静态的成员变量,如果需要,该功能 就是非静态的。 如果不需要,就可以将该功能定义成静态的。 但是非静态需要被对象调用 而仅创建对象调用非静态的没有访问特有数据的方法 该对象的创建是没有意义的
随着类的加载而执行 而且只执行一次
作用:用于给类进行初始化
class StaticCodeDemo { static { System.out.println("a"); } public static void main(String[] args) { System.out.println("aaa"); } } //这个时候会先输出a 在输出aaa 因为静态代码块随着类的创建而执行一般用类静态代码块初始化的类中全都是静态成员。
class Demo2 { static int num ; static { num = 10; System.out.println("huahd"); } }构造代码块
class Demo1 { public static void main(String[] args) { Person p1 = new Person(); } public void show() } class Person { private String name; { // 构造代码块,可以给所有对象进行初始化的。与对象有关,凡是定义一个类的对象,就执行一次。 System.out.println("new Person"); } Person() // 构造函数,给对应的对象进行针对的初始化,可能会有构造重构Person(name)等。 { name = "baby"; cry(); } public void cry() { System.out.println("哇哇"); } } //结果为 new Person //哇哇在函数中的{ }为局部代码块,在类里面的为构造代码块,类中前加static{}的代码块为静态代码块。面试中问,那个代码块先执行,一般是静态代码块限制性,因为随着类的存在而加载,若有对象就是构造代码块,若函数则局部代码块。