java中static关键字的用法?主要对new User().getName()和User.name比较疑惑,啥区别呢?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java中static关键字的用法?主要对new User().getName()和User.name比较疑惑,啥区别呢?相关的知识,希望对你有一定的参考价值。

前者是private String name;以及其getName()方法;
后者是public static String name;
这两种调用效果是否一样?原理呢?请解释清楚,谢谢。

假设这两句话都是写在Person类中的,前面的意思是定义一个name的属性,那这个name属性是属于new 出的Person对象的。第二句有static,是静态的name属性,这个name属性是属于Person类的。区别就是,如果在一个地方new 了100个Person对象,那如果是第一种情况,没有static,那这100个Person对象都有自己的name值,person1修改了name,对person2~person100的name是没有影响的。如果是第二种情况,有static修饰,那这100个Person对象是公用1个name的,person1修改了name的值,person2~person100读到的值都是person1修改过的。就是这个区别。一般如果使用static修饰的属性我们称为类属性,调用的时候尽量的时候“类名.属性”的方式调用,例如:Person.name的方式调用上面的情况2,而少是用 person1.name的方式,虽然这个方式也可以,但是并不符合static静态属性是类属性的这个概念。
希望对你有帮助,谢谢。
参考技术A 肯定是不一样的了,
private String name; 这个name是User类的私有属性,当需要获取这个属性值时只能通过.getName()方法。你要是使用new User().getName()方法的话获得的永远是null,因为new 的User还没有name值。
但是public static String name;这个name是User的公共属性。可以直接通过User.name获得。因为所有的static属性都会有默认值,所以说就算是你没有给name赋值,name还是有个默认值。所以public static String name;相当于public static String name=“”;
一般只有常数才会用public static String name;这种方式定义。因为它是静态的也就是共享的,无论谁调用该类时name都会有值。
参考技术B 效果来说是一样的,最终都是看到name这个属性的值。
不过略有区别:
static是静态的,与类相关的,被static修饰的属性、方法或者代码块在加载类时就一起编译执行了。调用时也不需要通过创建类的实例来获取。即可以用User直接打点"User."调用。
而private String name这种不用static修饰的,是需要先获取类实例的,然后再实例打点调用,如:new User().getName()
参考技术C static 属于全局,也就是类的属性 和方法,换句话说 一个类,不管有多少个实例,却只有一个全局变量
class B static int a=0;
B b1=new B();..................;B bn=new B();
b1~bn 都是类B的实例,每个实例都共享 变量a,a是全局变量,属于类B的属性,每个实例都能引用变量a,
加入执行b1.a=1;后 那么b2.a,b3.a,b4.a......bn.a 都等于1了,

static 方法也是类似的

需要注意的是 静态属性和方法属于类方法,加载类后,就已经存在静态属性和方法,实例是需要用new构造出来后 才会有引用
根据先后顺序,就有以下两条规则
1、非静态的方法可以调用静态的或者非静态的属性和方法;
2、静态的方法不可以调用非静态的属性和方法,因为非静态的还不一定存在,只能先构造出来后,再通过实例引用
例如 在main方法中 可以直接调用static 的方法,调用非static方法 需要先构造出类的实例,通过实例才能调用方法
参考技术D static关键字声明一个属性为静态字段,它把这个字段作为了类的字段,所以访问时通过类名.字段名就可以访问,即你说的User.name
而private String name则定义了一个私有字段,外部是无法访问的,必须提供一个公有的方法来访问该字段。而且java中非static的字段只能使用对象来访问,所以要用new关键字来实例化一个对象,即你说的new User().getName()

Java的static和final关键字的用法

static关键字的用法

  static的意思是“’静态的”,在java里面可用于修饰属性和方法。

  static关键字的应用应注意以下几种情形:  

    1.static作用于某个字段,一个static字段对每个类来说只有一份存储空间,而非static字段是每个对象有一份存储空间。

    2.static作用于方法的重要用法是不需要创建任何对象直接调用该static方法,这对于main()方法很重要。

    3.static不能应用于局部变量。

    4.Java中禁止使用全局方法,所以引入static方法通过类本身来直接调用。

package cn.wangze.test;

class Demo{
    public static int i = 19;
}

public class staticDemo {
    private static Demo demo1 = new Demo();
    private static Demo demo2 = new Demo();
    public static void main(String[] args){
        System.out.println(Demo.i);     //19
        System.out.println(demo1.i);    //19
        System.out.println(demo2.i);    //19
        demo1.i++;
        System.out.println(Demo.i);        //20
        System.out.println(demo1.i);    //20
        System.out.println(demo2.i);    //20
        Demo.i++;
        System.out.println(Demo.i);        //21
        System.out.println(demo1.i);    //21
        System.out.println(demo2.i);    //21
    }
}

  上面程序的输出结果验证了上面两条,带有static关键字的数据在内存中占有一块固定内存地址,你可以用类名直接调用,也可以创建对象来调用,推荐ClassName.method()来调用。当我们改变它的值,任何地方的调用也会随之改变。

  Java系统自带的Math、UUID、Class等常用的工具类就是用的这种方式。

 为什么要将方法和变量都写成静态的。
 因为,这些方法我只是想调用一下,不需要牵扯工具类中的任何属性和变量,所以,我就没有必要实例化了(new)。既然不需要实例化了,那么就用静态就行了。

  你也可以在实际项目中根据业务需求来声明自己的工具类,只需要加入static关键字,引入该类后使用类名.方法名()调用即可。

  需要注意的一点是,类的加载和初始化过程中,带有static的数据会最先加载并调用,其次是构造器的加载,最后才是普通成员变量和方法的加载。

 

final关键字的用法

  final意味着"不可改变的",一般应用于数据、方法和类。

final数据

    当数据是基本类型时,意味着这是一个永不改变的编译时常量,一个在运行时被初始化的值,你不希望它改变。

    当数据是引用类型时,用static和final修饰表示这是只占据一块不能改变的内存空间。

    有一条约定成俗的规定是使用stati和final修饰的变量即编译期常量应该用全部大写字母表示,例如:

package cn.wangze.test;

import java.util.*;

class Value{
    int i;
    public Value(int i){
        this.i = i;
    }
}

public class FinalData {
    private static Random rand = new Random(47);
    private String id;
    public FinalData(String id){
        this.id = id;
    }
    private final int value_one = 9;
    private static final int VALUE_TWO = 99;
    public static final int VALUE_THREE = 39;
    private final int i4 = rand.nextInt(20);
    static final int INT_5 = rand.nextInt(20);
    private Value v1 = new Value(11);
    private final Value v2 = new Value(22);
    static final Value V3 = new Value(33);
    private final int[] a = {1,2,3,4,5,6};
    @Override
    public String toString(){
        return id+", i4="+i4+",INT_5 = "+INT_5;
    }
    public static void main(String[] args){
        FinalData fd1 = new FinalData("fd1");
        //fd1.value_one++; 错误,final修饰的基本类型数据的值不能改变
        fd1.v2.i++;
        fd1.v1 = new Value(9); //可以操作,因为v1不是final数据
        //fd1.v2 = new Value(0);  错误,final修饰的引用类型数据的内存地址不能改变
        //fd1.v3 = new Value(5);  错误,final修饰的引用类型数据的内存地址不能改变
        //fd1.a = new int[3];  /错误,final修饰的引用类型数据的内存地址不能改变
        System.out.println(fd1);   // fd1, i4=15,INT_5 = 18
        System.out.println("creating new FinalData");
        FinalData fd2 = new FinalData("fd2");  
        System.out.println(fd1);     //fd1, i4=15,INT_5 = 18
        System.out.println(fd2);    //fd2, i4=13,INT_5 = 18
    }
}

    上面例子验证了final修饰的基本数据类型和引用数据类型的区别。根据i4和INT_5的输出值可以得出结论,在编译期我们不能因为数据是final 的就可以知道它的值,只有在运行时才会确定它的值。同时这里也展示了静态和非静态的区别,带有static关键字的数据在装载时被初始化,非静态的数据是在创建对象时间初识化的。例如:

package cn.wangze.test;

class useDemo{
    private int i;
    public useDemo(int ii){
        i = ii;
    }
}

public class BlankFinal {
    private final int i = 9;
    private final int j;
    private final useDemo ud;
    public BlankFinal(){
        j = 1;
        ud = new useDemo(10);
    }
    public BlankFinal(int x){
        j = 2;
        ud = new useDemo(x);
    }
    public static void main(String[] args){
        new BlankFinal();
        new BlankFinal(55);
    }
}

   上面例子我们在定义final变量是没有给其赋值,这并没有错,但是一定要在构造器中给其赋值,不然编译都不会通过。

  2、fianl参数

    当我们把方法传入的形参定义为fianl时候,代表我们并不想在方法内部改变此参数的引用。

    public void change( final useDemo u2){
        u2.i = 20;
        //u2 = new useDemo(20); 报错
    } 

    事实是当我们不带有final关键字时,函数内部的引用改变也不会对外界的实参产生影响,所以我认为这里final的作用是编译期的阻拦,起到一个警示的作用。

  3、fianl方法

    一般我们使用final方法的目的就是防止子类对该类方法的覆盖或修改。

    类中的所有private方法都隐式的制定为final的。因为private方法只会在本类显示,即使是子类也不能操作该方法。有时候我们在子类中声明与父类private方法相同名称的方法,这样并不会报错,实际上我们并没有覆盖或者修改父类的private 方法,它只是一个和父类private方法具有相同名称的新方法。

  4、fianl类

    一般我们使用final类的目的就是说明我们不打算用任何类继承该类,即不希望该类有子类。

    带有final关键字的类,其内部所有方法和数据都是隐式带有final关键字的,因为没有类可以继承该类,代表着任何外界因素可以改变它的数据。

  总结:

    在我们设计程序的时候,会根据业务需求来决定是否对数据或方法或类带有static和final关键字,这很重要,从另一个角度来说,final和static关键字的合理应用确实可以提高程序的效率,减少内存的消耗,当我们了解了类的初始化和加载过程,可能会对final和static有一个更加直观的认识。

以上是关于java中static关键字的用法?主要对new User().getName()和User.name比较疑惑,啥区别呢?的主要内容,如果未能解决你的问题,请参考以下文章

Java基础之static关键字的用法

Java的static和final关键字的用法

Java的static和final关键字的用法

C# 之 static的用法详解

static关键字的作用?

java中不用new关键字也可以创建对象吗