Java中的static关键字解析转载
原创static关键字是很多朋友在编写和阅读代码时遇到的关键字。这也是大公司的面试官在面试时喜欢问的知识点之一。让我们先谈谈这件事。static最后列出了关键字的用法和通常容易被误解的地方。static试题。以下是本文的目录大纲:
一.static关键字的用途
二.static关键词中的错误
三.常见笔试试题
如果有什么不对的地方,我希望能够理解,并欢迎批评和纠正。
敬请尊重作者的劳动成果,转载原文链接:
http://www.cnblogs.com/dolphin0520/p/3799052.html
一.static关键字的用途
在《Java编程思想P86这一页上有一段话:
“static方法是否定的。this方法。在……里面static不能在方法内部调用非静态方法,这反过来也是可能的。并且您只能通过类本身调用它,而不需要创建任何对象。static方法。这实际上就是static该方法的主要用途。
虽然这段话只展示了static的方法,但可以看出static简而言之,关键字的基本功能用一句话来描述:
无需创建对象就可以方便地调用(方法)。/变量)。
显然,作为static对象不需要访问关键字修改的方法或变量。只要加载了类,就可以通过类名访问它们。
static可以用来修改类的成员方法、类成员变量,并且可以编写。static优化程序性能的代码块。
1)static方法
static方法通常称为静态方法,因为静态方法不依赖于任何对象来访问,因此对于静态方法,没有。this是的,因为它没有附着到任何物体上,因为没有物体,所以它不是this是。并且由于该特性,类的非静态成员变量和非静态成员方法不能在静态方法中被访问,因为非静态成员方法/变量必须依赖于要调用的特定对象。
但是,请注意,虽然非静态成员方法和非静态成员变量不能在静态方法中访问,但静态成员方法可以在非静态成员方法中访问。/变量之间的关系。一个简单的例子:
在上面的代码中,由于print2方法独立于对象而存在,并且可以使用类名直接调用。假设您可以在静态方法中访问非静态方法。/变量,则如果在。main方法具有以下语句:
MyObject.print2();
目前还没有任何物体,str2没有矛盾这回事。方法也是如此,因为您无法在中进行预测。print1是否在方法中访问非静态成员变量,因此在静态成员方法中也禁止访问非静态成员方法。
对于非静态成员方法,它访问静态成员方法。/变量显然是无限的。
因此,如果要在不创建对象的情况下调用方法,可以设置该方法static。我们最常见的static方法就是main方法,关于为什么main方法必须为static是的,现在很清楚了。因为程序正在执行。main方法不创建任何对象,因此只能通过类名访问它。
还要记住,无论构造函数是static方法可以参考:http://blog.csdn.net/qq\_17864929/article/details/48006835
2)static变量
static变量也称为静态变量。静态变量和非静态变量之间的区别在于,静态变量由所有对象共享,并且在内存中只有一个副本。它们在且仅在第一次加载类时初始化。但是,非静态变量由对象拥有,并在创建对象时进行初始化。存在多个副本,每个对象拥有的副本不会相互影响。
static成员变量的初始化顺序按照定义的顺序进行初始化。
3)static代码块
static关键字的另一个关键作用是 用于形成静态代码块以优化程序性能。static块可以放在类中的任何位置,并且可以有多个static阻止。当第一次加载类时,它将遵循static执行每个操作的块的顺序static块,并且只会执行一次。
为什么说static由于块的特性,它可用于优化程序性能:它只会在加载类时执行一次。让我们来看一个例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
class
Person{
private
Date birthDate;
public
Person(Date birthDate) {
this
.birthDate = birthDate;
}
boolean
isBornBoomer() {
Date startDate = Date.valueOf(
"1946"
);
Date endDate = Date.valueOf(
"1964"
);
return
birthDate.compareTo(startDate)>=
0
&& birthDate.compareTo(endDate) <
0
;
}
}
isBornBoomer是给这个人用的吗?1946-1964出生在,并且每个isBornBoomer当被调用时,它被生成。startDate和birthDate如果将导致空间浪费的两个对象更改为以下内容,则效率会更高:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class
Person{
private
Date birthDate;
private
static
Date startDate,endDate;
static
{
startDate = Date.valueOf(
"1946"
);
endDate = Date.valueOf(
"1964"
);
}
public
Person(Date birthDate) {
this
.birthDate = birthDate;
}
boolean
isBornBoomer() {
return
birthDate.compareTo(startDate)>=
0
&& birthDate.compareTo(endDate) <
0
;
}
}
因此,很多时候会进行一些只需要执行一次的初始化操作static在代码块中。
二.static关键词中的错误
1.static关键字是否会更改类中成员的访问权限?
一些初学者朋友会java中的static与C/C++中的static关键词的功能被混淆了。只需记住一件事:。C/C++中的static不同,Java中的static该关键字不影响变量或方法的作用域。在……里面Java仅限private、public、protected(包括包访问)这些关键字。请看下面的例子来理解:
提示错误"Person.age 不可视",这说明static关键字不会更改对变量和方法的访问。
2.能通过this访问静态成员变量?
尽管不适用于静态方法this,则在非静态方法中可以传递。this访问静态成员变量?先看下面的一个例子,这段代码输出的结果是什么?
1
2
3
4
5
6
7
8
9
10
11
12
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什么意思?this表示当前对象,然后通过。new Main()来调用printValue传递当前对象。new Main()生成的对象。和static变量由对象使用,因此在printValue中的this.value的价值毋庸置疑33。在printValue方法内部value是一个无法关联的局部变量this关联,因此输出结果为33。这里要始终记住的一件事是:尽管静态成员变量独立于对象,但它们并不意味着不能通过对象访问它们。所有静态方法和静态变量都可以通过对象访问(只要访问权限足够)。
3.static它能对局部变量起作用吗?
在C/C++中static是可以限定作用域的局部变量,但在。Java中切记:static不允许修改局部变量。别问为什么,这就是Java文法规定。
具体原因请参考这篇博客文章中的讨论:http://www.debugease.com/j2se/178932.html
三.常见笔试试题
以下是一些在书面面试中经常遇到的问题。static关键字的标题仅供参考。如果有任何补充,请在下面留言。
1.以下代码的输出是什么?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public
class
Test
extends
Base{
static
{
System.out.println(
"test static"
);
}
public
Test(){
System.out.println(
"test constructor"
);
}
public
static
void
main(String[] args) {
new
Test();
}
}
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.此代码的输出是什么?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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.此代码的输出是什么?
1
2
3
4
5
6
7
8
9
10
11
12
13
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执行块的顺序。
参考资料:
http://lavasoft.blog.51cto.com/62575/18771/
http://www.51cto.com/specbook/24/35011.htm
http://blog.csdn.net/zhu_apollo/article/details/1888219
http://blog.sina.com.cn/s/blog_70b845780100n9zz.html
http://hi.baidu.com/yuiezt/item/b71ff5fbfe9c385cc8f3370d
http://bbs.csdn.net/topics/330251070
http://yezixingchen.iteye.com/blog/1597186
版权声明
所有资源都来源于爬虫采集,如有侵权请联系我们,我们将立即删除