当前位置 : IT培训网 > Java开发 > Java教程 > Java语言中的static关键字及Java静态变量和静态方法

Java语言中的static关键字及Java静态变量和静态方法

时间:2016-08-04 16:23:44  来源:Java培训网  作者:IT培训网  已有:名学员访问该课程
标签(Tag):   java语言(263)static(8)
静态变量和静态方法能够通过类名来访问,不需要创建一个类的对象来访问该类的静态成员,所以static修饰的成员又称作类变量和类方法。静态变量与实例变量不同,实例变量总是通过对象来访问,因为它们的值在对象和对象之间

static是Java中的一个关键字,我们不能声明普通外层类或者包为静态的。static用于下面四种情况。

静态变量:我们可以将类级别的变量声明为static。静态变量是属于类的,而不是属于类创建的对象或实例。因为静态变量被类的所有实例共用,所以非线程安全的。通常静态变量还和关键字final一起用,作为所有对象共用的资源或常量。如果静态变量不是私有的,那么可以通过ClassName.variableName来访问它。

//静态变量的例子

private static int count;

public static String str;

public static final String DB_USER = "myuser";

静态方法:类似于静态变量,静态方法也属于类,不属于实例的。静态类只能访问类的静态变量,或调用类的静态方法。通常静态方法作为工具方法,被其它类使用,而不需要创建类的实例。譬如集合类、Wrapper类(String, Integer等)和工具类(java.util中的类)都有很多静态方法。通常java程序的开始就是一个main()方法,它就是个静态方法。

//静态方法的例子

public static void setCount(int count) {

    if(count > 0)

    StaticExample.count = count;

}

//静态工具方法

public static int addInts(int i, int...js){

    int sum=i;

    for(int x : js) sum+=x;

    return sum;

}

静态块:静态块就是类加载器加载对象时,要执行的一组语句。它用于初始化静态变量。通常用于类加载的时候创建静态资源。我们在静态块中不能访问非静态变量。我们可以在一个类中有多个静态块,尽管这么做没什么意义。静态块只会在类加载到内存中的时候执行一次。

static{

    //在类被加载的时候用于初始化资源

    System.out.println("StaticExample static block");

    //仅能访问静态变量和静态方法

    str="Test";

    setCount(2);

}

静态类:我们对嵌套类使用static关键字。static不能用于最外层的类。静态的嵌套类和其它外层的类别无二致,嵌套只是为了方便打包。

Java static关键字以及Java静态变量和静态方法介绍:

static 修饰符能够与变量、方法一起使用,表示是“静态”的。

静态变量和静态方法能够通过类名来访问,不需要创建一个类的对象来访问该类的静态成员,所以static修饰的成员又称作类变量和类方法。静态变量与实例变量不同,实例变量总是通过对象来访问,因为它们的值在对象和对象之间有所不同。

请看下面的例子:

复制格式化新窗口

public class Demo {

    static int i = 10;

    int j;

    Demo() {

        this.j = 20;

    }

    public static void main(String[] args) {

        System.out.println("类变量 i=" + Demo.i);

        Demo obj = new Demo();

        System.out.println("实例变量 j=" + obj.j);

    }

}

运行结果:

类变量 i=10

实例变量 j=20

static 的内存分配

静态变量属于类,不属于任何独立的对象,所以无需创建类的实例就可以访问静态变量。之所以会产生这样的结果,是因为编译器只为整个类创建了一个静态变量的副本,也就是只分配一个内存空间,虽然有多个实例,但这些实例共享该内存。实例变量则不同,每创建一个对象,都会分配一次内存空间,不同变量的内存相互独立,互不影响,改变 a 对象的实例变量不会影响 b 对象。

请看下面的代码:

public class Demo {

    static int i;

    int j;

    public static void main(String[] args) {

        Demo obj1 = new Demo();

        obj1.i = 10;

        obj1.j = 20;

        Demo obj2 = new Demo();

        System.out.println("obj1.i=" + obj1.i + ", obj1.j=" + obj1.j);

        System.out.println("obj2.i=" + obj2.i + ", obj2.j=" + obj2.j);

    }

}

运行结果:

obj1.i=10, obj1.j=20

obj2.i=10, obj2.j=0

注意:静态变量虽然也可以通过对象来访问,但是不被提倡,编译器也会产生警告。

上面的代码中,i 是静态变量,通过 obj1 改变 i 的值,会影响到 obj2;j 是实例变量,通过 obj1 改变 j 的值,不会影响到 obj2。这是因为 obj1.i 和 obj2.i 指向同一个内存空间,而 obj1.j 和 obj2.j 指向不同的内存空间,请看下图:

Java语言中的static关键字及Java静态变量和静态方法_www.itpxw.cn

图1  静态变量内存分配

注意:static 的变量是在类装载的时候就会被初始化。也就是说,只要类被装载,不管你是否使用了这个static 变量,它都会被初始化。

小结:类变量(class variables)用关键字 static 修饰,在类加载的时候,分配类变量的内存,以后再生成类的实例对象时,将共享这块内存(类变量),任何一个对象对类变量的修改,都会影响其它对象。外部有两种访问方式:通过对象来访问或通过类名来访问。

静态方法

静态方法是一种不能向对象实施操作的方法。例如,Math 类的 pow() 方法就是一个静态方法,语法为 Math.pow(x, a),用来计算 x 的 a 次幂,在使用时无需创建任何 Math 对象。

因为静态方法不能操作对象,所以不能在静态方法中访问实例变量,只能访问自身类的静态变量。

以下情形可以使用静态方法:

•       一个方法不需要访问对象状态,其所需参数都是通过显式参数提供(例如 Math.pow())。

•       一个方法只需要访问类的静态变量。

读者肯定注意到,main() 也是一个静态方法,不对任何对象进行操作。实际上,在程序启动时还没有任何对象,main() 方法是程序的入口,将被执行并创建程序所需的对象。

关于静态变量和静态方法的总结:

•       一个类的静态方法只能访问静态变量;

•       一个类的静态方法不能够直接调用非静态方法;

•       如访问控制权限允许,静态变量和静态方法也可以通过对象来访问,但是不被推荐;

•       静态方法中不存在当前对象,因而不能使用 this,当然也不能使用 super;

•       静态方法不能被非静态方法覆盖;

•       构造方法不允许声明为 static 的;

•       局部变量不能使用static修饰。

静态方法举例:

public class Demo {

    static int sum(int x, int y){

        return x + y;

    }

    public static void main(String[] args) {

        int sum = Demo.sum(10, 10);

        System.out.println("10+10=" + sum);

    }

}

运行结果:

10+10=20

static 方法不需它所属的类的任何实例就会被调用,因此没有 this 值,不能访问实例变量,否则会引起编译错误。

注意:实例变量只能通过对象来访问,不能通过类访问。

静态初始器(静态块)

块是由大括号包围的一段代码。静态初始器(Static Initializer)是一个存在于类中、方法外面的静态块。静态初始器仅仅在类装载的时候(第一次使用类的时候)执行一次,往往用来初始化静态变量。

示例代码:

public class Demo {

    public static int i;

    static{

        i = 10;

        System.out.println("Now in static block.");

    }

    public void test() {

        System.out.println("test method: i=" + i);

    }

    public static void main(String[] args) {

        System.out.println("Demo.i=" + Demo.i);

        new Demo().test();

    }

}

运行结果是:

Now in static block.

Demo.i=10

test method: i=10

静态导入

静态导入是 Java 5 的新增特性,用来导入类的静态变量和静态方法。

一般我们导入类都这样写:

import packageName.className;  // 导入某个特定的类

import packageName.*;  // 导入包中的所有类

而静态导入可以这样写:

import static packageName.className.methonName;  // 导入某个特定的静态方法

import static packageName.className.*;  // 导入类中的所有静态成员

导入后,可以在当前类中直接用方法名调用静态方法,不必再用 className.methodName 来访问。

对于使用频繁的静态变量和静态方法,可以将其静态导入。静态导入的好处是可以简化一些操作,例如输出语句 System.out.println(); 中的 out 就是 System 类的静态变量,可以通过 import static java.lang.System.*; 将其导入,下次直接调用 out.println() 就可以了。

请看下面的代码:

import static java.lang.System.*;

import static java.lang.Math.random;

public class Demo {

    public static void main(String[] args) {

        out.println("产生的一个随机数:" + random());

    }

}

运行结果:

产生的一个随机数:0.05800891549018705

顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
------分隔线----------------------------
Java教程
1、Java 概述
1.1 Java语言概述
1.2 Java虚拟机以及跨平台原理
1.3 Java的主要就业方向
1.4 Java的不同版本
1.5 Java开发环境搭建
1.6 第一个Java程序示例
1.7 Java类和对象的概念
1.8 Java类库及其组织结构
1.9 Java import
2、Java 语法基础
2.1 Java数据类型以及变量的定义
2.2 Java数据类型转换
2.3 Java运算符
2.4 Java流程控制
2.5 Java数组的定义和使用
2.6 Java字符串(String)
2.7 Java StringBuffer与StringBuider
2.8 强调一下编程风格
3、Java 类与对象
3.1 Java类的定义及其实例化
3.2 Java访问修饰符
3.3 Java变量的作用域
3.4 Java this关键字详解
3.5 Java方法重载
3.6 Java类的基本运行顺序
3.7 Java包装类、拆箱和装箱详解
3.8 再谈Java包
3.9 源文件的声明规则
4、Java 继承和多态
4.1 继承的概念与实现
4.2 Java super关键字
4.3 继承中的方法的覆盖和重载
4.4 多态和动态绑定
4.5 instanceof 运算符
4.6 多态对象的类型转换
4.7 Java static关键字
4.8 Java final关键字
4.9 Java Object类
5、面向对象高级特性
5.1 Java内部类及其实例化
5.2 内部类的分类
5.3 抽象类的概念和使用
5.4 接口的概念和使用
5.5 接口和抽象类的区别
5.6 Java 泛型
5.7 泛型通配符和类型参数的范围
6、异常处理
6.1 异常处理基础
6.2 异常类型Java语言中常见的异常类型有哪些
6.3 未被捕获的异常
6.4 try和catch的使用
6.5 多重catch语句的使用
6.6 try语句的嵌套
6.7 throw:异常的抛出
6.8 throws子句
6.9 finally块
6.10 Java的内置异常
6.11 创建自己的异常子类
6.12 断言
7、线程编程
7.1 线程的概念
7.2 Java线程模型
7.3 主线程
7.4 创建线程
7.5 创建多线程
7.6 isAlive()和join()的使用
7.7 线程优先级
7.8 线程同步
7.9 线程间通信
7.10 线程死锁
7.11 线程的挂起、恢复和终止
8、输入输出(IO)操作
8.1 输入输出基本概念
8.2 面向字符的输入流
8.3 面向字符的输出流
8.4 面向字节的输入输出流
8.5 面向字节流的应用
8.6 文件与目录管理
8.7 文件的随机读写
8.8 文件的压缩处理
9、常用类库、向量与哈希
9.1 Java基础类库
9.2 Object类
9.3 Java语言包(java.lang)简介
9.4 日期和时间类
9.5 向量及其应用
9.6 哈希表及其应用
10、图形界面(GUI)设计
10.1 图形界面设计基础
10.2 框架窗口
10.3 标签、按钮和按钮事件
10.4 面板
10.5 布局设计
10.6 文本框和文本区
10.7 文本框和文本区的输入输出
10.8 选择框和单选按钮
10.9 列表和组合框
10.10 菜单
10.11 对话框
10.12 滚动条
10.13 鼠标事件
10.14 键盘事件
11、图形、图像与多媒体
11.1 绘图基础
11.2 设置字型和颜色
11.3 绘图模式
11.4 Graphics类的绘图方法
11.5 Graphics2D类的绘图方法
11.6 图像处理基础
11.7 图像缓冲技术
11.8 多媒体基础
12、网络与数据库编程
12.1 IP地址和InetAddress类
12.2 统一资源定位符
12.3 套接字(Socket)
12.4 数据库连接
12.5 几个重要的类和接口
12.6 数据库查询
12.7 数据库更新
12.8 插入记录
12.9 修改记录
12.10 删除记录