用构造器确保初始化
通过构造器,可以确保每个对象都会得到初始化
创建对象时,如果他的类有构造器,JAVA会在操作对象之前自动调用相应的构造器,从而保证初始化的进行
构造器的名称必须与类名完全相同,不接受任何参数的构造器叫做默认构造器(无参构造器)
class Rock2{Rock2(int i){System.out.println("Rock:" + i);}}
有构造器形式参数,就可以在初始化对象时提供实际参数,初始化和创建时捆绑在一起的,二者不能分离
假设要创建一个类,既可以用标准方式进行初始化,也可以从文件中读取信息来进行初始化。这就需要两个构造器,一个默认构造器,另一个取字符串作为形式参数,字符串表示初始化对象所需要的文件名称。
为了让方法名相同而形式参数不同的构造器同时存在,必须用到方法重载
如果写的类中没有构造器,编译器会自动帮忙创建一个默认构造器
区分重载的方法
每个重载的方法都必须有一个独一无二的参数类型列表,甚至参数类型顺序不同也足以区分两个方法
基本类型的重载
基本类型可以从一个“较小”的类型自动转换为一个“较大”的类型
如果输入的数据类型(实际参数类型)小于方法中声明的形式参数类型,实际的数据类型会被提升,但是char类型不同,如果没有恰好接受参数的方法,就会把char类型直接提升为int型
This关键字
public class ThisDemo {void f(){System.out.println(this);}public static void main(String[] args) {ThisDemo demo = new ThisDemo();demo.f();//此时demo就是调用f()的那个对象(实例)System.out.println(demo);}}
需要明确指出对当前对象的引用时,需要用到this关键字
在返回对当前对象的引用时
public class Leaf {int i = 0;Leaf increment(){i ++;return this;}void print(){System.out.println(i);}public static void main(String[] args) {Leaf l = new Leaf();l.increment().increment().increment().increment().print();}}
class Person{public void eat(Apple apple){Apple peeled = apple.getpeeled();System.out.println("好吃");}}class Peeler{static Apple peel(Apple apple){return apple;}}class Apple{Apple getpeeled(){return Peeler.peel(this);}}public class PassTest {public static void main(String[] args) {new Person().eat(new Apple());}}
尽管可以用this可以调用一个构造器,但是不能调用两个,并且必须要将构造器调用置于最起始处
public class Flower {int petalCount = 0;String s ="initial value";Flower(int petals){//在构造器Flower(String s ,int petals)中被调用petalCount = petals;System.out.println(petalCount);}Flower(String ss){System.out.println(ss);s = ss;}Flower(String s ,int petals){this(petals);//调用构造器Flower(int petals)this.s= s;System.out.println("String & int args");}Flower(){this("hi",47);//调用构造器Flower(String s ,int petals)System.out.println("default constructor(no args)");}void printPetalCount(){System.out.println("PetalCount = " + petalCount + "s = " +s);}public static void main(String[] args) {Flower f = new Flower();f.printPetalCount();}}
static
在static方法内部不能调用非静态方法,反过来可以,而且可以在没有创建任何对象的前提下,仅仅通过类本身来调用static方法
static变量在加载到虚拟机的时候就已经被初始化
static变量初始化先于普通变量
static变量只会初始化一次,和创建的实例没有关系
成员初始化
指定初始化
如果想为某个变量赋值,可以在定义类成员变量的地方为其赋值
public class InitialValues{boolean bool = true;char ch = 'x';byte b = 2;short s = 0xff;int i = 999;long l = 100000;float f = 1.2f;double d = 3.14159d;}
如果是一个类,可以创建一个实例并初始化
class Depth{}public class Demo{Depth De = new Depth();}
也可以通过调用某个方法来提供初值
public class MethodInit{int i = f();int f(){return 1;}}
public class MethodInit2{int i = f();int j = g(i);int f(){return 1;}int g(int n){return n * 10;}}
构造器初始化
在运行时刻,可以调用方法或执行某些动作来确定初值,但是无法组织自动初始化的进行,它在构造器被调用之前使用
public class Counter{int i;Count (){i = 1;}}
初始化顺序
在类的内部,变量定义的先后顺序 决定了初始化的顺序,即使变量定义散布于方法定义之间,他们仍会在任何方法包括构造器被调用之前得到初始化
静态数据的初始化
无论创建多少个对象,静态对象都只占用一份存储空间,并且,static关键字不能用于局部变量中,只能作用于“域”(说到域的时候指的就是成员变量)
初始的顺序是先静态对象,而后是非静态对象。
class对象只会加载一次,static域在加载的时候执行(即只执行一次)
class Meat{Meat(String str){sout("Meat Constructor " + str);}}public class Dog{static Meat meat = new Meat("static");static void doSth(){sout("Dog Static Method " + meat);Dog(){sout("Dog constructor excute ..")}private static void main (String[] args){//new Dog();总结1-1,首次创建Dog实例,构造器会去执行//sout("Dog.meat");总结1-2,Dog中的静态域首次访问的时候去找Dog.class,意味着静态域会被初始化//Dog.doSth();总结1-3,Dog中的静态域首次访问的时候会去找Dog.class,意味着静态域会被初始化//总结2,静态域只在Dog.class对象加载到虚拟机的时候执行一次new Dog();//总结3,new Dog();分配存储空间,意味着初始化一个Dog实例,构造器将会执行//sout(instance.m)总结4,5 对Dog中成员变量的区域清零,即普通的成员便令m将为null//总结6,执行构造器,确保初始化}}}
数组初始化
枚举
枚举类型的构造器是私有的
