JAVA语言笔记 —— 初始化
小标 2018-07-24 来源 : 阅读 962 评论 0

摘要:本文主要向大家介绍了JAVA语言笔记 —— 初始化,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助。

本文主要向大家介绍了JAVA语言笔记 —— 初始化,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助。

 

一、属性初始化和构造器调用

1)编译器会为属性指定一个默认的初始值,例如:int i; 默认初始值为 0,  double d; 默认初始值为0.0 

2)局部变量使用前必须由程序员指定初始值 

3)在构造器被调用之前,属性就被初始化了

例1:

 

package com.example;

 

public class Values{

private boolean bt;

private char c;

private byte b;

private short s;

private int i;

private float f;

private double d;

private Values v;


public void show(){

System.out.println("属性的默认初始化值:");

System.out.println("boolean: " + bt);

System.out.println("char: " + c);

System.out.println("byte: " + b);

System.out.println("short: " + s);

System.out.println("int: " + i);

System.out.println("float: " + f);

System.out.println("double: " + d);

System.out.println("Values: " + v);

}

}

 

 

package com.example;

 

public class Test{

public static void main(String[] args){

Values val = new Values();

val.show();

}

}

 


运行结果为:

 

属性的默认初始化值:

boolean: false

char:

byte: 0

short: 0

int: 0

float: 0.0

double: 0.0

Values: null


· 编译器为所有的属性都指定了一个默认初始值

· 编译器为对象的引用指定的默认初始值是 null,例如:例子中的 private Values v;

· 编译器为 char 类型指定的初始值是0(ASCII 中的 NUL),是空字符,这里以空白表示

例2:


package com.example;

 

public class Man{

public void speak(){

int i;

System.out.println("i = " + i); //  error,i 是局部变量,局部变量使用之前必须要初始化

}

}


例3:

 

package com.example;

 

public class Man{

public Man(int i){

System.out.println("Man" + "(" + i + ")");

}

}

 

 

package com.example;

 

public class Woman{

public Man m1 = new Man(1);

public Man m2 = new Man(2);


public Woman(){

System.out.println("Woman()");

}


public  Man m3 = new Man(3);

}

 

 

package com.example;

 

public class Test{

public static void main(String[] args){

new Woman();

}

}

 

 

运行结果为:

 

Man(1)

Man(2)

Man(3)

Woman()

 

· 这个例子不是使用系统的默认值对属性进行初始化,而是通过我指定的值对属性进行初始化

· Woman 类中有三个属性 m1,m2,m3 和一个 构造器 Woman(),从运行结果可以看出:属性先被初始化,然后构造器才被调用

· 属性先被初始化这一特性与属性的位置无关,例如:Woman 类中 m3 就位于构造器的后面,但 m3 也在构造器被调用之前就已经被初始化了

 

[ 返回顶部 ]

 

 

二、初始化的顺序

1)属性分为静态属性和非静态属性,且静态属性比非静态属性先初始化,即初始化顺序为:静态属性 -> 非静态属性 -> 构造器调用 

2)静态属性只会在创建对象或者被直接调用的时候初始化(在主类中静态属性也会被初始化),非静态属性只会在创建对象的时候初始化 

3)无论创建多少个对象,静态属性只占用一块存储空间,所以静态属性只会初始化一次,而非静态属性在每次创建对象时都会初始化 

4)含有继承关系的初始化:当创建一个子类对象时,该对象会包含一个父类的对象,那么保证父类对象初始化的方法是:在子类构造器中调用父类构造器

例1:

 

package com.example;

 

public class Pear{

public Pear(int i){

System.out.println("Pear" + "(" + i + ")");

}

}

 


package com.example;

 

public class Apple{

public Pear p1 = new Pear(1);

public static Pear p2 = new Pear(2);


public Apple(){

System.out.println("Apple()");

}


public static Pear p3 = new Pear(3);

}



package com.example;

 

public class Test{

public static void main(String[] args){

new Apple();

}

}



运行结果:

 

Pear(2)

Pear(3)

Pear(1)

Apple()


· 该例子中用 new 创建了 Apple 对象,所以 Apple 类中的静态属性和非静态属性都会初始化

· 初始化顺序:静态属性 -> 非静态属性 -> 构造器调用,例如:例子中先输出 Pear(2) 和 Pear(3),然后输出 Pear(1),最后调用 Apple() 构造器,所以是先初始化静态属性 p2 和 p3,然后初始化非静态属性 p1,最后调用构造器 Apple()

例2:


package com.example;

 

public class Pear{

public Pear(int i){

System.out.println("Pear" + "(" + i + ")");

}

}



package com.example;

 

public class Apple{

public static String color = "red";

public static int number = 10;

public String size = "big";

}



package com.example;

 

public class Test{

public static void main(String[] args){

System.out.println("Hello World !");

System.out.println("color: " + Apple.color);

}

static Pear p1 = new Pear(1);

static Pear p2 = new Pear(2);

Pear p3 = new Pear(3);

}



运行结果:


Pear(1)

Pear(2)

Hello World !

color: red


· Test 类是主类,所以静态属性 p1 和 p2 都会初始化。非静态属性 p3 不会初始化,是因为我们没有创建 Test 对象

· Apple 类中有两个静态属性和一个非静态属性,该例子中调用了 Apple.color ,静态属性 color 在调用的时候会初始化为 red,而静态属性 number 和非静态属性 size 没有被调用,也没有创建对象,所以此时它们不会初始化

例3:


package com.example;

 

public class Cat{

public Cat(int i){

System.out.println("Cat" + "(" + i + ")");

}

}



package com.example;

 

public class Dog{

public Cat c1 = new Cat(1);

public static Cat c2 = new Cat(2);


public Dog(){

System.out.println("Dog()");

}


public static Cat c3 = new Cat(3);

}



package com.example;

 

public class Test{

public static void main(String[] args){

System.out.println("第一次创建对象");

Dog d1 = new Dog();

System.out.println("第二次创建对象");

Dog d2 = new Dog();

}

}



运行结果:

 

第一次创建对象

Cat(2)

Cat(3)

Cat(1)

Dog()

第二次创建对象

Cat(1)

Dog()


· 第一次创建对象的时候,静态属性和非静态属性都初始化了,但是第二次创建对象的时候,只有非静态属性会再次初始化,静态属性只初始化一次

例4:

父类不含构造器


package com.example;

 

public class T{

public T(int i){

System.out.println("T" + "(" + i + ")");

}

}



package com.example;

 

public class Person{ // 父类

public static T t4 = new T(4);

public T t5 = new T(5);

public static T t6 = new T(6);

}



package com.example;

 

public class Man extends Person{ // 子类

public static T t1 = new T(1);

public T t2 = new T(2);

public static T t3 = new T(3);


public Man(){

System.out.println("Man()");

}

}



package com.example;

 

public class Test{

public static void main(String[] args){

new Man();      

}

}



运行结果:

 

T(4)

T(6)

T(1)

T(3)

T(5)

T(2)

Man()


· 某个类不含构造器时,编译器会为这个类生成一个默认构造器,该生成的默认构造器是一个无参构造器。这些操作是在编译时完成的,所以我们看不见

· 当父类含有默认构造器时,编译器会自动在子类的构造器中调用父类的构造器来对父类进行初始化。这个过程也是在编译时完成的,所以我们看不见

· 初始化的顺序:父类静态属性 -> 子类静态属性 -> 父类非静态属性 -> 子类非静态属性 -> 调用子类构造器

父类含有无参构造器


package com.example;

 

public class T{

public T(int i){

System.out.println("T" + "(" + i + ")");

}

}



package com.example;

 

public class Person{ // 父类

public static T t4 = new T(4);

public T t5 = new T(5);

public static T t6 = new T(6);


public Person(){ // 无参构造器

System.out.println("Person()");

}

}



package com.example;

 

public class Man extends Person{ // 子类

public static T t1 = new T(1);

public T t2 = new T(2);

public static T t3 = new T(3);


public Man(){

System.out.println("Man()");

}

}



package com.example;

 

public class Test{

public static void main(String[] args){

new Man();      

}

}



运行结果:

 

T(4)

T(6)

T(1)

T(3)

T(5)

Person()

T(2)

Man()


· 父类含有无参构造器时和父类含有默认构造器时差不多,编译器会自动在子类的构造器中调用父类的构造器来对父类进行初始化

· 不同的是,当我们创建了构造器之后,编译器就不会再为类创建一个默认构造器了

· 初始化顺序:父类静态属性 -> 子类静态属性 -> 父类非静态属性 -> 父类构造器调用 -> 子类非静态属性 -> 子类构造器调用

父类只含有有参构造器


package com.example;

 

public class T{

public T(int i){

System.out.println("T" + "(" + i + ")");

}

}



package com.example;

 

public class Person{ // 父类

public static T t4 = new T(4);

public T t5 = new T(5);

public static T t6 = new T(6);


public Person(int i){

System.out.println("Person" + "(" + i + ")"); // 有参构造器

}

}



package com.example;

 

public class Man extends Person{ // 子类

public static T t1 = new T(1);

public T t2 = new T(2);

public static T t3 = new T(3);


public Man(){

super(1); // super 关键字表示调用父类构造器,且必须位于子类构造器的第一行,每个子类的构造器只能调用父类构造器一次

System.out.println("Man()");

}

}



package com.example;

 

public class Test{

public static void main(String[] args){

new Man();      

}

}



运行结果:

 

T(4)

T(6)

T(1)

T(3)

T(5)

Person(1)

T(2)

Man()


· 当父类只有有参构造器时,子类构造器中必须使用 super 关键字调用父类构造器,否则会报错。

· 当子类有多个构造器时,子类中的每个构造器都必须要调用父类构造器(如果父类有多个构造器,那么子类构造器只需挑父类构造器的其中一个来调用即可,不过一定要保证子类的每个构造器都有调用父类构造器)

父类既含有无参构造器,也含有有参构造器


package com.example;

 

public class T{

public T(int i){

System.out.println("T" + "(" + i + ")");

}

}



package com.example;

 

public class Person{ // 父类

public static T t4 = new T(4);

public T t5 = new T(5);

public static T t6 = new T(6);


public Person(){ // 无参构造器

System.out.println("Person()");

}

public Person(int i){

System.out.println("Person" + "(" + i + ")"); // 有参构造器

}

}



package com.example;

 

public class Man extends Person{ // 子类

public static T t1 = new T(1);

public T t2 = new T(2);

public static T t3 = new T(3);


public Man(){ // 子类无参构造器

System.out.println("Man()");

}

public Man(int i){ // 子类有参构造器

System.out.println("Man" + "(" + i + ")");

}

}



package com.example;

 

public class Test{

public static void main(String[] args){

System.out.println("调用子类的无参构造器");

new Man();

System.out.println("调用子类的有参构造器");

new Man(1);

}

}



运行结果:

 

调用子类的无参构造器

T(4)

T(6)

T(1)

T(3)

T(5)

Person()

T(2)

Man()

调用子类的有参构造器

T(5)

Person()

T(2)

Man(1)


· 当父类含有无参构造器时,即使子类有多个构造器,这些构造器也无需显式地通过 super 关键字调用父类构造器,因为编译器会自动为每个子类的构造器都调用父类的无参构造器,例如:例子中运行结果打印了两次 Person(),这是两次创建子类对象时,编译器自动调用父类中无参构造器的结果

总结:如果要建立继承关系时,最好给父类创建一个无参构造器或者不给父类创建任何构造器

 

[ 返回顶部 ]

 

 

三、静态块和非静态块

1)静态块会使所有静态属性都被初始化,即使静态属性不在静态块内

例如:


package com.example;

 

public class T{

public T(int i){

System.out.println("T" + "(" + i + ")");

}

}



package com.example;

 

public class S{

public static T t1;

public static T t2;

public static T t3;

public T t4;

public T t5;

public T t6;

public T t7 = new T(7); // t7 不在静态块内


static{ // 静态块

t1 = new T(1);

t2 = new T(2);

t3 = new T(3);

}


{ // 非静态块

t4 = new T(4);

t5 = new T(5);

t6 = new T(6);

}

}



package com.example;

 

public class Test{

public static void main(String[] args){

System.out.println(S.t1);

}

}



运行结果:

 

T(7)

T(1)

T(2)

T(3)

com.example.T@15db9742


· 可以看到,该例子中只是调用了 S.t1 ,静态属性 t2, t3, t7 也跟着被初始化了

 

[ 返回顶部 ]

 

 

四、初始化的方式

1)在定义处初始化 

2)在构造器内初始化 

3)在静态块或非静态块内初始化 

4)等到要用的时候再初始化

 

[ 返回顶部 ]

 

 

五、数组初始化

数组有三种初始化的方式

第一种初始化的方式

 

package com.example;

import java.util.Arrays;

 

public class Test{

public static void main(String[] args){

int[] a = {1,2,3,4,5};


/* error, 只能写在同一行

 

 int[] a;

 a = {1,2,3,4,5}

 

*/


// System.out.println(a); 这种方式无法打印数组的值


System.out.println(Arrays.toString(a)); // 打印数组的值

}

}

 


运行结果:

 

[1, 2, 3, 4, 5]


第二种初始化的方式


package com.example;

import java.util.Arrays;

 

public class Test{

public static void main(String[] args){

int[] a;

a = new int[5];

for(int i=0; i<5; i++){

a[i] = i;

}

System.out.println(Arrays.toString(a));

}

}



运行结果:

 

[0, 1, 2, 3, 4]


第三种初始化的方式

例1:


package com.example;

import java.util.Arrays;

 

public class Test{

public static void main(String[] args){

int[] a;

a = new int[]{1,2,3,4,5};

System.out.println(Arrays.toString(a));

}

}



运行结果:

 

[1, 2, 3, 4, 5]


例2(这种方式的用途):


package com.example;

import java.util.Arrays;

 

public class T{

public void show(Integer[] i){ //必须为 Integer 类型,不能是 int 这些基本类型

System.out.println(Arrays.toString(i));

}

public void show(String[] str){

System.out.println(Arrays.toString(str));

}

}



package com.example;

 

public class Test{

public static void main(String[] args){

T t1 = new T();

t1.show(new Integer[]{5,4,3,2,1}); // 必须为 Integer 类型,不能是 int 这些基本类型

t1.show(new String[]{"张三", "李四", "王五"});

}

}



运行结果:

 

[5, 4, 3, 2, 1]

[张三, 李四, 王五]


· 很明显这种方式的优点是无需额外定义一个数组变量 int[] a

以上就是职坐标整理发布关于JAVA的介绍,先祝大家对它有了一定的了解吧,了解更多内容,请关注职坐标编程语言JAVA频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 1 不喜欢 | 0
看完这篇文章有何感觉?已经有1人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程