`
i学霸
  • 浏览: 12685 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

I学霸官方免费教程十:Java基础之关键字static和this

 
阅读更多

关键字static

static:静态的,用于修饰类的成员;
被static修饰的成员,在字节码文件(.class文件)被类加载器(Classloader)从硬盘加载到内存中时,就被在内存中创建。没有被static修饰的成员在使用关键字new创建对象后才被创建
被static修饰的成员,一个类只有一份,不属于某个对象,而且会常驻内存;
例如:地球属于全人类,而不属于某一个人。
静态属性的调用:类名.属性名;
静态方法的调用:类名.方法名();
静态块语法格式:static{ //代码 };class文件被加载的时候执行一次
在静态方法或静态块中直接调用类的属性,这个属性也必须是静态的
当静态的属性和静态块或静态方法在一个类中时,可以直接使用属性名来访问属性
实例:
/**
 * 演示关键字static的使用
 * @author 学霸联盟 - 赵灿
 */
public class StaticDemo {
	// 声明一个静态的属性name,并赋值为“张三”
	static String name = "张三";
	// 声明一个非静态的属性age,并赋值为1
	int age = 18;

	// 声明一个静态方法
	static void staticMethod1(){
		System.out.println("静态方法staticMethod1");
		/*
		 * 这里可以直接使用静态成员name和staticMethod2
		 * 但是想要使用非静态成员age、method1和method2
		 * 就必须创建对象,再使用对象调用非静态的成员
		 */
		staticMethod2();
		System.out.println("静态的属性name:" + name);
	}
	// 声明一个静态方法
	static void staticMethod2(){
		//这里可以直接调用静态成员
		System.out.println("静态方法staticMethod2");
	}
	// 声明一个非静态方法
	void method1(){
		System.out.println("非静态方法method1");
		//这里可以直接使用静态成员和非静态成员
		method2();
		// 普通属性必须使用对象调用
		System.out.println("非静态的属性age:" + age);
	}
	// 声明一个非静态方法
	void method2(){
		System.out.println("非静态方法method2");
	}
	/*
	 * main方法是静态方法
	 * 静态方法中可以直接使用本类静态成员,也可以通过类名调用静态成员
	 * 但使用非静态成员时,无论是本来还是其他类,都要先创建对象
	 * 再通过对象去调用非静态的成员
	 */
	public static void main(String[] args) {
		// 静态的成员可以直接使用类名.成员的方式调用,无需创建对象再调用
		StaticDemo.staticMethod1();
		// 创建一个Person类的对象p
		StaticDemo sd = new StaticDemo();
		sd.method1();
	}
}
运行结果:
静态方法staticMethod1
静态方法staticMethod2
静态的属性name:张三
非静态方法method1
非静态方法method2
非静态的属性age:18
实例:
/**
 * 演示普通代码块和静态代码块
 * @author 学霸联盟 - 赵灿
 */
public class CodeBlockDemo {
	static int si = 1;
	int i = 1;
	//静态块:只会再该类的class文件被加载时执行一次
	static{
		//静态块中可以直接使用静态成员,但不能直接使用非静态成员
		System.out.println("静态块被执行");
	}
	//非静态代码块:创建一个对象,就会被执行一次
	{
		//非静态块中可以直接使用静态成员,也可以直接使用非静态成员
		System.out.println("普通代码块被执行");
	}
	public static void main(String[] args) {
		//在main方法开始之前,静态块就已经执行
		System.out.println("----- main方法开始 -----");
		//未创建当前类的对象之前,就执行了静态块
		System.out.println("si = " + si);

		//普通代码块,创建对象时被执行
		System.out.println("----- 创建对象开始 -----");
		/*
		 * 创建一个对象时
		 */
		CodeBlockDemo cbd1 = new CodeBlockDemo();
		//输出结果:cbd1.si = 1 , cbd1.i = 1
		System.out.println("cbd1.si = " + cbd1.si + " , cbd1.i = " + cbd1.i);

		//对静态属性si和非静态属性i都进行修改
		cbd1.si = 10;
		cbd1.i = 10;
		System.out.println("----- 再次创建对象开始 -----");
		CodeBlockDemo cbd2 = new CodeBlockDemo();
		//输出结果:cbd1.si = 10 , i = 10
		System.out.println("cbd1.si = " + cbd1.si + " , i = " + cbd1.i);
		//输出结果:cbd2.si = 10 , i = 1
		System.out.println("cbd2.si = " + cbd2.si + " , i = " + cbd2.i);
	}
}
运行结果:
静态块被执行
----- main方法开始 -----
si = 1
----- 创建对象开始 -----
普通代码块被执行
cbd1.si = 1 , cbd1.i = 1
----- 再次创建对象开始 -----
普通代码块被执行
cbd1.si = 10 , i = 10
cbd2.si = 10 , i = 1
由结果可以看出,静态的属性si一个类只有一份,两个对象cdb1和cdb2共同拥有这一份,任何一个对象对静态的属性进行修改,其他对象访问时也会随之改变。而非静态的属性i,则是每个对象各有一份,所以修改某一个对象的非静态属性,其他对象不会随之改变

关键字this

一个指向自身的引用(变量),他在哪个对象中,他的值就是哪个对象的地址。
实例:
/**
 * 演示关键字this的使用
 * @author 学霸联盟 - 赵灿
 */
public class ThisDemo {
	// 声明一个变量a并赋值为123
	public int a = 123;
	/*
	 * 声明一个变量b并赋值为变量a的值,所以变量b的值也是123
	 * 创建一个对象执行一次
	 */
	public int b = this.a;

	// 声明一个没有返回值,没有参数的方法print
	public void print() {
		// 声明一个局部变量a,局部变量和成员变量可以重名
		int a = 456;
		// 变量a前没用关键字this,代表使用的是局部变量a;输出的值是456
		System.out.println(a);
		// 变量a前使用了关键字this,代表使用的是成员变量a;输出的值是123
		System.out.println(this.a);
		// 由于没有局部变量和成员变量b重名,所以前面的this可以省略
		System.out.println(b);
		System.out.println("this的地址:" + this);
	}

	//静态的main方法
	public static void main(String[] args) {
		// new语句执行完,其中的变量a和b都有了值是123
		ThisDemo td1 = new ThisDemo();
		// 给对象td1的属性a赋值为789
		td1.a = 789;
		// 调用对象td1的print方法,此时ThisDemo类中使用的this都和td1中存储的地址相同
		td1.print();
		System.out.println("td1的地址:" + td1);
		// 创建对象td2
		ThisDemo td2 = new ThisDemo();
		// 使用对象td2调用print方法,此时ThisDemo类中使用的this都和td2中存的地址相同
		td2.print();
		System.out.println("td2的地址:" + td2);
	}
}
输出结果:
456
789
123
this的地址:cls.keyword.ThisDemo@659e0bfd
td1的地址:cls.keyword.ThisDemo@659e0bfd
456
123
123
this的地址:cls.keyword.ThisDemo@2a139a55
td2的地址:cls.keyword.ThisDemo@2a139a55

小结:

1、不能用在static修饰的成员中,因为this代表的是对象的引用
2、如果在非静态的方法或非静态的代码块中,没有局部变量和属性(成员变量)重名,this可以省略;否则,必须使用 this.属性的方式来访问类的属性
3、调用本类的其他构造方法:this( [参数列表] )
使用关键字this调用构造方法时,只能在构造方法中调用,而且调用时必须写在构造方法中的第一行;构造方法不能自己调用自己,不能相互调用

版权声明:本文为博主原创文章,未经博主允许不得转载。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics