博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java基础(二)--this关键字及初始化
阅读量:5020 次
发布时间:2019-06-12

本文共 6334 字,大约阅读时间需要 21 分钟。

构造器:

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

默认构造器:

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

有参构造器:

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

区分重载:

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

this关键字:

public class Test1 {    private void add(int i) {    }    public static void main(String[] args) {        Test1 a = new Test1();        Test1 b = new Test1();        a.add(1);        b.add(2);    }}

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

Test1.add(a, 1)

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

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

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

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

public class Test {    int i = 0;    Test increment(){        i++;        return this;    }}

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

public class Test1 {    public static Test add(Test test) {        return test;    }}public class Test {    Test add() {        return Test1.add(this);    }}

3、构造器互相调用

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

public class ThreadPoolExecutor extends AbstractExecutorService {       public ThreadPoolExecutor(int var1, int var2, long var3, TimeUnit var5, BlockingQueue
var6) { this(var1, var2, var3, var5, var6, Executors.defaultThreadFactory(), defaultHandler); } public ThreadPoolExecutor(int var1, int var2, long var3, TimeUnit var5, BlockingQueue
var6, ThreadFactory var7) { this(var1, var2, var3, var5, var6, var7, defaultHandler); } public ThreadPoolExecutor(int var1, int var2, long var3, TimeUnit var5, BlockingQueue
var6, RejectedExecutionHandler var7) { this(var1, var2, var3, var5, var6, Executors.defaultThreadFactory(), var7); } public ThreadPoolExecutor(int var1, int var2, long var3, TimeUnit var5, BlockingQueue
var6, ThreadFactory var7, RejectedExecutionHandler var8) { this.ctl = new AtomicInteger(ctlOf(-536870912, 0)); this.mainLock = new ReentrantLock(); this.workers = new HashSet(); 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 new NullPointerException(); } } else { throw new IllegalArgumentException(); } } }

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

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

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

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

构造器初始化:

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

public class Test1 {    public Test1(int i) {        System.out.println("Test1: " + i);    }}public class Test {    Test1 test1 = new Test1(1);    Test() {        System.out.println("Test");        test3 = new Test1(4);    }    Test1 test2 = new Test1(2);    void  add() {        System.out.println("add");    }    Test1 test3 = new Test1(3);    public static void main(String[] args) {        Test test = new Test();        test.add();    }}

 结果:

Test1: 1Test1: 2Test1: 3TestTest1: 4add

静态数据初始化:

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

public class Bowl {    Bowl(int marker) {        System.out.println("Bowl: " + marker);    }    void fl(int marker) {        System.out.println("fl: " + marker);    }}
public class Table {    static Bowl bowl1 = new Bowl(1);    Table() {        System.out.println("Table()");        bowl2.fl(2);    }    void f2(int marker) {        System.out.println("f2: " + marker);    }    static Bowl bowl2 = new Bowl(2);}
public class Cupboard {    Bowl bowl3 = new Bowl(3);    static Bowl bowl4 = new Bowl(4);    Cupboard() {        System.out.println("Cupboard()");        bowl4.fl(3);    }    void f3(int marker) {        System.out.println("f3: " + marker);    }    static Bowl bowl5 = new Bowl(5);}
public class Test {    public static void main(String[] args) {        System.out.println("Create new Cupboard() in main");        new Cupboard();        System.out.println("Create new Cupboard() in main");        new Cupboard();        table.f2(1);        cupboard.f3(1);    }    static Table table = new Table();    static Cupboard cupboard = new Cupboard();}

结果:

Bowl: 1Bowl: 2Table()fl: 2Bowl: 4Bowl: 5Bowl: 3Cupboard()fl: 3Create new Cupboard() in mainBowl: 3Cupboard()fl: 3Create new Cupboard() in mainBowl: 3Cupboard()fl: 3f2: 1f3: 1

初始化的顺序: 

  1、父类的静态变量赋值

  2、自身的静态变量赋值

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

  4、父类构造函数赋值

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

  6、自身构造函数赋值

PS:

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

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

显式的静态初始化:

public class Cup {    Cup(int marker) {        System.out.println("Cup: " + marker);    }    void f(int marker) {        System.out.println("f: " + marker);    }}
public class Cups {    static Cup cup1;    static Cup cup2;    static {        cup1 = new Cup(1);        cup2 = new Cup(2);    }    Cups() {        System.out.println("Cups()");    }}
public static void main(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 class StaticTest {    public static void main(String[] args)    {        staticFunction();    }    static StaticTest st = new StaticTest();    static    {        System.out.println("1");    }    {        System.out.println("2");    }    StaticTest()    {        System.out.println("3");        System.out.println("a="+a+",b="+b);    }    public static void staticFunction(){        System.out.println("4");    }    int a=110;    static int b =112;}

结果:

23a=110,b=014

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

类加载过程:

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不是本类,就不会产生这个现象的

转载于:https://www.cnblogs.com/huigelaile/p/10998798.html

你可能感兴趣的文章
ubuntu 11.04下android开发环境的搭建!
查看>>
Bzoj 3343: 教主的魔法
查看>>
括号序列(栈)
查看>>
一件趣事
查看>>
DevExpress控件TExtLookupComboBox实现多列模糊匹配输入的方法
查看>>
【动态规划】洛谷-过河卒
查看>>
linux环境下mysql 5.7.1X 如何重置root密码
查看>>
hdu 1007 Quoit Design(最近点对模板)
查看>>
php中strlen和mb_strlen的区别
查看>>
数据库【mongodb篇】练习操作
查看>>
第十二周学习进度
查看>>
淘宝网6个质量属性的场景分析:
查看>>
PJzhang:kali linux安装网易云音乐、Visual Studio Code、skype
查看>>
CentOS7下JSP连接Mysql
查看>>
文件包含
查看>>
Android 更新升级下载 自定义Updates 兼容版
查看>>
[osg]osg背景图设置
查看>>
使用vs2013打开vs2015项目
查看>>
Java中手动提交事务
查看>>
第一次提交 nacos 代码
查看>>