[2014-02-27]JAVA笔记_Static关键字、代码块{}、main()、final关键字

Static关键字:可以用于修饰属性,也可以用于修饰方法,还可以用于修饰类。

Static修饰属性:无论一个类生产多少个对象,所有这些对象共同使用唯一一份静态的成员变量;一个对象对该成员变量进行了修改,其他对象的该静态成员变量的值也会随之发生变化。如果一个成员变量是static的,那么我们通过类名.成员变量名的方式来使用它(推荐使用这种方式)。

public class StaticTest{
	public static void main(String args[]){

		/*
		MyStatic myStatic = new MyStatic();
		MyStatic myStatic2 = new MyStatic();
		myStatic.a = 10;
		System.out.println(myStatic2.a);
		*/
		
		//使用类名访问成员变量
		MyStatic.a = 10;
		System.out.println(MyStatic.a);
	
	}
}

class MyStatic{
	static int a;
}

在程序中使用static声明属性,则此属性称为全局属性(或成为静态属性).

例1:使用static声明属性

class Person{
	String name;
	int age;
	static String country = "A城";			//使用static申明类属性
	public Person(String name, int age){
		this.name = name;
		this.age = age;
	}
	public void info(){
		System.out.println("姓名:" + this.name + " 年龄:"
		+ this.age + " 城市:" + this.country);
	}
};
public class StaticDemo02{
	public static void main(String args[]){
		Person p1 = new Person("张三", 30);
		Person p2 = new Person("李四", 30);
		Person p3 = new Person("王五", 30);
		System.out.println("------------修改之前---------");
		p1.info();
		p2.info();
		p3.info();
		System.out.println("------------修改之前---------");
		Person.country = "B城";			//直接修改static属性
		p1.info();
		p2.info();
		p3.info();
		fun();
	}
	public static void fun(){
		System.out.println("静态方法无法调用非静态方法,必须有static关键字");
	};
}



static修饰方法:static 修饰的方法叫做静态方法。对于静态方法来说,可以使用类名.方法名 的方式来访问。

public class StaticTest2{
	public static void main(String args[]){
	
		//MyStatic2 test = new MyStatic2();
		//test.output();
		
		MyStatic2.output();
	}
}

class MyStatic2{
	public static void output(){
		System.out.println("output");
	}
}


·静态方法只能继承,不能重写(override)。
//静态方法的继承
public class StaticTest3{
	public static void main(String args[]){
		M m = new N();	//结果取决于调用着的类型
		//M m = new M();
		m.output();
	}
}

class M{
	public static void output(){
		System.out.println("M");
	}
}

class N extends M{
	public static void output(){
		System.out.println("N");
	}
}
//N类中的方法继承了M中的方法。并隐藏了M中的方法
参考文献:http://docs.oracle.com/javase/tutorial/java/IandI/override.html


例2:使用static声明方法。使用static声明的方法有时也成为类方法

class Person{
	private String name;
	private int age;
	static String country = "A城";			//使用static申明类属性
	public Person(String name, int age){
		this.name = name;
		this.age = age;
	}
	public void info(){
		System.out.println("姓名:" + this.name + " 年龄:"
		+ this.age + " 城市:" + this.country);
	}
	public static void setCountry(String c){	//使用static申明方法
		country = c;			//修改static属性
	}
	public static String getCountry(){
		return country;
	}
};
public class StaticDemo03{
	public static void main(String args[]){
		Person p1 = new Person("张三", 30);
		Person p2 = new Person("李四", 30);
		Person p3 = new Person("王五", 30);
		System.out.println("------------修改之前---------");
		p1.info();
		p2.info();
		p3.info();
		System.out.println("------------修改之前---------");
		Person.setCountry("B城");		//因为是使用static声明的方法,所以也可称为类方法
		p1.info();
		p2.info();
		p3.info();
	}
}

总结: 

        1. static声明的方法是不能调用非static类型声明的属性或方法(因为static得方法在装载class得时候首先完成,比 构造方法早,此时非static得属性和方法还没有完成初始化。。。所以不能调用)。但是非static声明的方法可以去调用static调用的属性或方法。

        2. 使用 static 声明的属性或方法可以直接由类名称调用。

        3. 只能访问 static 声明的属性或方法,而非 static 声明的属性和方法是不能访问,因为 static 可以在对象没有实例化时就直接调用,而其他的属性或方法必须在对象实例化之后才可以调用。


final关键字:final可以修饰 类、 方法、属性。

final修饰类:当一个类被 final 所修饰时,表示该类是一个终态类,即不能被继承。

public class FinalTest{
	public static void main(String args[]){
		
	}
}

final class E{	//该类不能被继承

}

class F extends E{

}

final修饰方法:当一个方法被 final 所修饰时,表示改方法时一个终态方法,即不能被重写(override)。

public class FinalTest2{
	public static void main(String args[]){
	
		H h = new H();
		h.output();
	}
}

class G{

	public final void output(){
	
		System.out.println("G");
	}
}

class H extends G{
	public  void output(){
		System.out.println("H");
	}
	
}

final 修饰属性:当一个属性被final 所修饰时,表示该属性不能被改写。

public class FinalTest3{
	public static void main(String args[]){
	
		People people = new People();
		people.age = 20;
	}
}

class People{
	final int age = 10;
}

//使用final修饰地址:
public class FinalTest3{
	public static void main(String args[]){
	
		People people = new People();
		
		//people.address = new Address();		//Error,将新的地址赋值给address引用

		people.address.name = "shanghai";	//修改的是address所指向的地址的内容
	}
}

class People{
	final Address address = new Address();	//将引用类型声明为final,意思是new出来的地址是不能改变的
}

class Address{
	String name = "bejing";
}
总结:当final 修饰一个原生数据类型时,表示该原生数据类型的值不能发生变化(比如说不能从8变为20);如果final修饰的是一个引用数据类型时,表示该引用类型不能再指向其他对象了,但该引用所指向的对象的内容是可以发生变化的。

//final 陷阱
public class FinalTest4{
	final int a;	//必须显示的给变量赋值,否则报错。或者通过构造方法赋初值
	public FinalTest4(){
		a = 0;
	}

	public FinalTest4(int a){	//Error,因为有2个构造方法,调用时不知道会先调用哪个构造方法
		//this.a = a;<span style="white-space:pre">		</span>//或者这样也可以
	}
}

final陷阱:对于final 类型成员变量,一般来说有两种赋初值方式:

                           a) 在声明 final 类型成员变量时就赋上初值
                           b) 在声明 final 类型成员变量时不赋初值,但在类的所有构造方法中都为其赋上初值


·static 代码块: 静态代码块。静态代码块的作用也是完成一些初始化的工作。首先执行静态代码块,然后执行构造方法。静态代码块在类被加载的时候执行,而构造方法是在生成对象的时候执行;要想调用某个类生成对象,首先需要将类加载到 java 虚拟机上(JVM),然后由JVM 加载这个类生产对象。

//静态代码块
public class StaticTest4{
	public static void main(String args[]){
		/*
		P p = new P();
		P p2 = new P();	//static只执行一次,因为class只需要加载一次到JVM,然后每次new的时候执行构造方法。
		*/
		new S();	//因为静态代码块在加载到JVM的时候就执行了,所以先执行3个static方法,然后在依次查找子类上面的父类构造方法,从父类到一类依次执行。
		new S();
	}
}

class P{

	static{
		System.out.println("P static block");	//当将class文件加载到JVM时执行
	}

	public P(){
		System.out.println("P constructor");	//当 new 这个类生产对象的时候执行
	}
}

class Q extends P{
	static{
		System.out.println("Q static block");
	}
	public Q(){
		System.out.println("Q constructor");
	}
}
class S extends Q{
	static{
		System.out.println("S static block");
	}
	public S(){
		System.out.println("S constructor");
	}
}
 ·类的静态代码块只会执行一次,是在类被加载的时候执行的,因为每个类只会被加载一次,所以静态代码块也只会被执行一次;而构造方法则不然,每次生成一个对象的时候都会调用类的构造方法,所以 new 一次就会调用构造方法一次。
 ·如果继承体系中既有构造方法,又有静态代码块,那么首先执行最顶层的类的静态代码块,一直执行到最底层的静态代码块,然后在去执行最顶层类的构造方法,一直执行到最底层类的构造方法。 注意:静态代码块只会执行一次。

//静态方法调用
public class StaticTest5{
	public static void main(String args[]){
		W w = new W();
		w.change();	
	}
}

class W{
	static int a = 10;

	int a = 10;	//不能在一个静态方法里面访问一个非静态的成员变量

	public static void change(){
	//public void change(){	//可以因为a的值只有一份是全局的
		a++;
                this.a++;<span style="white-space:pre">	</span>//Error:this表示当前对象的引用。如果直接使用类名调用静态方法的时候,就不存在对象,也就不知道this是什么了
	}
}
//因为每次new一个对象的时候都会有自己的一份a的值,所以在静态方法不知道是修改了哪个a的值。
·不能在静态方法中访问非静态成员变量;可以在静态方法中访问静态的成员变量。可以在非静态方法中访问静态的成员变量。
总结:静态的只能访问静态的;非静态的可以访问一切。

·不能在静态方法中使用 this 关键字。


java中的内存区域:

· 栈内存:可以保存对象的名称

· 堆内存:保存每个对象的具体属性

· 全局数据区:保存 static 类型的属性

· 全局代码区:保存所有方法的定义



main方法:

· public: 表示此方法可以被外部所调用

· static: 表示此方法可以由类名直接调用(执行一个java程序的时候,使用的是 java 类名称)

· void: 主方法是程序的起点,所以不需要任何的返回值

· mian: 系统规定好的默认调用的方法名称,执行的时候,默认找到main方法名称

· String args[]: 表示的是运行时的参数

· 参数传递的形式: java 类名称 参数1 参数2 参数3...


代码块:

概念:代码块是指用{}括起来的一段代码,根据位置不同可以分为  普通代码块、构造快、静态代码块、同步代码块  4种。


class Demo{
	{					//定义构造快
		System.out.println("1、构造块。");
	}
	static{				//定义静态代码块
		System.out.println("0、静态代码块。");
	}
	{					//定义构造方法
		System.out.println("2、构造方法。");
	}

}
public class CodeDemo03{
	static{				//在主方法所在的类中定义静态块
		System.out.println("在主方法所在的类中定义静态块");
	}
	public static void main(String args[]){
		new Demo();
		new Demo();
		new Demo();
	}
}
//执行顺序:静态代码块优先于主方法执行,而在类中定义的静态代
//码块会优先于构造块执行,而且静态代码块只执行一次。



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值