【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是指本类的属性
相关文章推荐
- java中复制文本文件的方式我总结为14种(按字符读取4中,按字节读取8种!??)
- java中的同步与异步
- Java基础查漏补缺:(开篇)为什么要在即将找工作的时候还在看Java基础
- spring bean 生命周期
- Learn Gradle - CH 3 Java 快速入门
- 关于Java集合的总结
- 用枚举方法编写的星期几 并输出相应文字(Java)
- Java对象的equals方法分析与重写
- JAVA深入研究——Method的Invoke方法
- SPRING技术内幕-笔记(十二)spring驱动ibatis的设计与实现
- JavaWeb学习笔记:Servlet
- java Ip地址的获取 简单代码
- 冒泡,简单选择,直接插入排序比较(Java版)
- springmvc的restful服务理解
- 常见排序算法(java实现)
- JAVA集中中 List Set Map 区别和关系
- eclipse编辑器下显示文件路径
- 开源 自由 java CMS - FreeCMS1.8 网上申报
- Java Base64、AES、SHA1、MD5加密算法
- JAVA注解