前言
static关键字
本章讲解static关键字定义属性以及定义方法的操作。
static是Java中定义的一个关键字,主要是描述全局的概念,所以利用static关键字可以定义一些属性、定义方法。但是在90%的情况下,我们的开发代码很少会去直接编写static。
一、利用static定义属性
现在假设定义一个只描述中国人的类,那么在这个类里面肯定包含姓名、年龄、国家。
来看一下代码:
class Persontea{
private String name;
private int age;
String country="中华人民共和国";//此属性暂时不封装
public Persontea(String name,int age){
this.name=name;
this.age=age;
}
public String getInfo(){
return "name:"+this.name+",age:"+this.age+",country:"+this.country;
}
}
public class javatest1 {
public static void main(String args[]){
Persontea perA=new Persontea("ss0",10);
Persontea perB=new Persontea("ss1",10);
Persontea perC=new Persontea("ss2",10);
System.out.println(perA.getInfo());
System.out.println(perB.getInfo());
System.out.println(perC.getInfo());
}
}
上述代码应该很好懂,但是,如果在main方法中出现了perA.country=“balabala”;,那么最后的getInfo结果也会改变,我们不希望这样改变,最好的方法是将国家的属性设置为公共属性。所有的对象都可以共享此属性,如果要想实现这样的操作,就可以通过static关键字来进行定义。
范例:使用static关键字来定义
class Persontea{
private String name;
private int age;
static String country="中华人民共和国";//此属性暂时不封装
public Persontea(String name,int age){
this.name=name;
this.age=age;
}
public String getInfo(){
return "name:"+this.name+",age:"+this.age+",country:"+this.country;
}
}
public class javatest1 {
public static void main(String args[]){
Persontea perA=new Persontea("ss0",10);
Persontea perB=new Persontea("ss1",10);
Persontea perC=new Persontea("ss2",10);
perA.country="ss";//修改了一个对象的属性
System.out.println(perA.getInfo());
System.out.println(perB.getInfo());
System.out.println(perC.getInfo());
}
}
通过执行结果可以发现,修改了一个对象的属性之后,所有对象对应的属性都发生了改变,所以这样的属性,我们称之为公共属性,公共属性必须通过static定义,而对于公共属性的内容保存不会在栈也不会在堆,而是会存在于我们的全局数据区之中。
但是现在出现了一个问题,既然static属于全局属性,那么一个对象进行修改是否合适呢?
很明显,这是不合适的,最好的做法是利用所有对象的一个最高的代表来操作,这个代表就是类。
所以对于static定义的一个属性可以有类名称直接进行调用,这样的属性也被称为类属性。
如:Persontea.country=“sss”;
此时类中存在有static属性以及非static属性,但在里面需要注意一点:
所有的非static属性都是在对象实例化的时候才会进行内存的分配;
所有的static属性可以在没有实例化对象产生的情况下直接使用。
范例:直接调用类属性
class Persontea{
private String name;
private int age;
static String country="中华人民共和国";//此属性暂时不封装
public Persontea(String name,int age){
this.name=name;
this.age=age;
}
public String getInfo(){
return "name:"+this.name+",age:"+this.age+",country:"+this.country;
}
}
public class javatest1 {
public static void main(String args[]){
Persontea.country="hh";
System.out.println(Persontea.country);
System.out.println(new Persontea("ss",9).getInfo());
}
}
虽然static定义在了类之中,但是其是完全独立的,不受实例化对象控制。
在90%的情况下类的设计都会使用非static属性,只有在10%表示公共的属性,或者是与类实例化无关的属性定义时才会考虑使用static。
二、利用static定义方法
利用static定义的属性可以直接通过类名称进行访问,但是static也可以用于方法的定义上,同样,这个方法可以由类名称直接进行调用。
范例:定义static方法:
class Persontea{
private String name;
private int age;
private static String country="中华人民共和国";//封装
public Persontea(String name,int age){
this.name=name;
this.age=age;
}
public static void setCountry(String c){
country=c;
}
public static String getCountry(){
return country;
}
public String getInfo(){
return "name:"+this.name+",age:"+this.age+",country:"+this.country;
}
}
public class javatest1 {
public static void main(String args[]){
//此时没有实例化对象产生
System.out.println(Persontea.getCountry());
Persontea.setCountry("sss");
System.out.println(Persontea.getCountry());
System.out.println(new Persontea("sssss",8).getInfo());
}
}
static的方法依然不受到实例化对象的控制,所以可以由类名称直接调用。但是此时,类中的方法就存在有两种:static方法、非statiic方法,那么这两种方法的互相访问就会出现问题。
所有的非sattic方法可以直接调用static方法或static属性。
比如,我们可以用getInfo调用getCountry,代码如下:
class Persontea{
private String name;
private int age;
private static String country="中华人民共和国";//封装
public Persontea(String name,int age){
this.name=name;
this.age=age;
}
public static void setCountry(String c){
country=c;
}
public static String getCountry(){
return country;
}
public String getInfo(){
System.out.println(getCountry());
return "name:"+this.name+",age:"+this.age+",country:"+this.country;
}
}
public class javatest1 {
public static void main(String args[]){
System.out.println(new Persontea("sssss",8).getInfo());
}
}
注意:static方法不能够直接调用非static方法或者是非static属性。
我们来分析一下:
1.所有的static属性或方法可以在类没有实例化对象的时候进行直接调用;
2.所有的非static属性或方法必须在类产生实例化对象之后才可以进行调用
所以,发现了没有,调用static属性方法的时候,可能还没有对象,所以static方法其实自然不建议调用非static属性或方法。
那么,最后,我们来想一下什么时候使用static方法呢?
1.类设计过程之中90%的方法都使用非static方法定义
2.如果一个类中没有任何的熟悉那个,那么这个类不需要定义普通方法,只需要定义static方法就行了。
关于以上的2,我们可以参考对比代码来理解一下:
class Math{
public int add(int x,int y){
return x+y;
}
}
public class javatest1 {
public static void main(String args[]){
System.out.println(new Math().add(10,20));
}
}
来看另外一段代码:
class Math{
public static int add(int x,int y){
return x+y;
}
}
public class javatest1 {
public static void main(String args[]){
System.out.println(Math.add(10,20));
}
}
因为此时Math类没有属性就不需要使用到堆内存,而如果使用了第一种代码,意味着要开辟一块不用的堆内存空间。所以这个时候,在内存的角度看,第二种方式更为合理。
三、观察主方法
在讲解方法定义的时候实际上给出了两种方案:
第一种:某一个方法定义在主类中,并且由主方法直接调用,定义格式:
public static 返回值类型 方法名称(){}
第二种:某一个方法定义在了类中,并且由实例化对象进行调用,定义格式:
public 返回值类型 方法名称(){}
废话不多说,来看代码:
public class javatest1 {
public static void main(String args[]){//static方法
print();
}
public void print(){//非static方法
System.out.println("hello world");
}
}
我们会发现报错:java: 无法从静态上下文中引用非静态 方法 print()
我们来分析一下:
如果主类中定义的方法没有使用static,那么肯定无法通过主方法直接进行调用,上面讲过嗷,static无法调用非static的,但是反过来,这个时候只能够通过产生本类实例化对象的方式来进行调用。
public class javatest1 {
public static void main(String args[]){//static方法
new javatest1().print();//对象.方法
}
public void print(){//非static方法
System.out.println("hello world");
}
}
进行如上修改后,就可以调用了,相当于是对象.方法。
在以后所编写的代码过程之中,主类不会编写什么方法,大部分的方法都会封装在类之中,通过产生对象调用。
我们来看一下主方法:
Java中的主方法可以说是历史之最长的:
public:是一种访问权限,表示所有的操作者都可以看见;
static:执行一个类的时候输入:”java类名称“,表示由类直接调用;
void:主方法是一切的起点,开始了就继续吧;
main:是一个系统定义好的方法名称;
String args[]:程序执行时的输入参数,初始化参数。
如果要输入参数,则在解释Java程序时,类后面利用空格设置,每个参数间使用空格区分。但是如果你输入的参数原本就带有空格,那么这个时候可以使用” ” “转义
这了解一下就行,没啥用
四、static应用案例
static在一些系统类库上会大量的出现,那么这些就可能是static方法所导致的。这次重点来看static属性。
static属性有一个最好的特点在于:公共属性,所有对象都可以对其进行修改。
范例:实现一个对象的个数统计.
所有的新的实例化对象产生时都一定要调用构造方法,所以可以在构造方法里面增加一个统计。
class Persontea{
private static int count=1;//统计个数
public Persontea(){
System.out.println("对象个数:"+count++);
}
}
public class javatest1 {
public static void main(String args[]){//static方法
new Persontea();
new Persontea();
new Persontea();
}
}
实际上可以将以上的程序进一步的修改,现在假设Persontea类中存在有一个name的属性,那么在Persontea类提供有两个构造方法;一个负责接收name属性内容,一个是无参的,但是不管使用那种构造方法都应该为我们的name属性设置一个名字,而不是null,这种属性自动命名的操作,就可以通过static属性实现。
来代码:为属性自动命名
class Persontea{
private static int count=1;//统计个数
private String name;
public Persontea(){
this("无名氏-"+count++);
}
public Persontea(String name){
this.name=name;
}
public String getName(){
return this.name;
}
}
public class javatest1 {
public static void main(String args[]){//static方法
System.out.println(new Persontea().getName());
System.out.println(new Persontea().getName());
System.out.println(new Persontea("sss").getName());
}
}
这样的操作在以后的高级部分会见到其应用。
总结
1.在类的首要设计过程之中不要去考虑static属性或者方法;
2.使用static方法大部分情况下有两种可能性
(1)可以不受到类实例化的对象控制;
(2)类中就没提供有普通属性
下一节我们会讲解代码块,加油嗷。