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方法,大多数情况下类中普通方法和普通变量才时主流