static关键字


static是Java中定义的一个关键字,主要是描述全局的概念,所以利用static关键字可以定义属性和方法。但是在百分之九十的情况下,开发代码很少会直接编写static。

利用static定义属性

class Person{
	private String name;
	private int age;
	String country = "中华人民共和国";//此属性暂时不封装
	public Person(String name,int age){
		this.name=name;
		this.age=age;
	}
	public String getInfo(){
		return "姓名:"+this.name+",年龄:"+this.age+",国家:"+this.country;
	}
}	
public class Hello {
	public static void main(String args[]){
		Person perA = new Person("小胖",10);
		Person perB = new Person("小壮",20);
		Person perC = new Person("小不点",10);
		System.out.println(perA.getInfo());
		System.out.println(perB.getInfo());
		System.out.println(perC.getInfo());
	}
}

在这里插入图片描述
但是对于以上的程序的内存关系中就会发现问题。
在这里插入图片描述
如果时光倒退回唐朝,这个时候代码维护难度就比较大,造成这种问题的原因是类中的普通属性是每个对象都独自拥有的,所以这样的设计明显不符合当前的环境,所以最好的做法是将国家这个属性设置为公共属性,所有的对象都可以共享此属性,如果要实现这样的操作,就可以通过static关键字来进行定义。
范例:使用static关键字来定义

class Person{
	private String name;
	private int age;
	static String country = "中华人民共和国";//此属性暂时不封装
	public Person(String name,int age){
		this.name=name;
		this.age=age;
	}
	public String getInfo(){
		return "姓名:"+this.name+",年龄:"+this.age+",国家:"+this.country;
	}
}	
public class Hello {
	public static void main(String args[]){
		Person perA = new Person("小胖",10);
		Person perB = new Person("小壮",20);
		Person perC = new Person("小不点",10);
		perA.country="中国-唐朝";//修改了一个对象的属性
		System.out.println(perA.getInfo());
		System.out.println(perB.getInfo());
		System.out.println(perC.getInfo());
	}
}

在这里插入图片描述
通过执行结果可以发现,修改了一个对象的属性之后,所有对象对应的属性都发生了改变,所以这样的属性称为公共属性,公共属性必须通过static定义,而对于公共属性的内容保存不会在栈,也不会在堆,而是会存在于全局数据区之中,所有的方法保存在全局代码区之中。
在这里插入图片描述
既然static属于全局属性,那么由一个对象进行修改是否合适?很显然不合适,最好的做法就是利用类。所以对于static定义的属性可以由类名称直接进行调用,所以这样的属性也被称为类属性。

Person.country="中国-唐朝";//直接通过类来调用

在这里插入图片描述
此时类中存在有static属性以及非static属性,需要注意的是:

  • 所有非static属性都是在对象实例化的时候才会进行内存分配;
  • 所有的static属性在没有实例化对象产生的情况下直接使用。

范例:直接调用类属性

public class Hello {
	public static void main(String args[]){		
		System.out.println(Person.country);
		Person.country="北宋";
		System.out.println(Person.country);
	}
}

在这里插入图片描述

public class Hello {
	public static void main(String args[]){		
		System.out.println(Person.country);
		Person.country="北宋";
		System.out.println(Person.country);
		System.out.println(new Person("小机灵鬼",20).getInfo());
	}
}

在这里插入图片描述
虽然static的属性定义在类中,但是它是完全独立的,不受实例化对象的控制。
在百分之九十的情况下类的设计都会用static属性,只有在表示公共的属性或与类实例化无关的属性时才会考虑使用static。

利用static定义方法

利用static定义的属性可以直接通过类名称进行访问,但是static也可以用于方法的定义上,同样,该方法可以由类名称直接调用。
范例:定义static方法

class Person{
	private String name;
	private int age;
	private static String country = "中华人民共和国";//此属性暂时不封装
	public Person(String name,int age){
		this.name=name;
		this.age=age;
	}
	public static void setContry(String c){
		country=c;
	}
	public static String getCountry(){
		return country;
	}
	public String getInfo(){
		return "姓名:"+this.name+",年龄:"+this.age+",国家:"+this.country;
	}
}	
public class Hello {
	public static void main(String args[]){
		//此时没有实例化对象产生
		System.out.println(Person.getCountry());
		Person.setContry("清朝");
		System.out.println(Person.getCountry());
		System.out.println(new Person("小淘淘",20).getInfo());
	}
}

在这里插入图片描述
static的方法依然不受到实例化对象的控制,所以可以由类名称直接调用。
但是此时类中的方法就存在有两种:static方法、非static方法,两种方法之间的互相访问就会出现问题:

  • 所有的非static方法可以直接调用static方法或static属性;
  • static方法不能够直接调用非static方法或非static属性;
    在这里插入图片描述
    分析?为什么会出现有这样的定义呢?
  • 所有的static属性或方法可以在类没有实例化对象的时候进行直接调用;
  • 所有非static属性或方法必须在类产生实例化对象之后才可以进行调用。
    那么什么时候可以用static方法呢?
  • 类设计的过程中百分之九十的方法都使用非static方法
  • 如果一个类中没有任何的属性,那么这个类不需要定义普通方法,只需要定义static方法。
    范例:对比一下两种代码
    在这里插入图片描述
    因为此时MyMath类没有属性,没有属性就不需要使用到堆内存,若使用第一种方式,则会开辟一块无用的堆内存空间。所以此时第二种方法更合理。

观察主方法(理解)

在最早讲解方法定义的时候给出了两种方案:

  • 第一种:某一个方法定义在主类中,并且由主方法直接调用,定义格式:
public static 返回值类型 方法名称(){}

-第二种:某一方法定义在类中,并且有实例化对象进行调用,定义格式:

public 返回值类型 方法名称(){}

下面来做简单分析:
如果主类中定义的方法没有使用static,那么肯定无法通过主方法直接进行调用。此时只能够通过产生本类实例化对象的方式进行调用。

public class Hello {
	public static void main(String args[]){
		new Hello().print();
	}
	public void print(){
		System.out.println("*****Hello!!!*****");
	}
}

以后编程中,主类不会定义方法,方法大部分封装在类之中,通过产生对象进行调用。
Java中的主方法是历史上最长的:

  • public:访问权限,所有操作者可见;
  • static:执行一个类的时候输入:“java类名称”,表示由类直接调用;
  • void:主方法是一切的起点,开始了就一直继续
  • main:系统定义好的方法名称
  • String args[]:程序执行时的输入参数,初始化参数。
    范例:取得初始化输入参数
public class Hello {
	public static void main(String args[]){
		for(int x=0;x<args.length;x++){
			System.out.println(args[x]);	
		}
	}
}

输出为空。
如果要输入参数,则在解释Java程序时,类后面用空格设置,每个属性间用空格区分。
如果输入的参数本身就带有空格,那么这个时候可以使用“"”转义。
在这里插入图片描述
在这里插入图片描述

static应用

static在一些系统类库中会大量出现,那么这些就有可能是static方法导致的。static属性有一个最好的特点在于:公共属性,所有对象都可以对其进行修改。
范例:实现一个属性的个数统计
所有的新的对象产生时都一定要调用构造方法,所以可以在构造方法里增加一个统计。

class Person{
	private static int count=1;//统计个数
	public Person(){
		System.out.println("对象个数:"+count++);
	}
}
public class Hello {
	public static void main(String args[]){
		new Person();new Person();new Person();
	}
}

在这里插入图片描述
进行修改,假设Person中存在一个name属性,那么在Person中提供两个构造方法:一个是负责接收name属性内容的,一个是无参的,无论适用哪种方法,都要求为name属性设置一个名字,而不是null。这种属性自动命名的操作就可以通过static属性实现。
范例:为属性自动命名

class Person{
	private static int count=1;//统计个数
	private String name;
	public Person(){
		this("无名氏——"+count++);
	}
	public Person(String name){
		this.name=name;
	}
	public String getName(){
		return this.name;
	}
}
public class Hello {
	public static void main(String args[]){
		System.out.println(new Person().getName());
		System.out.println(new Person().getName());
		System.out.println(new Person("SMITH").getName());
	}
}

这样的操作以后在高级部分会见到应用。

总结

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值