您的位置:首页 > 编程语言 > Java开发

【java】this()与super()使用详解

2015-07-26 15:48 706 查看

1.this关键字







对于上述需要注意的地方:
1.不是重载即在构造器中调用构造器可以直接调用其方法,无需this。在需要明确的地方使用即可

2.疑惑点

this关键字对于将当前对象传递给其他的方法也很有用,这一点自己现在也不是很熟练



2.在构造器中调用构造器



package test;

public class Test {
int petalCount = 0;
String s = "initial value";
Test(int petals) {
petalCount = petals;
System.out.println("Constructor w/ int arg only, petalCount= "
+ petalCount);
}
Test(String ss) {
s = ss;
System.out.println("Constructor w/ String arg only, s = " + s);
//	    s=ss;  要是将上面的语句放到下面,这输出s的值就是initial  value;
}
Test(String s, int petals) {
//	    this(petals);// Can't call two!
this(s);
//	    上面语句是调用另外一个构造器,下面是将由于参数s的名称和数据成员s的名字相同,所以会产生歧义
//	    因此使用this.s来代表数据成员就能解决这个问题
this.s = s; // Another use of "this"
System.out.println("String & int args");
}
Test() {
this("hi", 47);
System.out.println("default constructor (no args)");
}
void printPetalCount() {
//! this(11); // Not inside non-constructor!
System.out.println("petalCount = " + petalCount + " s = "+ s);
}
public static void main(String[] args) {
Test x = new Test();
x.printPetalCount();
}
}



例子:

package test;

public class Test {

private int i=0;

//第一个构造器:有一个int型形参

Test(int i){

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

this.i=i+1;//此时this表示引用成员变量i,而非函数参数i

//下面的i表示形参i,this.i表示数据成员
System.out.println("Int constructor i——this.i:  "+i+"  ——  "+this.i);

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

System.out.println("  i-1:  "+(i-1)+"  this.i+1:  "+(this.i+1));

//从两个输出结果充分证明了i和this.i是不一样的!

}

//  第二个构造器:有一个String型形参

Test(String s){

//    	重新调用新的构造器之后,数据成员的值不再受到上一个的影响
//    	难道是因为每个构造器都有自己独立内存空间吗?
System.out.println("2i:"+this.i);

System.out.println("String constructor:  "+s);

}

//  第三个构造器:有一个int型形参和一个String型形参

Test(int i,String s){

this(s);//this调用第二个构造器

/*this(i);*/

/*此处不能用,因为其他任何方法都不能调用构造器,只有构造方法能调用他。

但是必须注意:就算是构造方法调用构造器,也必须为于其第一行,构造方法也只能调

用一个且仅一次构造器! http://blog.sina.com.cn/s/blog_8612e75d0100ze1m.html */

System.out.println("3i:"+this.i);

this.i=i++;//this以引用该类的成员变量

System.out.println("Int constructor:  "+i+"\n"+"String constructor:  "+s);

}

/*    Test(int i ,String s,double a){

this(i);
System.out.println("5i:"+this.i);
}*/

public Test increment(){

System.out.println("4i:"+this.i);
this.i++;
return this;//返回的是当前的对象,该对象属于(Test)

}

public static void main(String[] args){

Test tt0=new Test(10);

Test tt1=new Test("ok");

Test tt2=new Test(20,"ok again!");

/* Test tt3=new Test(15, "okhushid", 0.12345);*/

//由于increment()通过this关键字返回了当前对象的引用,所以很容易在一条语句里面对同一个对象执行多次操作
System.out.println(tt0.increment().increment().increment().i);
//       输出的是this.i,就相当于输出其数据成员
System.out.println(tt0.increment().increment().increment());
//       输出的是test.Test@2b0a141e,这是什么?这是java中的内存地址吗?

//http://www.cnblogs.com/java-class/archive/2012/12/19/2825463.html

}

}


关于this()与super()共用的问题:

package test;

class TestA {
public TestA() {
System.out.println("A");
}
}

class TestB extends TestA {
public TestB(int i) {
super();
// this();

}

public TestB() {
this(3);
System.out.println("B");
}
}

public class Test {
public static void main(String[] ars) {
new TestB(1);
new TestB();
}
}


super()和this ()不能共存,否则编译时会报异常。

Constructor call must be the first statement in a constructor

换句话说就是super()和this ()都必须在构造方法的第一行。

this(有参数/无参数) 用于调用本类相应的构造函数

super(有参数/无参数) 用于调用父类相应的构造函数

而且在构造函数中,调用必须写在构造函数定义的第一行,不能在构造函数的后面使用。

一个构造函数定义中不能同时包括this调用和super调用,如果想同时包括的话,可以在一每构造器中使用一个。

补充:

用类名定义一个变量的时候,定义的应该只是一个引用,外面可以通过这个引用来访问这个类里面的属性和方法,那们类里面是够也应该有一个引用来访问自己的属性和方法纳?JAVA提供了一个很好的东西,就是 this 对象,它可以在类里面来引用这个类的属性和方法。

public class ThisDemo {
String name="Mick";
public void print(String name){
System.out.println("类中的属性 name="+this.name);
System.out.println("局部传参的属性="+name);
}
public static void main(String[] args) {
ThisDemo tt=new ThisDemo();
tt.print("Orson");
}
}


自我问题:
http://bbs.csdn.net/topics/391819324?page=1#post-400326846
第一个问题:每次重新调用一个新的构造器之后,this.i的数据都会恢复到原来了0;上一个构造器的this.i的结果没有保存,难道在java中每个构造器都有自己的内存空间地址吗?

第二个问题: System.out.println(tt0.increment().increment().increment());

// 输出的是test.Test@2b0a141e,这是什么?这是java中的内存地址吗?

第一个问题:

构造器(构造函数,Constructor)是一种特殊的函数,它是用来初始化一个“刚刚建立”的对象的方法。不同的构造器重载用于以不同的方式初始化这个对象(其中的逻辑是由编程人员自由控制的)。对于同一个类内的构造器,对于每个对象只能被调用一次,且是由new方法发起调用,可以使用super(调用父类的构造方法)和this(调用本类的构造方法)在不同构造器方法之间跳转,但是每个构造方法最多被调用一遍,同一个类内的构造方法最多有一个是实质上执行的(如果递归,编译器会报错)。this是对当前对象的引用,每次构造器调用时都是作用于一个全新的对象,故每次调用时其类中数据成员的值(那个i是成员变量,在每个对象中有独立的存储空间)一定是未初始化的默认值。

static:只有静态成员变量才是整个类共用的。对于非静态成员变量每个对象保存一个独立的值(当然占用的就是对象的空间)。

第二个问题:

当没有重写toString方法时,默认会使用Object类提供的toString方法,其规则是:类全名@类对象的hashcode方法返回值。当没有重写hashCode方法时,默认使用Object类的hashCode方法,它是java对一个对象的标识号,可能由不同机制生成,不一定是内存地址,但是可能与之相关(通常实现采用的是将地址转换为int值的方法)。

要搞清楚成员变量和局部变量

Test(int i){ },这个构造器中形参 i 是一个局部变量,作用域是这个构造器的大括号,意思是 声明一个局部变量i,是这个构造器的形参,其值为传入的实参的值,在这个构造器中的i 是指的这个局部变量。

在类中也声明了一个成员变量i,在构造器中也能调用这个变量,但是名字都一样,为了区分应this.i表示这个成员变量,这里的this是指本类的属性

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: