用构造器确保初始化

通过构造器,可以确保每个对象都会得到初始化
创建对象时,如果他的类有构造器,JAVA会在操作对象之前自动调用相应的构造器,从而保证初始化的进行
构造器的名称必须与类名完全相同,不接受任何参数的构造器叫做默认构造器(无参构造器)

  1. class Rock2{
  2. Rock2(int i){
  3. System.out.println("Rock:" + i);
  4. }
  5. }

有构造器形式参数,就可以在初始化对象时提供实际参数,初始化和创建时捆绑在一起的,二者不能分离
假设要创建一个类,既可以用标准方式进行初始化,也可以从文件中读取信息来进行初始化。这就需要两个构造器,一个默认构造器,另一个取字符串作为形式参数,字符串表示初始化对象所需要的文件名称。
为了让方法名相同而形式参数不同的构造器同时存在,必须用到方法重载
如果写的类中没有构造器,编译器会自动帮忙创建一个默认构造器

区分重载的方法

每个重载的方法都必须有一个独一无二的参数类型列表,甚至参数类型顺序不同也足以区分两个方法

基本类型的重载

基本类型可以从一个“较小”的类型自动转换为一个“较大”的类型
如果输入的数据类型(实际参数类型)小于方法中声明的形式参数类型,实际的数据类型会被提升,但是char类型不同,如果没有恰好接受参数的方法,就会把char类型直接提升为int型

This关键字

  1. public class ThisDemo {
  2. void f(){
  3. System.out.println(this);
  4. }
  5. public static void main(String[] args) {
  6. ThisDemo demo = new ThisDemo();
  7. demo.f();//此时demo就是调用f()的那个对象(实例)
  8. System.out.println(demo);
  9. }
  10. }

需要明确指出对当前对象的引用时,需要用到this关键字
在返回对当前对象的引用时

  1. public class Leaf {
  2. int i = 0;
  3. Leaf increment(){
  4. i ++;
  5. return this;
  6. }
  7. void print(){
  8. System.out.println(i);
  9. }
  10. public static void main(String[] args) {
  11. Leaf l = new Leaf();
  12. l.increment().increment().increment().increment().print();
  13. }
  14. }
  1. class Person{
  2. public void eat(Apple apple){
  3. Apple peeled = apple.getpeeled();
  4. System.out.println("好吃");
  5. }
  6. }
  7. class Peeler{
  8. static Apple peel(Apple apple){
  9. return apple;
  10. }
  11. }
  12. class Apple{
  13. Apple getpeeled(){
  14. return Peeler.peel(this);
  15. }
  16. }
  17. public class PassTest {
  18. public static void main(String[] args) {
  19. new Person().eat(new Apple());
  20. }
  21. }

尽管可以用this可以调用一个构造器,但是不能调用两个,并且必须要将构造器调用置于最起始处

  1. public class Flower {
  2. int petalCount = 0;
  3. String s ="initial value";
  4. Flower(int petals){//在构造器Flower(String s ,int petals)中被调用
  5. petalCount = petals;
  6. System.out.println(petalCount);
  7. }
  8. Flower(String ss){
  9. System.out.println(ss);
  10. s = ss;
  11. }
  12. Flower(String s ,int petals){
  13. this(petals);//调用构造器Flower(int petals)
  14. this.s= s;
  15. System.out.println("String & int args");
  16. }
  17. Flower(){
  18. this("hi",47);//调用构造器Flower(String s ,int petals)
  19. System.out.println("default constructor(no args)");
  20. }
  21. void printPetalCount(){
  22. System.out.println("PetalCount = " + petalCount + "s = " +s);
  23. }
  24. public static void main(String[] args) {
  25. Flower f = new Flower();
  26. f.printPetalCount();
  27. }
  28. }

static

在static方法内部不能调用非静态方法,反过来可以,而且可以在没有创建任何对象的前提下,仅仅通过类本身来调用static方法
static变量在加载到虚拟机的时候就已经被初始化
static变量初始化先于普通变量
static变量只会初始化一次,和创建的实例没有关系

成员初始化

成员变量会自动初始化,局部变量必须手动初始化.

指定初始化

如果想为某个变量赋值,可以在定义类成员变量的地方为其赋值

  1. public class InitialValues{
  2. boolean bool = true;
  3. char ch = 'x';
  4. byte b = 2;
  5. short s = 0xff;
  6. int i = 999;
  7. long l = 100000;
  8. float f = 1.2f;
  9. double d = 3.14159d;
  10. }

如果是一个类,可以创建一个实例并初始化

  1. class Depth{
  2. }
  3. public class Demo{
  4. Depth De = new Depth();
  5. }

也可以通过调用某个方法来提供初值

  1. public class MethodInit{
  2. int i = f();
  3. int f(){
  4. return 1;
  5. }
  6. }
  1. public class MethodInit2{
  2. int i = f();
  3. int j = g(i);
  4. int f(){
  5. return 1;
  6. }
  7. int g(int n){
  8. return n * 10;
  9. }
  10. }

构造器初始化

在运行时刻,可以调用方法或执行某些动作来确定初值,但是无法组织自动初始化的进行,它在构造器被调用之前使用

  1. public class Counter{
  2. int i;
  3. Count (){
  4. i = 1;
  5. }
  6. }

初始化顺序

在类的内部,变量定义的先后顺序 决定了初始化的顺序,即使变量定义散布于方法定义之间,他们仍会在任何方法包括构造器被调用之前得到初始化

静态数据的初始化

无论创建多少个对象,静态对象都只占用一份存储空间,并且,static关键字不能用于局部变量中,只能作用于“域”(说到域的时候指的就是成员变量)
初始的顺序是先静态对象,而后是非静态对象。
class对象只会加载一次,static域在加载的时候执行(即只执行一次)

  1. class Meat{
  2. Meat(String str){
  3. sout("Meat Constructor " + str);
  4. }
  5. }
  6. public class Dog{
  7. static Meat meat = new Meat("static");
  8. static void doSth(){
  9. sout("Dog Static Method " + meat);
  10. Dog(){
  11. sout("Dog constructor excute ..")
  12. }
  13. private static void main (String[] args){
  14. //new Dog();总结1-1,首次创建Dog实例,构造器会去执行
  15. //sout("Dog.meat");总结1-2,Dog中的静态域首次访问的时候去找Dog.class,意味着静态域会被初始化
  16. //Dog.doSth();总结1-3,Dog中的静态域首次访问的时候会去找Dog.class,意味着静态域会被初始化
  17. //总结2,静态域只在Dog.class对象加载到虚拟机的时候执行一次
  18. new Dog();//总结3,new Dog();分配存储空间,意味着初始化一个Dog实例,构造器将会执行
  19. //sout(instance.m)总结4,5 对Dog中成员变量的区域清零,即普通的成员便令m将为null
  20. //总结6,执行构造器,确保初始化
  21. }
  22. }
  23. }

数组初始化

枚举

枚举类型的构造器是私有的