成员变量: 定义在类里面,为类所有;可以被public、private、protect、static修饰;存储在堆中;没有被static修饰必须先new对象才能使用;当前类的所有方法都可以调用;如果该类有子类,则子类也可以调用;可以不赋值,如果没有赋值基本数据类型返回对应的值,非基本数据类型返回null。
定义:
public class Test{
public int num;
}
初始化方式:
1、如果只是单纯的定义一个成员变量而没有赋值,则编译器会自动添加相应的默认值。如:
public class Test{
//基本数据类型
private boolean flag; //默认值:false
private int _int; //默认值:0
private byte _byte; //默认值:0
private char _char; //默认值:’\u0000′,但是Eclipse中打印的时候会是空白符”方框”,因为空白符的code是0x20,0x20以下为不可见的控制字符。
private short _short; //默认值:0
private float _float; //默认值:0.0
private long _long; //默认值:0
private double _double; //默认值:0.0
//引用类型默认为null
private String string;
}
2、直接赋值
public class Test {
private int num = 1;
private String name = “xiaomin”;
public Person person = new Person();
}
3、通过方法初始化
public class Test{
private int i = f();
private int j = g(i);
private int f() {
return 10;
}
private int g(int i){
return i*2
}
}
但是,编译器在初始化对象的时候是按顺序执行的,所以不能像下面那样的方法来初始化:
public class Test{
private int j = g(i);
private int i = f();
private int f() {
return 10;
}
private int g(int i){
return i*2
}
}
4、通过构造函数初始化
public class Test{
int num ;
public Test(){
num = 10;
}
}
在进入构造器之前,编译器会先给num默认初始化为0,进入构造器之后再赋值为10。
初始化顺序:
一个类在编译的时候是成员变量优先初始化,而成员变量的初始化顺序是由成员变量在该类里面定义的顺序决定的。
package com.extendstest;
public class OrderOfInitialization {
public static void main(String[] args) {
Card card = new Card();
card.f();
}
}
class Tag {
Tag(int num) {
System.out.println(“Tag” + num);
}
}
class Card {
Tag tag1 = new Tag(1); //定义tag1变量
Card() {
System.out.println(“Card()”);
tag3 = new Tag(33); //tag3重新初始化了
}
Tag tag2 = new Tag(2); //定义tag2变量
void f() {
System.out.println(“f()”);
}
Tag tag3 = new Tag(3); //定义tag3变量
}
在main方法里面创建了一个card对象的,编译器在编译Card类时,成员变量tag1、tag2、tag3的初始化工作是在构造器Card()之前,因此,上述代码输出结果为:
Tag1
Tag2
Tag3
Card()
Tag33
f()
static变量的初始化顺序:static成员变量优先于非static成员变量。
public class StaticInitialization {
public static void main(String[] args) {
System.out.println(“Creating new Cupboard() in main”);
new Cupboard();
System.out.println(“Creating new Cupboard() in main”);
new Cupboard();
t2.f2(1);
t3.f3(1);
}
static Table t2 = new Table();
static Cupboard t3 = new Cupboard();
}
class Bowl{
Bowl(int i){
System.out.println(“Bowl”+i);
}
void f(int i){
System.out.println(“f”+i);
}
}
class Table{
static Bowl b1 = new Bowl(1);
Table(){
System.out.println(“Table()”);
b2.f(1);
}
void f2(int i){
System.out.println(“f2(“+i+”)”);
}
static Bowl b2 = new Bowl(2);
}
class Cupboard{
Bowl b3 = new Bowl(3);
static Bowl b4 = new Bowl(4);
Cupboard(){
System.out.println(“Cupboard()”);
b4.f(2);
}
void f3(int i){
System.out.println(“f3(“+i+”)”);
}
static Bowl b5 = new Bowl(5);
}
因为static仅在Class对象首次创建的时候初始化仅发生一次,所以,上面代码执行结果为:
Bowl1
Bowl2
Table()
f1
Bowl4
Bowl5
Bowl3
Cupboard()
f2
Creating new Cupboard() in main
Bowl3
Cupboard()
f2
Creating new Cupboard() in main
Bowl3
Cupboard()
f2
f2(1)
f3(1)
还有以下静态块里初始化方式也是:
class Cup{
Cup(int i){
System.out.println(“Cup(“+i+”)”);
}
void f(int i){
System.out.println(“f(“+i+”)”);
}
}
class Cups{
static Cup c1;
static Cup c2;
static { //静态块初始化
c1 = new Cup(1);
c2 = new Cup(2);
}
Cups(){
System.out.println(“Cups()”);
}
}
public class StaticInitialization {
public static void main(String[] args) {
System.out.println(“Inside main()”);
Cups.c1.f(99);
}
static Cups x = new Cups();
static Cups y = new Cups();
}
执行结果:
Cup(1)
Cup(2)
Cups()
Cups()
Inside main()
f(99)
另外一种,非静态实例初始化,没有static关键字,:
package com.extendstest;
class Mug{
Mug(int i){
System.out.println(“Mug(“+i+”)”);
}
void f(int i ){
System.out.println(“f(“+i+”)”);
}
}
public class Mugs {
Mug c1;
Mug c2;
{ //非静态初始化,创建对象时会多次调用
c1 = new Mug(1);
c2 = new Mug(2);
System.out.println(“c1&&c2inin….”);
}
Mugs(){
System.out.println(“Mugs()”);
}
public static void main(String[] args) {
System.out.println(“inin..main”);
Mugs x = new Mugs();
Mugs y = new Mugs();
}
}
执行结果:
inin..main
Mug(1)
Mug(2)
c1&&c2inin….
Mugs()
Mug(1)
Mug(2)
c1&&c2inin….
Mugs()