static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量的概念。
我们先来看以下程序
private String name;
private int age ;
String city="A城";
public Person() {
}
public Person(String name, int age) {
this.name= name;
this.age = age;
}
public String fun(){
return "姓名:"+this.name + " 年龄:"+this.age + " 城市:"+city;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class StaticDemo {
public static void main(String[] args) {
Person p1 = new Person("MOHAN",19);
Person p2 = new Person("damiao",17);
Person p3 = new Person("dez",23);
System.out.println(p1.fun());
System.out.println(p2.fun());
System.out.println(p3.fun());
}
}
输出结果:
姓名:MOHAN 年龄:19 城市:A城
姓名:damiao 年龄:17 城市:A城
姓名:dez 年龄:23 城市:A城
那么问题来了!
·city的属性表示的的信息都是一样的,对于各个对象来说内容重复了,
·如果我们假设将A城改为B城,那么此时以及有500对象产生了,那么我们将要修改500次,现在最好的解决问题的方法就是将 city设为public属性
我们来看代码
class Person2{
private String name;
private int age ;
String city="A城";
public Person2() {
}
public Person2(String name, int age) {
this.name= name;
this.age = age;
}
public String fun(){
return "姓名:"+this.name + " 年龄:"+this.age + " 城市:"+city;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class StaticDemo2 {
public static void main(String[] args) {
Person2 p1 = new Person2("MOHAN",19);
Person2 p2 = new Person2("damiao",17);
Person2 p3 = new Person2("dez",23);
p1.city="B城";
System.out.println(p1.fun());
System.out.println(p2.fun());
System.out.println(p3.fun());
}
}
那么此时的输出结果
姓名:MOHAN 年龄:19 城市:B城
姓名:damiao 年龄:17 城市:A城
姓名:dez 年龄:23 城市:A城
我们发现 只是p1更改为B城了
我么来说如果想将一个属性设置成public属性,我们就需要使用static关键字来声明。
class Person2{
private String name;
private int age ;
static String city="A城";
public Person2() {
}
public Person2(String name, int age) {
this.name= name;
this.age = age;
}
public String fun(){
return "姓名:"+this.name + " 年龄:"+this.age + " 城市:"+city;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class StaticDemo2 {
public static void main(String[] args) {
Person2 p1 = new Person2("MOHAN",19);
Person2 p2 = new Person2("damiao",17);
Person2 p3 = new Person2("dez",23);
p1.city="B城";
System.out.println(p1.fun());
System.out.println(p2.fun());
System.out.println(p3.fun());
}
}
输出结果:
姓名:MOHAN 年龄:19 城市:B城
姓名:damiao 年龄:17 城市:B城
姓名:dez 年龄:23 城市:B城
我们可以看到城市全部都改为B城了,我们来看一下内存中的地址
我们可以看到这三个对象全都指向了city属性,当我们给city重新赋值时就会更改为B城,
总结:用public修饰的static成员变量和成员方法本质是全局变量和全局方法,当声明它类的对象市,不生成static变量的副本,而是类的所有实例共享同一个static变量。
下面我们来看static修饰的方法
静态方法可以直接通过类名调用,任何的实例也都可以调用,
因此静态方法中不能用this和super关键字。
class Person3{
private String name;
private int age ;
private static String city="A城";
public static void setCity(String c){
city = c;
}
public Person3() {
}
public Person3(String name, int age) {
this.name= name;
this.age = age;
}
public String fun(){
return "姓名:"+this.name + " 年龄:"+this.age + " 城市:"+city;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class StaticDemo3 {
public static void main(String[] args) {
Person3 p1 = new Person3("MOHAN",19);
Person3 p2 = new Person3("damiao",17);
Person3 p3 = new Person3("dez",23);
Person3.setCity("B城");
System.out.println(p1.fun());
System.out.println(p2.fun());
System.out.println(p3.fun());
}
}
这时我们的输出结果:
姓名:MOHAN 年龄:19 城市:B城
姓名:damiao 年龄:17 城市:B城
姓名:dez 年龄:23 城市:B城
我们来说如果让一个人说这个城市改为B城了,他要给A城每一个人说,如果让整个城市的人都说这个是B城,这人对我们来说容易了很多。
再看这个程序
class Person3{
private String name;
private int age ;
private static String city="A城";
public static void setCity(String c){
city = c;
this.name= name ;
}
public Person3() {
}
public Person3(String name, int age) {
this.name= name;
this.age = age;
}
public String fun(){
return "姓名:"+this.name + " 年龄:"+this.age + " 城市:"+city;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class StaticDemo3 {
public static void main(String[] args) {
Person3 p1 = new Person3("MOHAN",19);
Person3 p2 = new Person3("damiao",17);
Person3 p3 = new Person3("dez",23);
Person3.setCity("B城");
System.out.println(p1.fun());
System.out.println(p2.fun());
System.out.println(p3.fun());
}
}
这个程序会报错:
Exception in thread "main" java.lang.Error: Unresolved compilation problems:
Cannot use this in a static context
Cannot make a static reference to the non-static field name
意思是:
不能在静态上下文中使用它
无法对非静态字段名进行静态引用
记住:静态方法只能调用静态方法和变量,它是不能调用非静态方法和变量的。
而非静态方法可以调用我们的静态方法和变量,只有实例化之后才能。
静态属性和方法可以在没有实例化对象的时候调用。
在类中普通属性和普通方法。只能在实例化之后被调用。
我们来说一下主方法 我们的主方法上也存在static关键字 它有什么含义呢?
public static void main(String args []){
- public:最大的权限,所有人多可以访问。
- static:执行之方法就是执行类的名称,表示可以由类名称直接调用。
- void:主方法就是一切的起点,所以有没返回值,就相当于一个人出生之后还能再回去吗?
- main:这个就是我们系统内建的方法名称。
- String args []:表示字符串数组。用于接收参数
}
public class StaticDemo4 {
public static void main(String args[]) {
for(int i=0;i<args.length;i++){
System.out.println(args[i]+"、");
}
}
}
此程序的输出格式
Java StaticDemo4 参数1 参数2 参数3......中间是要有空格的。
比如直接输出 hello world
输出结果为:hello、
world、
那么想要输出 hello world 就要 "hello world"
那么这时的输出结果为:hello world。
此时的程序内存划分:
- 栈内存:对象名称,实际上是对象对堆的引用地址。
- 堆内存:属性。
- 全局代码区:保存所有的操作方法。
- 全局数据区:保存所有的static属性。
static成员是不能被其所在class创建的实例访问的。 如果不加static修饰的成员是对象成员,也就是归每个对象所有的。 加static修饰的成员是类成员,就是可以由一个类直接调用,为所有对象共有的。