static 关键字分析

在java中static 关键字用途很广,可以修饰成员变量 方法 甚至类(静态内部类),这里不分析static 修饰类

  • static修饰的内容的运行顺序

java的程序执行之前有一个类的加载的过程,在这个过程中将会执行static修饰的代码,重上往下执行,所以说static修饰的成员变量(顺便说一下,static不能用来修饰局部变量,java语法规定,没有为什么)或者方法会在对象还没有被实例化的时候将会被执行

  • static 访问限制

可以重上面推导以下规律:statc修饰的方法可以访问static修饰的属性和方法但不允许访问 非static修饰的属性和方法,非static修饰的变量和方法可以访问static修饰的变量和方法和非static修饰的属性和方法

对于一行规律不难理解,static修饰的变量和方法在类的加载时就已经被定义了,而此时的非static 修饰的变量和方法还没有被对象的实例化所创建,所以就有了上述的访问界限

  • static定义的方法中不能使用this
    this是本类对象的引用,可以表示正在调用的对象,用this.属性变量可以用来访问成员属性变量,但在static定义的方法中不允许用this访问成员属性变量,在我们前面的分析中可以知道static定义的方法在类的加载时就会执行,而在这个过程中,对象还没有被实例化,此时的this没有意义

对static的实际意义分析
    static表示“全局”或者“静态”的意思,用该关键字修饰的变量和方法,将不单独属于某个对象,而是被所以的对象共享
这样的方法一般称为静态变量(类变量)或者静态方法(类方法),它由对象层级上升为类层级,可有类名.直接访问(推荐该方式),他将不依赖于任何对象,因此static方法必须被实现,

举例说明
描述一个图书的类这些书的出版社相同

//定义一个描述图书的类
class Book{
	private String title;//标题
	private String author;//作者
	private double price;//价格
	String pub="沐言友拓出版社";//出版社 
	public Book(String title,String author,double price){
		this.title=title;
		this.author=author;
		this.price=price;
	}
	//得到图书的信息
	public String getInfo(){
		return"出版社:"+this.pub+"图书标题:"+this.title+"作者:"+this.author+"价格"+this.price;
	}
	
}	
	public class BookTest{
		public static void main(String[]args){
		Book book1=new Book("java重入门到项目实战","李兴华",99.2);
		Book book2=new Book("spring开发实战","李兴华",98.3);
		System.out.println(book1.getInfo());
		System.out.println(book2.getInfo());
			
		
	}
}
运行结果
![](https://img2022.cnblogs.com/blog/2942946/202210/2942946-20221025225146465-227031292.png)

对该类的对象的内存结构进行分析

该程序来说一般图书的出版社是不变的,这个程序的运行没有问题,假如我们就是一个作家,有一天我们想换一个出版社出版图书,假如我们有1000本图书,如果我们要修改上面这个程序的打印信息的话,那我们就需要将对象实力化时的出版社都修改成新的出版社,这样后天的维护太麻烦了

所以我们可以将上面的出版社定义成static 让其被所有的对象共享

修改后的代码

//定义一个描述图书的类
class Book{
	private String title;//标题
	private String author;//作者
	private double price;//价格
	static String pub="沐言友拓出版社";//出版社 
	public Book(String title,String author,double price){
		this.title=title;
		this.author=author;
		this.price=price;
	}
	//得到图书的信息
	public String getInfo(){
		return"出版社:"+this.pub+"图书标题:"+this.title+"作者:"+this.author+"价格"+this.price;
	}
	
}	
	public class BookTest{
		public static void main(String[]args){
		Book book1=new Book("java重入门到项目实战","李兴华",99.2);
		Book book2=new Book("spring开发实战","李兴华",98.3);
		Book.pub="人民出版社";
		System.out.println(book1.getInfo());
		System.out.println(book2.getInfo());
			
		
	}
}

输出结果


可以看出仅仅修改了一次出版社就被全部修改了

对此时的对象进行内存分析

可以发现此时的pab被所有对象共享,只有一个对象修改该属性,其他对象的该属性也将被修改

static 的应用之记录实例化了多少个对象

 //用static变量来记录多少个对象被实例化
 public class Static2{
	 private static int cnt=0;
	 private String name;
	 private int age;
	 public Static2(String name,int age){
		 this.name=name;
		 this.age=age;
		 cnt++;
		 System.out.println("已经实例化了"+cnt+"个对象");
	 }
	 public static void main(String[]args){
		 Static2 vr1=new Static2("刘涛",34);
		 Static2 vr2=new Static2("张三",23);
		 Static2 vr3=new Static2 ("小刘",35);
	 }
 }

static 和访问权限public private的差异
可能有人认为用static 修饰之后可以扩大访问权限,其实这是一个误区

static变量前可以有private修饰,表示这个变量可以在类的静态代码块中,或者类的其他静态成员方法中使用(当然也可以在非静态成员方法中使用--废话),但是不能在其他类中通过类名来直接引用,这一点很重要。实际上你需要搞明白,private是访问权限限定,static表示不要实例化就可以使用,这样就容易理解多了。static前面加上其它访问权限关键字的效果也以此类推。

静态方法的应用

 //定义一个图书类实现记录图书的总是并实现自动编名
 class Book{
	 
	 private long number;//图书编号 该处务必用long 和数据库的设计有关
	 private double price ;//图书价格
	 private String title;//图书标题
	 private static  long count=0;//记录图书的数量同时用于自动编号
	 
	 public Book(){};
	 //构造方法并实现图书数量记录和自动编号
	 public Book(double price,String title){
		 count++;
		 this.number=count;
		 this.price=price;
		 this.title=title;
	 }
	 public double getPrice(){
		 return this.price;
	 }
	 public String getTitle(){
		 return this.title;
	 }
	 public static long getCount(){
		 return Book.count;
	 }
	 public void setPrice(double price){
		 this.price=price;
	 }
	 public void setTitle(String title){
		 this.title=title;
	 }
	
	 //获取图书信息
	 public String getInfo(){
		 return "图书标题:"+this.title+"  图书价格:"+this.price+"  图书编号:"+this.number;
	 }
	 
	 
	 //记录图书数量
	 //该方法和对象无关
	 public static void getSum(){
		 System.out.println( "当前图书总数:"+Book.count);
	 }
 }
 
 public class Demo{
 public static void main(String[]args){
	 Book.getSum();
	 System.out.println("-----------------------------------");
	 Book book1=new Book(98.3,"java编程思想");
	 Book.getSum();
	 System.out.println( book1.getInfo());
	 System.out.println("--------------------------------");
	 
	 Book book2=new Book(23.4,"java核心技术");
	 Book.getSum();
	 System.out.println( book2.getInfo());
	 System.out.println("----------------------------------------");
	 Book book3=new Book(34.3,"effectivejava");
	 Book.getSum();
	 System.out.println( book3.getInfo());
	 
	 
 }
 }


static方法不受对象的约束,可以直接调用

static代码块
static代码块会在类的加载时被执行一遍(仅仅会被执行一遍),在类中可以有多个静态代码块,执行时将会按照顺序执行,可以用此功能
来优化程序的性能
例子参考<<参考一>>


在类中定义的static块其实是优先于main方法执行的,这与主方法程序执行的开始有点不符,

不允许静态块定义在main方法中

参考:
https://www.cnblogs.com/dolphin0520/p/3799052.html

https://blog.51cto.com/lavasoft/18771
《java实战开发经典》

总结:
只有某些方法不需要受到类中实例化对象的 才会考虑用static方法,大多数情况下类中普通方法和普通变量才时主流

posted @ 2022-10-25 23:41  一往而深,  阅读(27)  评论(0编辑  收藏  举报