构造方法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了构造方法相关的知识,希望对你有一定的参考价值。
*java中没有构造函数的概念 构造方法是创建对象时调用的方法,不要理解为构造方法就是创建对象的方法,因为构造方法主要是用来加载和初始化类的一些资源,创建一个对象并不完全靠 构造方法完成,构造方法主要进行创建对象的收尾工作 构造方法的作用? 能够在创建对象的时候完成对属性的赋值 构造方法如下: public class TestConstract1{ public static void main(String[] args){ Rect re = new Rect(45,32); re.showArea(); } } class Rect{ int length; int width; public Rect(int length, int width){ this.length = length; this.width = width; } public void showArea(){ System.out.println(length*width); } } java中只要是一个类,就一定有构造方法,即使程序员没有写,系统也会提供一个默认的构造方法,该方法无参且空体; 如果程序员写了自己的构造方法,那么系统就不再提供默认的构造方法,相当于中国的低保制度,没钱才领低保,有钱无论多少都不会领到低保 构造方法和普通方法的区别? 1:构造方法没有返回类型,连void都不能写 2:构造方法的名字需要和类名一模一样 -->构造方法名首字母大写 构造方法的首行默认是隐藏的super(): super():表示在执行本类构造方法之前,先去执行父类的构造方法 默认去找父类的无参构造方法: public class TestConstract2{ public static void main(String[] args){ Son s = new Son(); } } class GrandFather{ public GrandFather(){ //super() System.out.println("爷爷被创建出来了"); } } class Father extends GrandFather{ public Father(){ //super() System.out.println("爸爸被创建出来了"); } } class Son extends Father{ public Son(){ //super() System.out.println("儿子被创建出来了"); } } 打印的结果是: 爷爷被创建出来了 爸爸被创建出来了 儿子被创建出来了 -------------- 在java中,GrandFather默认继承Object类,所以,在创建对象时也会执行super(),然后去执行Object类的构造方法 如果父类没有无参构造方法: public class TestConstract3{ public static void main(String[] args){ Teacher tea = new Teacher("张三",29); System.out.println(tea.name); } } class Person{ String name; int age; public Person(String name, int age){ this.name = name; this.age = age; } //public Person(){} } class Teacher extends Person{ //String name; int age 从父类继承得到 public Teacher(String name,int age){ this.name = name; this.age = age; } } 此段程序执行会报错,因为Teacher类中默认会执行super(),去找父类Person的无参构造方法,而父类中没有无参构造方法,所以会报错 两种方法解决: 1.提供父类的无参构造方法 2.在super里面传参数,指定找父类的哪一个构造方法 构造方法首行还可以出现this(): public class TestConstract4{ 炒鸡蛋 cc = new 炒鸡蛋("西红柿"); } class 炒鸡蛋{ public 炒鸡蛋(){ System.out.println("热锅 放油"); System.out.println("打蛋 搅拌 放入锅中"); System.out.println("翻炒鸡蛋"); } public 炒鸡蛋(String x){// x-->佐料 this(); System.out.println("放入" + x); System.out.println("继续翻炒鸡蛋"); } } 该段程序执行结果: 热锅 放油 打蛋 搅拌 放入锅中 翻炒鸡蛋 放入西红柿 继续翻炒鸡蛋 this():表示要执行本构造方法之前,先去执行本类的其他构造方法,具体执行哪个构造方法,看this()里面的参数类型 下面是默认super()以及成员变量和局部变量区别的例子 public class TestConstract5{ public static void main(String[] args){ //Demo d1 = new Demo(); //System.out.println(d1.str); //打印,"能做对么" //Demo d2 = new Demo("etoak"); //System.out.println(d2.str); //打印,null Sample s = new Sample("etoak"); System.out.println(s.str); //打印,"能做对么" } } class Demo{ String str; //成员变量 public Demo(){ str = "能做对么?"; //成员变量 = "能做对么" } public Demo(String str){ //str:局部变量:etoak str = "还敢错么?"; //局部变量 = "还敢错么?" }//局部变量str消亡 } class Sample extends Demo{ //String str 继承得到成员变量str public Sample(String str){ //str局部变量 = etoak //super(); //成员变量 = 能做对么? str = "OK?" //局部变量 = OK? } //局部变量str消亡 } 下面是super调用父类有参构造方法实现代码共享的例子: public class ExecConstract{ public static void main(String[] args){ Teacher tea = new Teacher("Tom",29,5000.0); System.out.println(tea.name); } } class Person{ String name; int age; public Person(String name, int age){ this.name = name; this.age = age; } } class Teacher extends Person{ //name age double salary; public Teacher(string name,int age,double salary){ super(name,age); this.salary = salary; } } *:构造方法的首行只能出现this()/super()中的一个 有super()就不能有this() 有this()就不能有super() 面试题: 1.构造方法能不能方法重载? 可以 2.构造方法能不能进行方法覆盖? 方法覆盖的前提:需要子类先继承得到 但是父类的构造方法子类不能继承,所以没办法进行方法覆盖
参数传递
参数传递有两种说法,一种是java中只有值传递,另一种是java中的基本数据类型传值,引用数据类型传地址 public class TestArgs1{ public static void main(String[] args){ int a = 10; change(a); System.out.println(a); //打印结果:10 } public static void change(int x){ //int x = a; 隐含的一句代码 x = 55; } } 内存图:
public class Testargs2{ public static void main(String[] args){ int a = 56; int b = 90; change(a,b); System.out.println(a); //56 System.out.println(b); //90 } } public static void change(int x , int y){ //int x = a; int y = b; int z = x; x = y; y = z; }//x, y, z是局部变量 内存图:
public class TestArgs3{ public static void main(String[] args){ String str1 = new String("O"); String str2 = new String("K"); change(str1,str2); System.out.println(str1); //O System.out.println(str2); //K } public static void change(String x , String y){ //String x = str1,String y = str2; String z = x; x = y; y = z; }//x,y,z是局部变量 } java中,任何一个字符串底层都是char[]字符数组实现的 内存图:
public class TestArgs4{ public static void main(String[] args){ Student x = new Student(30); change(x); System.out.println(x.age); //打印,55 } public static void change(Student stu){ //Student stu = x ; stu.age = 55; } } class Student{ int age; public Student(int age){ this.age = age; } } 内存图:
public class TestArgs5{ public static void main(String[] args){ Student x = new Student(30); change(x); System.out.println(x.age); //打印,30 } public static void change(Student stu){ //Student stu = x; stu = new Student(55); } } class Student{ int age; public Student(int age){ this.age = age; } } 内存图:
String类的两个常见面试题: 1.new和不new之间的区别? String str1 = "etoak"; String str2 = new String("etoak"); 不new方式涉及到常量池查找机制 public class TestString1{ public static void main(String[] args){ String str1 = "etoak";//执行时,先到常量池寻找是否有"etoak",有,则不用创建对象;没有,则开辟内存空间,创建"etoak"对象,并将其存入常量池 String str2 = "etoak";//执行时,常量池中已经有"etoak",所以直接指向"etoak" System.out.println(str1 == str2); //true String str3 = new String("etoak"); String str4 = new String("etoak"); System.out.println(str3 == str4); //false } } 2.String StringBuffer StringBuilder都表示字符串,它们三者之间的区别? A:String和StringBuffer/StringBuilder之间的区别? 字符串的底层都是通过char[]字符数组实现的 String str = new String("etoak"); //[5]有5个字符,所以会开辟5个字符大小空间,当想要在其后再追加一个字符,则需要再申请开辟6个字符大小空间,并将etoak复制到新的空间, 以后每追加字符串都需要重新申请开辟空间并复制,效率较低 StringBuffer buffer = new StringBuffer("etoak"); //[5+16]有5个字符,因为StringBuffer/StringBuilder在创建对象时会预留16块缓冲区, 当不断字符串里面追加元素的时候,先使用缓冲区,缓冲区也装满之后,如果再追加n个字符,会申请开辟[21+n]*2大小的空间,以后再装满都按照这种机制扩充 当不断字符串里面追加元素的时候,尽量使用StringBuffer/StringBuilder 追加方法:buffer.append(); 效率对比: public class Speed{ public static void main(String[] args){ //String += //StringBuffer append String str1 = new String();//"" StringBuffer buffer = new StringBuffer();//"" long time1 = System.currentTimeMillis(); for(int x = 1; x <= 10000 ; x++){ str1 += x; } long time2 = System.currentTimeMillis(); System.out.println(time2 - time1); long time3 = System.currentTimeMillis(); for(int x = 1; x <= 10000; x++){ buffer.append(x); } long time4 = System.currentTimeMillis(); System.out.println(time4 - time3); } } B:StringBuffer和StringBuilder的之间的区别? StringBuffer同一时间只允许一个线程进行访问,效率较低,但是不会出现并发错误 StringBuilder同一时间允许多个线程进行访问,效率较高,但可能会出现并发错误
以上是关于构造方法的主要内容,如果未能解决你的问题,请参考以下文章