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关键字、静态方法与普通方法、静态成员变量的更多相关文章

  1. Java面向对象--static关键字

  2. JAVA面向对象-----final关键字

    JAVA面向对象-–final关键字 1:定义静态方法求圆的面积 2:定义静态方法求圆的周长 3:发现方法中有重复的代码,就是PI,圆周率. 1:如果需要提高计算精度,就需要修改每个方法中圆周率. 4 ...

  3. java中static关键字的作用

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

  4. Java的static关键字

    本文参考:Java的static关键字 通过static关键字可以满足两方面的需要.一种情形是,只想为某特定域分配单一存储空间,而不去考虑究竟要创建多少对象,甚至根本就不创建任何对象.另一种情形是,希 ...

  5. java的static关键字 – Break易站

    本文内容来自:java的static关键字 – Break易站 (原文网站阅读体验更好) 通过static关键字可以满足两方面的需要.一种情形是,只想为某特定域分配单一存储空间,而不去考虑究竟要创建多 ...

  6. JAVA面向对象-----super关键字

    JAVA面向对象-–super关键字 1:定义Father(父类)类 1:成员变量int x=1; 2:构造方法无参的和有参的,有输出语句 2:定义Son类extends Father类 1:成员变量 ...

  7. 面向对象-static关键字实战案例

    面向对象-static关键字实战案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.static关键字概述 1>.static的功能 static关键字用于修饰成员变量和 ...

  8. 面试官:兄弟,说说Java的static关键字吧

    读者乙在上一篇我去系列文章里留言说,"我盲猜下一篇标题是,'我去,你竟然不知道 static 关键字'".我只能说乙猜对了一半,像我这么有才华的博主,怎么可能被读者猜中了心思呢,必 ...

  9. Java:static关键字小记

    Java:static关键字小记 对 Java 中的 static 关键字,做一个微不足道的小小小小记 static 修饰变量 静态变量:是被 static 修饰的变量,也称为类变量,它属于类,因此不 ...

随机推荐

  1. MacOS Docker安装

    Docker简介: Docker 是一个开源的应用容器引擎 Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级.可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化. ...

  2. <input type="checkbox" name="" value=" ">

    <input type="checkbox"  name=""  value=" ">

  3. 从输入url到页面加载的过程

    用户端请求步骤:DNS解析URL地址.生成HTTP请求报文.构建TCP连接.使用IP协议选择传输路线.数据链路层保证数据的可靠传输.物理层将数据转换成电子.光学或微波信号进行传输 网络传输: 从客户机 ...

  4. Python探索记(16)——Python的可变类型与不可变类型

    # @Time : 2017/7/8 17:49 # @Author : 原创作者:谷哥的小弟 # @Site : 博客地址:http://blog.csdn.net/lfdfhl # @DESC : ...

  5. C / C ++中的数组讲解

    笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,已出版书籍:<手把手教你架构3D游戏引擎>电子工业出版社和<Unity3D实战核心技术详解 ...

  6. OpenCV 视频与图片序列相互转换

    我们在计算机视觉相关的实验中都需要视频与图片序列之间相互转换,在平时的实验中,经常需要将视频保存为一帧一帧的图片,以获取实验结果:另一方面,很多标准的算法测试数据库都是图片序列(文件名以帧号+图片扩展 ...

  7. RIPng 知识要点

    RIPng  --------------------------------------------------------- UDP:521 多播地址:FF02::9 -------------- ...

  8. 【转】Python自动化测试 (一) Eclipse+Pydev 搭建开发环境

    原文网址:http://www.cnblogs.com/TankXiao/archive/2013/05/29/3033640.html C#之所以容易让人感兴趣,是因为安装完Visual Studi ...

  9. webpack+vue-cli搭建项目 (vue项目重构三)

    在自己的电脑下载了npm 与 node的情况下 可使用vue-cli快速构建vue项目执行命令如下: # 全局安装 vue-cli$ npm install -g vue-cli# 创建一个基于 &q ...

  10. NOIp2018 D2T3 defense——树上倍增

    题目:https://www.luogu.org/problemnew/show/P5024 考场上只会写n,m<=2000的暴力,还想了想A1和A2的情况,不过好像只得了A1的分.然后仔细一看 ...