java 显式初始化_Java基础(二)--this关键字及初始化

构造器:

构造器的名称必须和类名完全相同,所以一般方法的"首字母小写"命名规则并不适合构造器

默认构造器:

也叫无参构造器,作用就是创建一个默认对象,如果你不是手写出来,编译器默认会创建

有参构造器:

也就有拥有参数的构造器,一旦写了有参构造器,编译器不会创建默认构造器。可以写多个构造器,也就是方法的重载

区分重载:

参数,不能通过返回值区分

this关键字:

public classTest1 {private void add(inti) {

}public static voidmain(String[] args) {

Test1 a= newTest1();

Test1 b= newTest1();

a.add(1);

b.add(2);

}

}

对象a,b都调用了add(),为了区分,编译器把这个对象的引用作为第一个参数传递给add(),就变成了

Test1.add(a, 1)

这是内部的表现形式,你并不能直接这样写,无法通过编译

this关键字只能在方法内部使用,可以用来获取当前对象(调用当前方法的对象)的引用,所以可以把this理解为一般的对象引用,当前方法

的this会自动应用同一个类的其他方法,所以在一个方法中调用另一个方法不需要使用this,直接调用就可以,可以用,但没必要。

1、通常可以返回当前对象的引用

public classTest {int i = 0;

Test increment(){

i++;return this;

}

}

2、可以将当前对象传递给其他方法

public classTest1 {public staticTest add(Test test) {returntest;

}

}public classTest {

Test add() {return Test1.add(this);

}

}

3、构造器互相调用

在jdk源码中和日常开发中很常见,例如:

public class ThreadPoolExecutor extendsAbstractExecutorService {public ThreadPoolExecutor(int var1, int var2, long var3, TimeUnit var5, BlockingQueuevar6) {this(var1, var2, var3, var5, var6, Executors.defaultThreadFactory(), defaultHandler);

}public ThreadPoolExecutor(int var1, int var2, long var3, TimeUnit var5, BlockingQueuevar6, ThreadFactory var7) {this(var1, var2, var3, var5, var6, var7, defaultHandler);

}public ThreadPoolExecutor(int var1, int var2, long var3, TimeUnit var5, BlockingQueuevar6, RejectedExecutionHandler var7) {this(var1, var2, var3, var5, var6, Executors.defaultThreadFactory(), var7);

}public ThreadPoolExecutor(int var1, int var2, long var3, TimeUnit var5, BlockingQueuevar6, ThreadFactory var7, RejectedExecutionHandler var8) {this.ctl = new AtomicInteger(ctlOf(-536870912, 0));this.mainLock = newReentrantLock();this.workers = newHashSet();this.termination = this.mainLock.newCondition();if (var1 >= 0 && var2 > 0 && var2 >= var1 && var3 >= 0L) {if (var6 != null && var7 != null && var8 != null) {this.corePoolSize =var1;this.maximumPoolSize =var2;this.workQueue =var6;this.keepAliveTime =var5.toNanos(var3);this.threadFactory =var7;this.handler =var8;

}else{throw newNullPointerException();

}

}else{throw newIllegalArgumentException();

}

}

}

PS:this只能调用一个构造器,不能写多个,而且要放在方法第一行,和super很像

4、区分参数和成员变量的名称

public Test(inti, String s) {this.i =i;this.s =s;

}

static method只能调用static,反过来倒是可以。this属于对象的,所以不能在static使用

构造器初始化:

变量定义的先后顺序决定了初始化顺序。即使随便分布,还是在构造方法之前调用

public classTest1 {public Test1(inti) {

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

}

}public classTest {

Test1 test1= new Test1(1);

Test() {

System.out.println("Test");

test3= new Test1(4);

}

Test1 test2= new Test1(2);voidadd() {

System.out.println("add");

}

Test1 test3= new Test1(3);public static voidmain(String[] args) {

Test test= newTest();

test.add();

}

}

结果:

Test1: 1Test1:2Test1:3Test

Test1:4add

静态数据初始化:

无论创建多少对象,和静态数据没关系,始终只占用一份存储空间

public classBowl {

Bowl(intmarker) {

System.out.println("Bowl: " +marker);

}void fl(intmarker) {

System.out.println("fl: " +marker);

}

}

public classTable {static Bowl bowl1 = new Bowl(1);

Table() {

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

bowl2.fl(2);

}void f2(intmarker) {

System.out.println("f2: " +marker);

}static Bowl bowl2 = new Bowl(2);

}

public classCupboard {

Bowl bowl3= new Bowl(3);static Bowl bowl4 = new Bowl(4);

Cupboard() {

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

bowl4.fl(3);

}void f3(intmarker) {

System.out.println("f3: " +marker);

}static Bowl bowl5 = new Bowl(5);

}

public classTest {public static voidmain(String[] args) {

System.out.println("Create new Cupboard() in main");newCupboard();

System.out.println("Create new Cupboard() in main");newCupboard();

table.f2(1);

cupboard.f3(1);

}static Table table = newTable();static Cupboard cupboard = newCupboard();

}

结果:

Bowl: 1Bowl:2Table()

fl:2Bowl:4Bowl:5Bowl:3Cupboard()

fl:3CreatenewCupboard() in main

Bowl:3Cupboard()

fl:3CreatenewCupboard() in main

Bowl:3Cupboard()

fl:3f2:1f3:1

初始化的顺序:

1、父类的静态变量赋值

2、自身的静态变量赋值

3、父类成员变量赋值和父类块赋值

4、父类构造函数赋值

5、自身成员变量赋值和自身块赋值

6、自身构造函数赋值

PS:

1、静态变量只有在第一次对象被创建(第一次访问静态数据)的时候,才会被初始化,而且只有这一次

2、构造器是静态方法,即使没有显式地使用static关键字

显式的静态初始化:

public classCup {

Cup(intmarker) {

System.out.println("Cup: " +marker);

}void f(intmarker) {

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

}

}

public classCups {staticCup cup1;staticCup cup2;static{

cup1= new Cup(1);

cup2= new Cup(2);

}

Cups() {

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

}

}

public static voidmain(String[] args) {

System.out.println("Inside main()");

Cups.cup1.f(99);

}

static Cups cups1 = new Cups();

结果:

Cup: 1Cup:2Cups()

Inside main()

f:99

PS:再一次证明,静态初始化只会执行一次

public classStaticTest {public static voidmain(String[] args)

{

staticFunction();

}static StaticTest st = newStaticTest();static{

System.out.println("1");

}

{

System.out.println("2");

}

StaticTest()

{

System.out.println("3");

System.out.println("a="+a+",b="+b);

}public static voidstaticFunction(){

System.out.println("4");

}int a=110;static int b =112;

}

结果:

2

3a=110,b=0

1

4

结果有点出人意料:实例初始化竟然在类初始化前面

类加载过程:

1、准备:

为类变量分配内存并设置默认值,因此类变量st为null、b为0。

PS:

如果这里b被final修饰,编译时javac将会为value生成ConstantValue属性,在准备阶段虚拟机就会根据ConstantValue的设置将变量设置为

指定的值。

例如:

static final int b=112,那么在准备阶段b的值就是112,而不再是0了。

初始化:

就是执行类构造器,类构造器是编译器收集所有静态语句块和类变量的赋值语句,此时会执行:static StaticTest st = new StaticTest();

冷知识点:

嵌套初始化时有一个特别的逻辑。内嵌的这个变量恰好是个静态成员,而且是本类的实例。

就会导致:"实例初始化竟然出现在静态初始化之前"。

我们在前面已经试验过,如果static StaticTest st = new StaticTest()中StaticTest不是本类,就不会产生这个现象的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值