Java面向对象-static关键字、静态方法与普通方法、静态成员变量
Java面向对象-static关键字、静态方法与普通方法
static关键字的基本作用:方便在没有创建对象的情况下来进行调用(方法/变量)。
很显然,被static关键字修饰的方法或者变量不需要依赖于对象来进行访问,只要类被加载了,就可以通过类名去进行访问。具体用途如下:
1.static可以用来修饰类的成员方法、类的成员变量;
2.可以编写static代码块来优化程序性能。
java里方法分为 static静态方法和普通方法:
所谓静态方法 是加了static修饰词的方法,我们使用的时候 一般用类名.方法 方式调用;
当然也可以用对象.方法 调用; 一般java里的工具类里的工具方法 用static修饰,作为静态方法;
上代码:
package com.java1234.chap03.sec03;
public class Demo02 {
void fun1(){
System.out.println("这是一个普通方法");
}
static void fun2(){
System.out.println("这是一个静态方法");
}
public static void main(String[] args) {
Demo02 demo=new Demo02();
// 调用普通方法 对象.方法
demo.fun1();
// 调用静态方法 类名.方法
Demo02.fun2();
demo.fun2();
}
}
static方法一般称作静态方法,由于静态方法不依赖于任何对象就可以进行访问,因此对于静态方法来说,是没有this的,因为它不依附于任何对象,既然都没有对象,就谈不上this了。并且由于这个特性,在静态方法中不能访问类的非静态成员变量和非静态成员方法(此处不能访问指:不能直接访问,但可以通过实例化对象访问类的非静态成员,),因为非静态成员方法/变量都是必须依赖具体的对象才能够被调用。
但是要注意的是,虽然在静态方法中不能访问非静态成员方法和非静态成员变量,但是在非静态成员方法中是可以访问静态成员方法/变量的,当然在静态方法中能访问类的静态成员变量和静态成员。
上下代码:

上面代码就是因为在静态方法中不能访问类的非静态成员变量和非静态成员方法,所以报错

上面代码就是因为:在静态方法中不能访问类的非静态成员变量和非静态成员方法(此处不能访问指:不能直接访问,但可以通过实例化对象访问类的非静态成员)
Java中静态成员变量:
static修饰的成员变量也叫类变量或全局变量,在类被加载时static修饰的成员变量被初始化,与类关联,只要类存在,static变量就存在。一个static变量单独划分一块存储空间,不与具体的对象绑定在一起,该存储空间被类的各个对象所共享。也就是说当声明一个对象时,并不产生static变量的拷贝,而是该类所有的实例对象共用同一个static变量。static修饰的成员变量能在创建任何实例对象之前被访问,而不必引用任何对象,也就是说不管创建多少对象,static修饰的变量只占有一块内存。
我们上下代码:
package com.baiye.test;
public class StaticTest {
static int a=9;
static String str="quan";
public StaticTest(){
System.out.println("static变量在类装载的时候就初始化(在实例化对象之前):a="+a);
System.out.println(a);
System.out.println(str);
}
static void staticMethod(){
str="baiye";
//return str;
System.out.println("在静态方法引用静态变量:str="+str);
}
void generalMethod(){
a=6;
System.out.println("在非静态方法中调用静态变量:a="+a);
}
public static void main(String[] args){
StaticTest st1=new StaticTest();
StaticTest st2=new StaticTest();
StaticTest st3=new StaticTest();
st1.a=5;
System.out.println("st1.a="+st1.a+" st2.a="+st2.a+" st3.a="+st3.a);
staticMethod();
System.out.println("st1.str="+st1.str+" st2.str="+st2.str+" st3.str="+st3.str);
StaticTest st4=new StaticTest();
st1.generalMethod();
System.out.println("st1.a="+st1.a+" st2.a="+st2.a+" st3.a="+st3.a);
}
}
运行结果:
static变量在类装载的时候就初始化(在实例化对象之前):a=9
9
quan
static变量在类装载的时候就初始化(在实例化对象之前):a=9
9
quan
static变量在类装载的时候就初始化(在实例化对象之前):a=9
9
quan
st1.a=5 st2.a=5 st3.a=5
在静态方法引用静态变量:str=baiye
st1.str=baiye st2.str=baiye st3.str=baiye
static变量在类装载的时候就初始化(在实例化对象之前):a=5
5
baiye
在非静态方法中调用静态变量:a=6
st1.a=6 st2.a=6 st3.a=6
在这个结果中我们可以看出不管实例多少个对象static修饰的成员变量只占有一块内存
java中static关键字不会改变类中成员的访问权限
在非静态方法中能够通过this访问静态成员变量
static是不允许用来修饰局部变量
常见的static笔试题:
1.下面这段代码的输出结果是什么?
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.这段代码的输出结果是什么?
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面向对象-static关键字、静态方法与普通方法、静态成员变量的更多相关文章
- Java面向对象--static关键字
- JAVA面向对象-----final关键字
JAVA面向对象-–final关键字 1:定义静态方法求圆的面积 2:定义静态方法求圆的周长 3:发现方法中有重复的代码,就是PI,圆周率. 1:如果需要提高计算精度,就需要修改每个方法中圆周率. 4 ...
- java中static关键字的作用
java中static关键字主要有两种作用: 第一:为某特定数据类型或对象分配单一的存储空间,而与创建对象的个数无关. 第二,实现某个方法或属性与类而不是对象关联在一起 简单来说,在Java语言中,s ...
- Java的static关键字
本文参考:Java的static关键字 通过static关键字可以满足两方面的需要.一种情形是,只想为某特定域分配单一存储空间,而不去考虑究竟要创建多少对象,甚至根本就不创建任何对象.另一种情形是,希 ...
- java的static关键字 – Break易站
本文内容来自:java的static关键字 – Break易站 (原文网站阅读体验更好) 通过static关键字可以满足两方面的需要.一种情形是,只想为某特定域分配单一存储空间,而不去考虑究竟要创建多 ...
- JAVA面向对象-----super关键字
JAVA面向对象-–super关键字 1:定义Father(父类)类 1:成员变量int x=1; 2:构造方法无参的和有参的,有输出语句 2:定义Son类extends Father类 1:成员变量 ...
- 面向对象-static关键字实战案例
面向对象-static关键字实战案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.static关键字概述 1>.static的功能 static关键字用于修饰成员变量和 ...
- 面试官:兄弟,说说Java的static关键字吧
读者乙在上一篇我去系列文章里留言说,"我盲猜下一篇标题是,'我去,你竟然不知道 static 关键字'".我只能说乙猜对了一半,像我这么有才华的博主,怎么可能被读者猜中了心思呢,必 ...
- Java:static关键字小记
Java:static关键字小记 对 Java 中的 static 关键字,做一个微不足道的小小小小记 static 修饰变量 静态变量:是被 static 修饰的变量,也称为类变量,它属于类,因此不 ...
随机推荐
- 实现QQ抽屉效果
代码: #coding: utf-8 from PyQt4.QtCore import * from PyQt4.QtGui import * import sys QTextCodec.setCod ...
- CountDownLatch闭锁
CountDownLatch是一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待. 闭锁可以延迟线程的进度直到其到达终止状态,闭锁可以用来确保某些活动直到其他活动都完 ...
- 如何在100万文字的文章中 200ms内 快速提取 替换 上万个关键字
关键点: 关键字 组合 成一棵 hash 树 ( 有属性就直接移动指针到下一个字对象, 没有属性就创建子对象, 再移动指针; 第二次循环在子对象看有没这个属性 ) 探测针 标记结束 ...
- 如何在JM8.6编码端提取QDCT?
毫无疑问,编码端的QDCT和解码端的QDCT完全相同,下面从编码端提取QDCT. 为简便起见,仅提取第一帧第一个宏块第一个4*4块的QDCT.JM8.6编码器最核心的编码函数是encode_one_m ...
- MySQL 5.7.18 在centos下安装记录
一个朋友找我如何在linux下安装mysql5.7.18,我稍微整理下了下记录,如下: 下载地址: MySQL5.7.18参数官方网址:https://dev.mysql.com/doc/refman ...
- vim自动打开跳到上次的光标位置
只需要vimrc里面加一个稍微复杂一点的autocmd就搞定了: if has("autocmd") au BufReadPost * && line(" ...
- C语言中的extern关键字用法
在C语言中,修饰符extern用在变量或者函数的声明前,用来说明“此变量/函数是在别处定义的,要在此处引用”. 1. extern修饰变量的声明.举例来说,如果文件a.c需要引用b.c中变量int v ...
- Go语言使用匿名结构体解析JSON数据
手机拥有屏幕.电池.指纹识别等信息,将这些信息填充为 JSON 格式的数据.如果需要选择性地分离 JSON 中的数据则较为麻烦.Go 语言中的匿名结构体可以方便地完成这个操作. 首先给出完整的代码,然 ...
- (二)Nginx反向代理与负载均衡的实现
引言:nginx正向代理与反向代理在上一篇文章中已经谈论过,这里狗尾草主要告诉大家Nginx对前端的小伙伴来说在工作中如何简单的使用. 1.0什么是反向代理 当我们有一个服务器集群,并且服务器集群中的 ...
- laravel 中将DB::select 得到的内容转为数组
$sql = "select count(*) as num from api_log where uid='{$this->uid}'"; $ ...