1.static引入

  通常来说,当创建一个类是,就是在描述那个类的对象的外观与行为。除非用new创建那个类的对象,否则实际并未获取任何对象。当执行new来创建对象时,数据存储空间才被分配,七方法才供外界调用。

  但是有两种情况是上述方法无法解决的。一种是,只想为某特定域分配单一存储空间,而不去考虑究竟要创建多少对象。甚至根本就不创建对象。另一种是,希望某种方法不与包含他的类的任何对象关联在一起。也就是说没有创建对象,也能调用这个方法。

  static可以满足这两方面需求。声明一个static时,就意味着这个域或方法不会与包含它的那个类的任何对象关联在一块,即使未创建这个类的任何对象也可以调用其static方法。

2.static基本用法

  (1)只须将static关键字放在定义之前,就可以将字段或者方法设定为static,如下

class Test{
static int i = 1;
}

现在即使创建两个Test对象,Test.i也只有一份存储空间,这两个对象共享一个i。如下

Test i1 = new Test();
Test i2 = new Test();

这里i1.i 与i2.i指向同一块存储空间,因此具有相同的值1。

  (2)引用static变量有两种方法,之前的是一种,也可以用下面的方式直接用。注意这对于非static的成员是不行的。

  

Test.i ++;

这里使用类名引用static变量的首选方式。这是因为强调了变量的static结构,而且在某些情况下他还为编译器进行优化提供更好机会。

3.static方法

  类似的逻辑可以应用到静态方法中,既可以像其他方法一样,通过一个对象来引用某个静态方法,也可以通过特殊的语法形式clasName.method()加以引用。定义形式如下

class Test2{
static void test(){
Test.i ++;
}
}

使用时可以用对象调用调用,如

 Test2 t2 = new Test2();
t2.test();

或者直接用类对其递调用。如:

Test2.test();

因此,如果说想在不创建对象的情况下调用某个方法,就可以将这个方法设置为static。我们最常见的static方法就是main方法,至于为什么main方法必须是static的,现在就很清楚了。因为程序在执行main方法的时候没有创建任何对象,因此只有通过类名来访问。

  另外记住,即使没有显示地声明为static,类的构造器实际上也是静态方法。

4.static误区

(1)static关键字会改变类中成员的访问权限吗?

这里不要将java中的static与C/C++中的static关键字混淆了,与C/C++中的不同,java关键字不会影响到变量或方法的作用域,在java中能影响到访问权限的只有private、public、protect。

(2)能通过this访问静态成员变量么?

对于静态方法来书没有this,那么下面代码的结果是什么?

public class Main{
static int value = 33;
public static void main(String[] args)throws Exception{
new Main().printValue();
} private void printValue(){
int value = 3;
System.out.println(this.value);
}
}

结果是

33

这里主要考察this和static的理解(this的用法详见java中this关键字)。this代表当前对象,通过new Main()来调用printValue的话,当前对象就是通过new Main()生成对象,而static变量是被所有对象所享有的,因此在printValue中this.Value的值毫无疑问是33.在printValue内部的value是局部变量,根本不可能与this相连,所以输出结果是33.这里永远记住:静态成员虽然独立于对象,但是不代表不可以通过对象去访问,所有的静态方法和静态变量都可以通过对象访问。

(3)static可以作用与局部变量么?

在C/C++中static是可以作用于局部变量的,但是在java中切忌:static是不允许用来修饰局部变量。这是java语法规定。

5.常见笔试面试题

1.下面代码的结果是什么?

public class StaticTest extends Base{

    static{
System.out.println("test static");
} public StaticTest(){
System.out.println("test constructor");
} public static void main(String[] args) {
new StaticTest();
}
} class Base{ static{
System.out.println("base static");
} public Base(){
System.out.println("base constructor");
}
}

结果是

base static
test static
base constructor
test constructor

分析下,在执行开始,先要寻找到main方法,因为main方法是程序的入口,但是在执行main方法之前,必须先加载Test类,而在加载Test类的时候发现Test类继承自Base类,因此会转去先加载Base类,在加载Base类的时候,发现有static块,便执行了static块。在Base类加载完成之后,便继续加载Test类,然后发现Test类中也有static块,便执行static块。在加载完所需的类之后,便开始执行main方法。在main方法中执行new Test()的时候会先调用父类的构造器,然后再调用自身的构造器。因此,便出现了上面的输出结果。

(2)下面程序的结果是什么?

public class Test {
Person person = new Person("Test");
static{
System.out.println("test static");
} public Test() {
System.out.println("test constructor");
} public static void main(String[] args) {
new MyClass();
}
} class Person{
static{
System.out.println("person static");
}
public Person(String str) {
System.out.println("person "+str);
}
} class MyClass extends Test {
Person person = new Person("MyClass");
static{
System.out.println("myclass static");
} public MyClass() {
System.out.println("myclass constructor");
}
}

结果是

test static
myclass static
person static
person Test
test constructor
person MyClass
myclass constructor

分析下,首先加载Test类,因此会执行Test类中的static块。接着执行new MyClass(),而MyClass类还没有被加载,因此需要加载MyClass类。在加载MyClass类的时候,发现MyClass类继承自Test类,但是由于Test类已经被加载了,所以只需要加载MyClass类,那么就会执行MyClass类的中的static块。在加载完之后,就通过构造器来生成对象。而在生成对象的时候,必须先初始化父类的成员变量,因此会执行Test中的Person person = new Person(),而Person类还没有被加载过,因此会先加载Person类并执行Person类中的static块,接着执行父类的构造器,完成了父类的初始化,然后就来初始化自身了,因此会接着执行MyClass中的Person person = new Person(),最后执行MyClass的构造器。

(3)下面代码的输出结果是什么?

public class Test {

    static{
System.out.println("test static 1");
}
public static void main(String[] args) { } static{
System.out.println("test static 2");
}
}

结果是

test static 1
test static 2

分析下,虽然在main方法中没有任何语句,但是还是会输出,原因上面已经讲述过了。另外,static块可以出现类中的任何地方(只要不是方法内部,记住,任何方法内部都不行),并且执行是按照static块的顺序执行的。

本文参考:

《java编程思想》

http://www.cnblogs.com/dolphin0520/p/3799052.html

以上就是static的简单基本用法。总结如是。

java中static的学习的更多相关文章

  1. Java学习笔记十七:Java中static使用方法

    Java中static使用方法 一:Java中的static使用之静态变量: 我们都知道,我们可以基于一个类创建多个该类的对象,每个对象都拥有自己的成员,互相独立.然而在某些时候,我们更希望该类所有的 ...

  2. java中static关键字的作用

    java中static关键字主要有两种作用: 第一:为某特定数据类型或对象分配单一的存储空间,而与创建对象的个数无关. 第二,实现某个方法或属性与类而不是对象关联在一起 简单来说,在Java语言中,s ...

  3. Java中static的用法,初始化块

    使用 Arrays 类操作 Java 中的数组语法: Arrays.sort(数组名); 可以使用 sort( ) 方法实现对数组的排序,只要将数组名放在 sort( ) 方法的括号中,就可以完成对该 ...

  4. Java中static块执行时机

    Java中static块执行时机 演示例子 在使用static进行初始化的操作,怎么也执行不了!代码如下: public class StaticDemo { public static final ...

  5. java中static变量和方法的总结

    转自:http://blog.csdn.net/haobo920/article/details/5921621 java中static变量和方法的总结 java中一切皆是对象 一个类中对象的定义一般 ...

  6. Java中static final 与 final 的区别(转载)

    转自:http://advance0683.iteye.com/blog/1107732 Java中static final 与 final 的区别: 例子: Java代码 import java.u ...

  7. Java中static修饰类的问题

    Java中static修饰类的问题 众所周知,Java中static关键字可以修饰方法与变量: 修饰变量的时候,这个变量属于类变量,可以直接通过类名.变量名来引用. 修饰方法的时候可以直接通过类名.方 ...

  8. Java 中 static 的作用

    static 关键字的作用 在 Java 中 static 关键字有4种使用场景,下面分别进行介绍: 1.static 成员变量 public class Student { // 静态成员变量 pr ...

  9. Java中static的用法

    static静态,作为修饰符,最初是由c引入,一开始static表示退出一个块后依然存在的局部变量.随后,static表示不能被其他文件访问的全局变量和函数.到了C++和java,static表示属于 ...

随机推荐

  1. Qt开发动画

    #include <QPropertyAnimation> #include <QDesktopWidget> //下坠 void MainWindow::on_pushBut ...

  2. springmvc拦截器基本使用

    1.HandlerExecutionChain是一个执行链,当用户的请求到达DispatcherServlet的时候,DispatcherServlet会到HandlerMapping中查找对应的Ha ...

  3. 剑指Offer——重建二叉树2

    Question 输入某二叉树的后序遍历和中序遍历的结果,请重建出该二叉树.假设输入的后序遍历和中序遍历的结果中都不含重复的数字.例如输入后序遍历序列{1, 3, 4, 2}和中序遍历序列{1, 2, ...

  4. MapReduce-计数器

    计数器 计数器是收集作业统计信息的有效手段之一,用于质量控制或应用级统计.计数器还可辅助诊断系统故障.根据计数器值来记录某一特定事件的发生比分析一堆日志文件容易得多.内置计数器Hadoop为每个作业维 ...

  5. 【转】数据库获得当前时间getdate()

    CONVERT(nvarchar(10),count_time,121): CONVERT为日期转换函数,一般就是在时间类型 (datetime,smalldatetime)与字符串类型(nchar, ...

  6. CSS3中的变形功能

    一.变形主要值得是利用transform功能来实现文字或图片的旋转,缩放,倾斜,移动这四种处理. 1.旋转-----transform:rotate(xxdeg);( IE9以上,safari 3.1 ...

  7. NSLog Release

    //将下面的代码插入到pch文件中即可 #ifndef __OPTIMIZE__ # define NSLog(…) NSLog(__VA_ARGS__) #else # define NSLog(… ...

  8. C#下利用正则表达式实现字符串搜索功能的方法(转)

    关键字:正则表达式.元字符.字符串.匹配: 1.正则表达式简介:正则表达式提供了功能强大.灵活而又高效的方法来处:.NET框架正则表达式并入了其他正则表达式实现的: 2.字符串搜索:正则表达式语言由两 ...

  9. Spring3.2.9 + JdbcTemplate 学习

    applicationContext.xml <?xml version="1.0" encoding="UTF-8"?> <beans xm ...

  10. crontab 总结

    crontab -e --------- linux定时任务提示-bash: crontab: command not found 执行 crontab 命令如果报 command not found ...