转载请注明出处:http://mingnianshimanian.iteye.com/admin/blogs/2324016
汇总了一些关于static的资料,包括用法,特点,以及作用等。以及一些经典的面试题。如有错误请指出,欢迎共同学习进步。
static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量的概念。被static修饰的成员变量和成员方法独立于该类的任何对象。也就是说,它不依赖类特定的实例,被类的所有实例共享。
只要这个类被加载,Java虚拟机就能根据类名在运行时数据区的方法区内定找到他们。因此,static对象可以在它的任何对象创建之前访问,无需引用任何对象。static变量前可以有private修饰,表示这个变量可以在类的静态代码块中,或者类的其他静态成员方法中使用(当然也可以在非静态成员方法中使用--废话),但是不能在其他类中通过类名来直接引用,这一点很重要。实际上你需要搞明白,private是访问权限限定,static表示不要实例化就可以使用,这样就容易理解多了。static前面加上其它访问权限关键字的效果也以此类推。用static修饰的代码块表示静态代码块,当Java虚拟机(JVM)加载类时,就会执行该代码块。
1.static变量
按照是否静态的对类成员变量进行分类可分两种:一种是被static修饰的变量,叫静态变量或类变量;另一种是没有被static修饰的变量,叫实例变量。两者的区别是:
- 对于静态变量在内存中只有一个拷贝(节省内存),JVM只为静态分配一次内存,在加载类的过程中完成静态变量的内存分配,可用类名直接访问(方便),当然也可以通过对象来访问(但是这是不推荐的)。
- 对于实例变量,没创建一个实例,就会为实例变量分配一次内存,实例变量可以在内存中有多个拷贝,互不影响(灵活)。
2.static方法
静态方法可以直接通过类名调用,任何的实例也都可以调用,因此静态方法中不能用this和super关键字,不能直接访问所属类的实例变量和实例方法(就是不带static的成员变量和成员成员方法),只能访问所属类的静态成员变量和成员方法。
因为实例成员与特定的对象关联!这个需要去理解,想明白其中的道理,不是记忆。因为static方法独立于任何实例,因此static方法必须被实现,而不能是抽象的abstract。例如为了方便方法的调用,Java API中的Math类中所有的方法都是静态的,而一般类内部的static方法也是方便其它类对该方法的调用。静态方法是类内部的一类特殊方法,只有在需要时才将对应的方法声明成静态的,一个类内部的方法一般都是非静态的。
3.static代码块
static代码块也叫静态代码块,是在类中独立于类成员的static语句块,可以有多个,位置可以随便放,它不在任何的方法体内,JVM加载类时会执行这些静态的代码块,如果static代码块有多个,JVM将按照它们在类中出现的先后顺序依次执行它们,每个代码块只会被执行一次。看下面的一个例子:
public class WangPan { private static String a; private String b; private static String c; private static String d; static { WangPan.a = "static--a"; System.out.println(a); WangPan wang = new WangPan(); wang.test(); wang.b = "static--b"; System.out.println(wang.b); } static { WangPan.c = "static--c"; System.out.println(c); } public static void main(String[] args) { // to do something... } static { WangPan.d = "static--d"; System.out.println(a); } public void test() { System.out.println("this is test"); } }
运行结果如下:
static--a
this is test
static--b
static--c
static--a
利用静态代码块可以对一些static变量进行赋值,最后再看一眼这些例子,都一个static的main方法,这样JVM在运行main方法的时候可以直接调用而不用创建实例。
4.static和final方法
static final用来修饰成员变量和成员方法,可简单理解为”全局常量“!对于变量,表示一旦给值就不可修改,并且通过类名可以访问。对于方法,表示不可覆盖,并且可以通过类名直接访问。
5.总结
- 方便在没有创建对象的情况下进行调用方法或变量;静态代码块以用来优化代码性能,只会在类加载的时候执行一次。
- 静态方法中不能访问非静态成员变量和方法,因为static方法中不能使用this。
- 非静态方法可以访问静态成员变量和方法。
- 类的构造器实际上也是静态方法。
- static 不允许用来修饰局部变量。
- 静态成员属于整个类,当系统第一次使用该类时就会为其分配内存空间直到该类被卸载才会进行垃圾回收。
看一个例子:
Test有一个静态变量和一个非静态变量:
public class Test { // 注意value是静态的成员变量 static int value = 9; String aa = "test"; }
另一个类中调用Test类变量:
public class WangPan { public static void main(String[] args) { System.out.println("=====静态成员变量可以直接通过类调用====="+Test5.value); Test5 test = new Test5(); System.out.println("=====非静态成员变量要通过实例化对象调用====="+test.aa); } }
当Test类被加载时静态变量就会初始化,而非静态变量必须通过实例化对象才能调用。
6.关于static面试题(持续更新)
(1).有三个类分别是X,Y,Z:
public class X { Y y = new Y(); static { System.out.println("111"); } X() { System.out.println("222"); } public static void main(String[] args) { new Z(); } }
public class Y { Y() { System.out.println("555"); } }
其中Z类继承了X类:
public class Z extends X{ Y y = new Y(); static { System.out.println("333"); } Z() { System.out.println("444"); } }
运行结果如下:
111
333
555
222
555
444
分析:
1.首先分析一段程序的执行后的结果,我们得先找到程序的入口,然后才能着手分析。也就是main()方法。
2.我们发现main()方法在X类中,要执行main()方法,还得先将X类加载到内存中。
3.X类加载完成后,会做什么事情呢?别急,先来看看static的作用,不知道吧。告诉你:static就是在类被第一次加载的时候执行,以后就不再执行。
4.知道了static的作用,那么X类被加载,那么就会先执行X类的静态属性和静态语句块(static),执行先后顺序看谁在前面就先执行谁。只在此时执行,以后都不会。
5.所以一个输出结果为111,没问题了吧。
6.X类的static语句块执行完了,就该执行main()方法啦。
7.new Z();此方法被执行。
8.既然new Z();那么Z类就要被加载。因为Z类继承X类。所以必须先加载X类才行。因为X类已经被加载。所以此时不用再加载X类了。Z类加载好了就要执行Z类的static语句块。
9.那么就会打印出333了吧。
10.都加在完后就要实例化对象了。
11.实例化Z之前,还得先实例化X对吧。因为子类的构造方法都会调用父类的构造方法。
12.那就先实例化X类吧。
13.执行X方法前还得先初始化对不。也就是获取所有属性。那么X类的属性Y就会获取。
14.即X类的Y y=new Y();要被执行。也就是会打印555。
15.接着执行System.out.println("222");
16.然后就是执行Z的构造方法。
17.同样先获取Z的属性Y y=new Y();打印555。
18.再执行System.out.println("444");
(2)一道选择题:
public class Test5 { // 注意value是静态的成员变量 static int value = 9; public static void main(String[] args) throws Exception { new Test5().printValue(); } private void printValue() { int value = 69; System.out.println(this.value); } }
这个程序会有下面哪种结果?
A. 编译错误
B. 打印9
C. 打印69
D. 运行时抛出异常
分析:此题答案是9,static只是起到了疑惑的作用,去掉static一样打印9,this.value指的是当前对象的属性。如果去掉this就会是69。
(3)Test5中有2个静态变量,并重写了toString方法:
public class Test5 { private static int id; private static String name; public static int getId() { return id; } public static void setId(int id) { Test5.id = id; } public static String getName() { return name; } public static void setName(String name) { Test5.name = name; } @Override public String toString() { return "id:" + id + "," + "name:" + name; } @SuppressWarnings("static-access") public static void main(String[] args) { List<Test5> list = new ArrayList<Test5>(); for (int i = 0; i < 4; i++) { Test5 t = new Test5(); t.setId(i + 1); t.setName("tom" + (i + 1)); Test5.setId(i + 1); list.add(t); } System.out.println(list); } }
输出结果为[id:4,name:tom4, id:4,name:tom4, id:4,name:tom4, id:4,name:tom4];list.size()=4,所以for循环中new了4个Test5对象,由于id和name是静态变量具有全局性,就是无论set多少次,都是最后一次set的值把前面的所有都覆盖。
而如果把静态变量改为非静态变量,就会输出:[id:1,name:tom1, id:2,name:tom2, id:3,name:tom3, id:4,name:tom4]
相关推荐
根据给定的信息,我们可以整理出一系列与C++相关的面试题及知识点解析,下面将逐一进行详细阐述。 ### C++ 面试题知识点解析 #### 1. 预处理器指令 预处理器是编译器执行的第一步,在实际编译之前处理源代码。预...
C++面试题集.pdf 本文档提供了一系列C++面试题,涵盖了内存拷贝、双向链表、费波那其数列、类的构造函数、析构函数和赋值函数、循环、单向链表类的实现、二叉树实现等多个方面的知识点。 内存拷贝 面试题:写一个...
Java 面试题、Java 框架面试题 Java 面试题是 Java 开发人员面试的必备知识,涵盖了 Java 基础知识、Java 框架、Java 集合框架、Java 多线程、Java 网络编程等方面的知识点。在本文中,我们将对 Java 面试题进行...
### Java程序员面试题详解 #### 一、Java基础知识 1. **作用域public, private, protected, 以及不写时的区别** - **public**: 可以被任何类访问。 - **protected**: 可以被同一包内及不同包内的子类访问。 - ...
- 面试题:如何理解Java中的“static”关键字? 2. **数据类型与变量** - 区分基本数据类型与引用数据类型,探讨它们在内存中的分配方式。 - 面试题:解释Java中的自动装箱和拆箱机制。 3. **运算符与控制结构*...
"C# Winform 面试题详解" C# Winform 面试题详解 1. foreach 遍历访问的对象需要实现 IEnumerable 接口或声明 GetEnumerator 方法的类型 在 C# 中,foreach 语句可以遍历实现了 IEnumerable 接口或声明了 ...
Android 高级开发面试题以及答案整理 Android 高级开发面试题以及答案整理是 Android 开发者面试的重要参考资料。该资料涵盖了 Java 基础知识、Android 平台知识、数据存储、网络编程、多媒体处理、Android 架构...
### 2017最新Java面试题知识点梳理 #### 一、面向对象编程(OOP) 面向对象编程(Object-Oriented Programming, OOP)是一种编程范式,它使用“对象”的概念来组织代码结构。Java作为一种典型的面向对象语言,支持...
### C++面试题集锦(非常详细):关键知识点解析 #### 一、引用和指针的区别 在C++中,引用和指针是两种不同的数据类型,它们各自有着独特的特性和用途。以下是它们之间的一些主要区别: 1. **内存分配**: - **...
PHP面试题总结 本文总结了PHP面试中的常见题目,涵盖了优先级、static 变量、类型转换、count 函数、foreach 循环、reference 变量、浮点数概念、ini_set 函数、isset 函数、逻辑判断和赋值操作等多方面的知识点。 ...
### Java面试题知识点概览 #### 面向对象概念 1. **super()与this()的区别**: - `super()`用于调用父类的构造方法或父类成员方法。 - `this()`用于调用本类中的其他构造方法。 2. **作用域public, protected, ...
### 2018 iOS面试题汇总解析 #### 一、设计模式的理解及常见类型 设计模式是指在软件开发过程中,对于特定问题的一种普遍适用的解决方案。它代表着开发者们长期以来积累的经验教训,可以帮助我们更好地组织代码,...
此外,JAVA类默认是public和static的,而实例变量默认是private的。 ### 3. Java的封装特性 封装是JAVA面向对象编程的一个核心原则,它通过将数据和操作数据的方法封装在一起,保护数据不被外部代码直接访问和修改...
cocos2d-x 面试题 cocos2d-x 是一个流行的开源游戏引擎,广泛应用于游戏开发领域。以下是 cocos2d-x 相关的知识点总结: 1. New 和 malloc 的区别: New 和 malloc 都是用于申请动态内存和释放内存的,但是它们...
Java常见面试题 Java是最流行的编程语言之一,掌握Java的基础知识是非常重要的。在这里,我们总结了Java常见的面试题,涵盖了Java的基础部分,包括基本语法、类相关的语法、内部类的语法、继承相关的语法、异常的...
C 语言面试题总汇 本文档将详细介绍 C 语言面试题总汇,涵盖了 C 语言的各种知识点,包括静态变量、指针、引用、实时系统、堆栈溢出、虚函数、冒泡排序、网络协议、IP 地址等。 1. static 变量的用途: static ...
### 第三部分面试题 #### 47. collection和collections的区别 - `Collection`:接口,是Java集合框架的基础接口之一。 - `Collections`:工具类,提供了一系列静态方法用于操作集合。 #### 48. list,set,map是否...
Java作为一门广泛使用的编程语言,其面试题涵盖了众多的知识领域,包括基础语法、面向对象、集合框架、多线程、异常处理、IO流、网络编程、设计模式、JVM内存模型以及框架应用等。以下是对这100道Java面试题可能涉及...