构造方法的定义
- 普通方法的定义:修饰符 返回值类型 方法名(参数列表){方法体}
- 构造方法的定义:修饰符 方法名【与类同名】(参数列表){方法体}
package cn.tedu.demo2;
public class TestConstructor {
public static void main(String[] args) {
//构造方法是一个用来创建对象的方法
//默认存在无参构造(不需要手动添加无参构造)
//一旦添加了含参构造,默认的无参构造会被覆盖,所以要手动添加无参构造
//构造方法执行的时机:创建对象时立即触发
//只要创建对象,就会触发指定的构造方法,创建几个,触发几次
Person p = new Person(); //每一次new(实例化)创建对象时,都会自动调用无参构造方法(自动调用无参构造?),前提是本身没有创建含参构造方法
Person p1 = new Person("洗碗");//含参构造会覆盖默认的无参构造
Person p2 = new Person("曾龙",20,"成都");//全参构造除了可以创建对象外,还可以给这个对象的所有属性赋值
System.out.println(p2.address);
p.eat();
System.out.println(p.address);
}
}
class Person{
String name;
int age;
String address;
//普通方法的定义:修饰符 返回值类型 方法名(参数列表){方法体}
//构造方法的定义:修饰符 方法名【与类同名】(参数列表){方法体}
public Person(){//无参构造
System.out.println("我是Person类的无参构造!");
}
//构造方法也有重载的现象
public Person(String s){//含参构造
System.out.println("我是Person类的含参构造!"+s);
}
//全参构造,可以创建对象并给对象的全部属性赋值
public Person(String name, int age, String address) {//全参构造
this.name = name;
this.age = age;
this.address = address;
System.out.println("我是Person类的全参构造!");
}
public void eat(){
System.out.println("干饭啦!");
}
}
结果显示:
我是Person类的无参构造!
我是Person类的含参构造!洗碗
我是Person类的全参构造!
成都
干饭啦!
null
构造代码块
- 位置:类里面,方法外面,类似于成员变量
- 执行时机:构造代码块在构造方法执行之前执行
- 作用:用来提取所有构造方法的共性内容,给对象统一初始化数据
- 注意:
- 构造代码块的作用是给对象进行初始化。
- 对象一建立就运行构造代码块了,而且优先于构造函数执行。这里要强调一下,有对象建立,才会运行构造代码块,类不能调用构造代码块的,而且构造代码块与构造函数的执行顺序是前者先于后者执行。
- 构造代码块与构造函数的区别是:构造代码块是给所有对象进行统一初始化,而构造函数是给对应的对象初始化,因为构造函数是可以多个的,运行哪个构造函数就会建立什么样的对象,但无论建立哪个对象,都会先执行相同的构造代码块。也就是说,构造代码块中定义的是不同对象共性的初始化内容。
package cn.tedu.demo2;
public class TestBlock {
public static void main(String[] args) {
Teacher t1 = new Teacher();
Teacher t2 = new Teacher("曾老师");
Teacher t3 = new Teacher("数学","曾老师",23);
String act = t1.teach();
System.out.println(t3.age+"岁的"+t3.name+act+"教"+t3.subject);
}
}
class Teacher{
String subject;
String name;
int age;
{
subject = "数学+语文";
System.out.println("我是构造代码块");//构造代码块在构造方法执行之前执行
//作用:用来提取所有构造方法的共性内容
}
public String teach(){
return "正在上课";
}
public Teacher(){
System.out.println("无参构造"+subject);
}
public Teacher(String s){
System.out.println("有参构造!"+s+subject);
}
public Teacher(String subject, String name, int age) {
this.subject = subject;
this.name = name;
this.age = age;
System.out.println("全参构造!"+subject);
}
}
结果显示:
我是构造代码块
无参构造数学+语文
我是构造代码块
有参构造!曾老师数学+语文
我是构造代码块
全参构造!数学
23岁的曾老师正在上课教数学
局部代码块
- 位置:方法里,与局部变量相同
- 执行时机:调用本方法时,此局部代码块才会被执行
- 作用:控制变量的作用范围,缩短变量生命周期。(方法中,某段代码之后,都不再使用某个变量(这个变量有可能是一个很大的Map集合,很占内存),则可以将其定义到局部代码块中,及时结束其生命周期,释放空间!)
package cn.tedu.demo2;
public class TestBlock {
public static void main(String[] args) {
Teacher t1 = new Teacher();
Teacher t2 = new Teacher("曾老师");
Teacher t3 = new Teacher("数学","曾老师",23);
t3.teach();
System.out.println(t3.age+"岁的"+t3.name+"教"+t3.subject);
}
}
class Teacher{
String subject;
String name;
int age;
{
subject = "数学+语文";
System.out.println("我是构造代码块");//构造代码块在构造方法执行之前执行
//作用:用来提取所有构造方法的共性内容
}
public void teach(){
System.out.println("正在上课");
//创建局部代码块
//位置:方法里,与局部变量相同
//执行时机:调用本方法时,此局部代码块才会被执行
//作用:控制变量的作用范围,范围越小越好
{
int i=10; //局部代码块
System.out.println(i); //这里变量i只出现在局部代码块内,所以超出此代码块不会被引用
}
// System.out.println(i);//不可以被引用的变量i(超出范围)
}
public Teacher(){
System.out.println("无参构造"+subject);
}
public Teacher(String s){
System.out.println("有参构造!"+s+subject);
}
public Teacher(String subject, String name, int age) {
this.subject = subject;
this.name = name;
this.age = age;
System.out.println("全参构造!"+subject);
}
}
结果显示:
我是构造代码块
无参构造数学+语文
我是构造代码块
有参构造!曾老师数学+语文
我是构造代码块
全参构造!数学
正在上课
10
23岁的曾老师教数学
静态代码块
- 它是随着类的加载而执行,只执行一次,并优先于主函数。具体说,静态代码块是由类调用的。类调用时,先执行静态代码块,然后才执行主函数的。
- 静态代码块其实就是给类初始化的,而构造代码块是给对象初始化的。
- 静态代码块中的变量是局部变量,与普通函数中的局部变量性质没有区别。
- 一个类中可以有多个静态代码块
package cn.tedu.demo2;
public class StaticBlock{
static int a = 7;
public StaticBlock(){
System.out.println("我是构造方法");
}
{
System.out.println("我是构造代码块");
}
static {
a+=3;
System.out.println("我是静态代码块");
}
public static void main(String[] args) {//先执行静态代码块,多个静态代码块按从上至下顺序执行
System.out.println(a); //2;然后执行打印a
new StaticBlock(); //先调用构造代码块,再调用构造方法
}
static {
a/=5;
System.out.println("我也是静态代码块");
}
}
结果显示:
我是静态代码块
我也是静态代码块
2
我是构造代码块
我是构造方法
执行顺序
对于一个类而言,按照如下顺序执行:
- 执行静态代码块
- 执行构造代码块
- 执行构造函数
执行时机:静态代码块->构造代码块->构造方法->对象创建->普通方法->局部代码块
this变量名相同时使用
this.变量名:调用成员变量
package cn.tedu.demo2;
public class TestVariableThis1 {
public static void main(String[] args) {
Cat c = new Cat();
Cat c1 = new Cat("朵朵");
c.eat();//会默认调用无参构造
c1.eat();//调用含参构造
}
}
class Cat{
int s = 30;
int sum = 20;
public Cat(){
sum = sum+100;
System.out.println(sum);
System.out.println(s);
System.out.println(this.sum);
}
public Cat(String s){
System.out.println(s);
eat();
}
public void eat(){
System.out.println("eat:"+this.sum);
// this.eat();
}
}
this之构造方法之间的调用(不能来回互相调用)
this():调用无参构造
this(“”):调用含参构造
package cn.tedu.demo2;
public class TestVariableThis2 {
public static void main(String[] args) {
Dog dog = new Dog();
Dog dog1 = new Dog("狗狗");
}
}
/*1.this还可以实现构造方法之间的调用
* */
class Dog{
public Dog(){//无参构造
/*在无参构造中调用含参构造功能
* 规定:this关键字必须在构造方法中的第一行使用,否则报错*/
// this("旺财");
System.out.println("我是无参构造");
}
public Dog(String s){//含参构造
//在含参构造中调用无参构造
//规定:this关键字必须在构造方法中的第一行使用,否则报错
this();
System.out.println("我是含参构造"+s);
voice();
}
public void voice(){
System.out.println("旺旺~");
}
}