java面向对象 final static 关键字

news2024/11/16 17:34:43

目录

关键字:static

类属性、类方法的设计思想

类变量(class Variable)

静态变量的内存解析

类方法(class method)  

单例 (Singleton)设计模式

理解main方法的语法

代码块

关键字:final

总结


关键字:static

当我们编写一个类时,其实就是在描述其对象的属性和行为,而并没有产生实质上的对象,只有通过new关键字才会产生出对象,这时系统才会分配内存空间给对象,其方法才可以供外部调用。我们有时候希望无论是否产生了对象或无论产生了多少对象的情况下,某些特定的数据在内存空间里只有一份,例如所有的中国人都有个国家名称,每一个中国人都共享这个国家名称,不必在每一个中国人的实例对象中 都单独分配一个用于代表国家名称的变量

 

class Circle{
private double radius;
public Circle(double radius){this.radius=radius;}
public double findArea(){return Math.PI*radius*radius;}}
创建两个 Circle 对象
Circle c1=new Circle(2.0);
//c1.radius=2.0
Circle c2=new Circle(3.0);
//c2.radius=3.0
Circle 类中的变量 radius 是一个 实例变量 (instance variable) ,它属于类的每一个对象,不能被同一个类的不同对象所共享。
上例中 c1 radius 独立于 c2 radius ,存储在不同的空间。 c1 中的 radius 变化不会影响c2 radius ,反之亦然。
如果想让一个类的所有实例共享数据,就用类变量!

类属性、类方法的设计思想

类属性作为该类各个对象之间共享的变量。在设计类时,分析哪些属性不因对象的不同而改变,将这些属性设置为类属性。相应 的方法设置为类方法。

如果方法与调用者无关,则这样的方法通常被声明为类方法,由于不需要创建对象就可以调用类方法,从而简化了方法的调用。

使用范围: 在Java 类中,可用 static 修饰 属性、方法 代码块、内部类
修饰后的成员具备以下特点
  • 随着类的加载而加载
  • 优先于对象存在
  • 修饰的成员,被所有对象所共享
  • 访问权限允许时,可不创建对象,直接被类调用

类变量(class Variable)

类变量(类属性)由该类的所有实例共享

 

public class Person {
    private int id;
    public static int total = 0;
    public Person() {
    total++;
    id = total;
    }
}
public static void main(String args[]){
    Person Tom=new Person();
    Tom.id=0;
    total=100; // 不用创建对象就可以访问静态成员
    }
}
public class StaticDemo {
    public static void main(String args[]) {
    Person.total = 100; // 不用创建对象就可以访问静态成员
    //访问方式:类名.类属性,类名.类方法
    System.out.println(Person.total);
    Person c = new Person();
    System.out.println(c.total); //输出101
}}

静态变量的内存解析

类方法(class method)  

  • 没有对象的实例时,可以用类名.方法名()的形式访问由static修饰的类方法。
  • static方法内部只能访问类的static修饰的属性或方法,不能访问类的非static的结构。
class Person {
    private int id;
    private static int total = 0;
    public static int getTotalPerson() { 
        //id++; //非法
        return total;}
    public Person() {
        total++;
        id = total;
    }}
public class PersonTest {
    public static void main(String[] args) {
    System.out.println("Number of total is " + Person.getTotalPerson());
    //没有创建对象也可以访问静态方法
    Person p1 = new Person();
    System.out.println( "Number of total is "+ Person.getTotalPerson());
}}
因为不需要实例就可以访问 static 方法,因此 static 方法内部不能有 this ( 不能有 super ? YES!)  static 修饰的方法不能被重写
class Person {
    private int id;
    private static int total = 0;
    public static void setTotalPerson(int total){
        this.total=total; //非法,在static方法中不能有this,也不能有super
    }
public Person() {
    total++;
    id = total;
    }}
public class PersonTest {
    public static void main(String[] args) {
        Person.setTotalPerson(3);
} }

单例 (Singleton)设计模式

设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、 以及解决问题的思考方式。设计模免去我们自己再思考和摸索。就像是经典 的棋谱,不同的棋局,我们用不同的棋谱。套路

所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对 某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法。 如果我们要让类在一个虚拟机中只能产生一个对象,

我们首先必须将类的构造器的访问权限设置为private,这样,就不能用new操作符在类的外部产生类的对象了,但在类内部仍可以产生该类的对象。因为在类的外部开始还无 法得到类的对象,只能调用该类的某个静态方法以返回类内部创建的对象,静态方法只能访问类中的静态成员变量,所以,指向类内部产生的该类对象的变量也必须定义成静态的

饿汉式

class Singleton {
    // 1.私有化构造器
    private Singleton() {
    }
    // 2.内部提供一个当前类的实例
    // 4.此实例也必须静态化
private static Singleton single = new Singleton();
    // 3.提供公共的静态的方法,返回当前类的对象
    public static Singleton getInstance() {
    return single;
    }
}
懒汉式
class Singleton {
// 1.私有化构造器
    private Singleton() {
    }
// 2.内部提供一个当前类的实例
// 4.此实例也必须静态化
private static Singleton single;
    // 3.提供公共的静态的方法,返回当前类的对象
    public static Singleton getInstance() {
        if(single == null) {
            single = new Singleton();
        }
    return single;
    }
}
由于单例模式只生成一个实例, 减少了系统性能开销 ,当一个对象的 产生需要比较多的资源时,如读取配置、产生其他依赖对象时,则可 以通过在应用启动时直接产生一个单例对象,然后永久驻留内存的方式来解决。
- 应用场景
  • 网站的计数器,一般也是单例模式实现,否则难以同步。
  • 应用程序的日志应用,一般都使用单例模式实现,这一般是由于共享的日志 文件一直处于打开状态,因为只能有一个实例去操作,否则内容不好追加。
  • 数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库 资源。
  • 项目中,读取配置文件的类,一般也只有一个对象。没有必要每次使用配置文件数据,都生成一个对象去读取。
  • Application 也是单例的典型应用
  • WindowsTask Manager (任务管理器)就是很典型的单例模式
  • WindowsRecycle Bin (回收站)也是典型的单例应用。在整个系统运行过程 中,回收站一直维护着仅有的一个实例

理解main方法的语法

由于Java虚拟机需要调用类的main()方法,所以该方法的访问权限必须是 public,又因为Java虚拟机在执行main()方法时不必创建对象,所以该方法必须 是static的,该方法接收一个String类型的数组参数,该数组中保存执行Java命令时传递给所运行的类的参数。

又因为main() 方法是静态的,我们不能直接访问该类中的非静态成员,必须创建该类的一个实例对象后,才能通过这个对象去访问类中的非静态成员,这种情 况,我们在之前的例子中多次碰到

public class CommandPara {
    public static void main(String[] args) {
        for (int i = 0; i < args.length; i++) {
            System.out.println("args[" + i + "] = " + args[i]);
        }
    }
}
// 运行程序 CommandPara.java
java CommandPara “Tom" “Jerry" “Shkstart"

代码块

码块(或初始化块)的作用: Java类或对象进行初始化

代码块(或初始化块)的分类:

  • 一个类中代码块若有修饰符,则只能被static修饰,称为静态代码块 (static block),
  • 没有使用static修饰的,为非静态代码块

static代码块通常用于初始化static的属性

class Person {
    public static int total;
    static {
        total = 100;//为total赋初值
    }
    …… //其它属性或方法声明
}
静态代码块:用 static 修饰的代码块
  • 1. 可以有输出语句。
  • 2. 可以对类的属性、类的声明进行初始化操作。
  • 3. 不可以对非静态的属性初始化。即:不可以调用非静态的属性和方法。
  • 4. 若有多个静态的代码块,那么按照从上到下的顺序依次执行。
  • 5. 静态代码块的执行要先于非静态代码块。
  • 6. 静态代码块随着类的加载而加载,且只执行一次。

非静态代码块:没有static修饰的代码块

  • 1. 可以有输出语句。
  • 2. 可以对类的属性、类的声明进行初始化操作。
  • 3. 除了调用非静态的结构外,还可以调用静态的变量或方法。
  • 4. 若有多个非静态的代码块,那么按照从上到下的顺序依次执行。
  • 5. 每次创建对象的时候,都会执行一次。且先于构造器执行。

静态初始化块举例

class Person {
    public static int total;
    static {
        total = 100;
        System.out.println("in static block!");
    }
}
public class PersonTest {
    public static void main(String[] args) {
        System.out.println("total = " + Person.total);
        System.out.println("total = " + Person.total);
    }
}
//in static block
//total=100
//total=100
程序中成员变量赋值的执行顺序

  • 声明成员变量的默认初始化
  • 显式初始化、多个初始化块依次被执行
  • \构造器再对成员进行初始化操作(同级别下按先后顺序执行)
  • 通过”对象.属性”或”对象.方法”的方式,可多次给属性赋值

关键字:final

Java中声明类、变量和方法时,可使用关键字final来修饰,表示“最终的”。

  • final标记的类不能被继承。提高安全性,提高程序的可读性。 String类、System类 StringBuffer
  • final标记的方法不能被子类重写。 比如:Object类中的getClass()
  • final标记的变量(成员变量或局部变量)即称为常量。名称大写,且只能被赋值一次
  • final标记的成员变量必须在声明时或在每个构造器中或代码块中显式赋值,然后才能使用。 final double MY_PI = 3.14;
 //final修饰类 中国古代,什么人不能有后代,就可以被final声明,称为“太监类”!
final class A{
}
class B extends A{ //错误,不能被继承。
}

//final修饰方法
class A {
    public final void print() {
        System.out.println("A");
    }
}
class B extends A {
    public void print() { // 错误,不能被重写。
        System.out.println("B");
    }
}

// final修饰变量——常量 常量名要大写,内容不可修改。——如同古代皇帝的圣旨。

class A {
    private final String INFO = "1"; //声明常量
     public void print() {
    //The final field A.INFO cannot be assigned
    //INFO = "ONE";
    }
}

//static final:全局常量
关键字 final 应用举例
public final class Test {
    public static int totalNumber = 5;
    public final int ID;
    public Test() {
        ID = ++totalNumber; // 可在构造器中给final修饰的“变量”赋值
    }
    public static void main(String[] args) {
        Test t = new Test();
        System.out.println(t.ID);
        final int I = 10;
        final int J;
        J = 20;
        J = 30; // 非法
    }
}

总结

package com.jyc.p2;
/*
* 一.static关键字的使用
*   static可以用来修饰 属性 方法 构造器 内部类
*   使用static修饰属性 :静态变量
*       属性使用static修饰又分为静态属性(类变量) vs 非静态属性(实例变量)
*       实例变量:我们创建了类的多个对象,每个对象都有独立的一套类中的非静态属性.当修改一个对象中的
*                非静属性时,不会导致对象中同样的属性值的修改
*       静态变量:我们创建了类的多个对象,多个对象共享同一个静态变量,当通过某一个对象修改静态变量
*                其他对象调用此静态变量时,是修改过的
*      static修饰符的其他说明
*         1.静态变量随着类的加载而加载(可以通过类.静态变量的方式进行调用)
*         2.静态变量的加载要早于对象的创建
*         3.由于类只会加载一次,则静态变量在内存中也会存在一份,存在方法区的静态域中
*         4.类不可以调用实例变量
*
*      例如 System.out  Math.PI
*
*   使用static修饰方法
*    1. 随着类的加载而加载,可以通过类.静态方法的方式进行调用
*    2.不能调用非静态方法
*    3.静态方法中只能调用静态的方法或属性,非静态的方法中,既可以调用非静态的方法和属性,也可以调用静态
*    的方法和属性
*
*   static注意点
*   在静态的方法内不能使用this super 关键字
*   从生命周期的角度理解
*   属性是可以被多个对象共享的,不会随着对象的不同而不同
*   操作静态的方法,通常设置为static
*   工具类中的方法,习惯上声明为static 比如 Math.Arrays
*
* 二 单例设计模式
*  所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,
*
* 饿汉式 vs 懒汉式
* 懒汉式 :延迟 对象的创建
* 饿汉式: 对象加载时间过长,线程安全
*
* 三 main方法的使用
*   1.mian()程序的入口
*     public static void main(String[] args) {}(也是普通的静态方法)
*     也可以作为我们与控制台交互的方式
*
* 四 代码块(或者初始化)
*   1.代码块的作用 用来初始化类 对象
*   2.代码块只能使用static修饰
*   3.分类 静态代码块 vs 非静态代码块
*   5.静态代码块
*       内部可以有输出语句
*       随着类者加载而执行,而且只执行一次
*       初始化类信息
*       如果一个类中定义了多个代码块,则按照声明的先后顺序执行
*       静态代码块的执行由于非静态代码块
*       静态代码块内可以调用静态属性静态方法,不能调用非静态结构
*
*     非静态代码块
*       内部可以有输出语句
*       随着对象的创建而执行,每创建一个对象执行一次
*       作用:可以对对象的属性进行初始化
*       如果一个类中定义了多个代码块,则按照声明的先后顺序执行
*       非静态代码块可以调用静态属性,静态方法 或非静态属性 非静态方法
*
*   属性可以赋值的位置
*   1.默认初始化
*   2.显示初始化
*   3.构造器中初始化
*   4.有了对象以后 可以对象.属性 对象.方法进行初始化
*   5.代码块中赋值
*   赋值顺序 1--> 2/5--> 3 -->4
*
* 五  final关键字 最终的
*  final 可以修饰的结构  类 方法 变量
*
*  final修饰一个类 此类不能够在继承
*   比如 String System
*
*  final修饰一个方法 表明方法不可以被重写
*    比如 object.getClass()
*
*  final可以用来修饰变量  此时的变量就是常量了
     final修饰属性 可以考虑赋值的位置有 显示初始化 代码块中 构造器中
     final修饰属性 修饰局部变量
        尤其是final修饰形参时,表明形参是一个常量,当我们调用此方法时给常量形参赋一个实参
        一但赋值以后,就只能在方法体内使用形参,但不能重新赋值
     static final:用来修饰属性 全局常量
     static final:用来修饰方法 不能被继承


* */
public class test1 {
    public static void main(String[] args) {
        Chinese c1=new Chinese("zs",18);
        Chinese c2=new Chinese("ls",22);
        c1.nation="中国";

        System.out.println(c2.nation);
        System.out.println("-----------单例设计模式饿汉式-------");
        Bank bank1=Bank.getInstance();
        Bank bank2=Bank.getInstance();
        System.out.println(bank1==bank2);
        System.out.println("-----------代码块-------");

        System.out.println(Chinese.desc);
        System.out.println(c2.language);

    }
}
class Chinese{
    String name;
    int age;
    String language;
    final  int width=10;
    final  int left;
    final  int right;
    static  String nation;
    static  String desc="我是一个人";
    Chinese(){
        right=100;
    }
    Chinese( String name, int age){
        this.age=age;
        this.name=name;
        right=100;

    }

    public  static  void show(){
        System.out.println("show执行");
        //name="tom";无法从静态上下文中引用非静态 变量
        nation="中国";//可以调用静态结构
    }
    //代码块
    {
        System.out.println("代码块");
        language="汉语";
        show();
        left=100;
    }
    static {
        System.out.println("静态代码块");
        desc="我是一个中国人";
        show();
    }
}
//饿汉式
 class Bank{
    //私有化类的构造器
     private  Bank(){}
     //内部创建类的对象(要求此对象必须为静态的)
     private  static  Bank instance=new Bank();

     //通过公共的静态对象 返回类的对象
     public  static  Bank getInstance(){
         return  instance;
     }
 }
 //饿汉式
 class Change{
    private  Change(){}
    //声明当前类对象,没有初始化
    private   static  Change instance =null;
    //声明public static的返回当前类对象方法
    public  static Change getInstance(){
        if (instance==null){
            instance= new Change();
      }
    return  instance;
}

 }

// class  C extends  String{} 不能继承

//class A{  不能重写
// final public  void  show(){}
//}
//class  B extends  A{
//    public  void  show(){}
//}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/70872.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue.js设计与实现,读书笔记第一章

第一章&#xff1a;权衡的艺术 1.1命令式和声明式 jq是命令式,关注过程&#xff0c;jq针对简化dom 而产生的 vue是 声明式&#xff0c;关注实现&#xff0c;不严格地说就像是在命令式(关注过程)基础上再对标签进行了一次封装&#xff08;关注实现&#xff09; jQuery命令式…

干货 | Jmeter 如何保证抢购、秒杀活动正常运行?

1. 前言 平常为了保证运营促销、抽奖活动能正常运行&#xff0c;我们一般都需要使用 Jmeter、LoadRunner 对接口进行压力测试 使用它可以模拟一定量的用户同时去参与促销抽奖活动&#xff0c;最后生成测试报告&#xff0c;以此判系统接口的稳定性 本篇文章以抢购商品为例&am…

清华毕业大佬用了一个项目就把SpringMVC+Spring+MyBatis给讲完了

前言 时间飞逝&#xff0c;转眼间毕业七年多&#xff0c;从事 Java 开发也六年了。我在想&#xff0c;也是时候将自己的 Java 整理成一套体系。 这一次的知识体系面试题涉及到 Java 知识部分、性能优化、微服务、并发编程、开源框架、分布式等多个方面的知识点。 写这一套 Ja…

R语言学习笔记——入门篇:第五章-高级数据管理

R语言 R语言学习笔记——入门篇&#xff1a;第五章-高级数据管理 文章目录R语言一、数值与字符处理函数1.1、数学函数1.2、统计函数1.3、概率函数1.4、字符处理函数1.5、其他实用函数1.6、将函数应用于矩阵与数据框二、控制流2.1、循环&#xff08;for&#xff0c;while&#…

从零开始带你实现一套自己的CI/CD(三)Jenkins+Harbor

目录一、简介二、安装Harbor2.1 Amd64架构安装Harbor2.2 Arm64架构安装Harbor找不到make命令找不到git命令执行make download和make compile_redis失败执行make compile_redis命令执行make prepare_arm_data命令执行make pre_update命令执行make compile COMPILETAGcompile_gol…

【OpenCV-Python】教程:4-4 SIFT 介绍

OpenCV Python SIFT (尺度不变特征变换) 【目标】 SIFT算法SIFT特征点和描述子 【理论】 前面的章节中&#xff0c;我们提到了角点检测&#xff0c;例如Harris角点&#xff0c;他们是旋转不变的&#xff0c;因为&#xff0c;图像无论如何旋转&#xff0c;其角点特性不会发生…

世界杯8强盘点

2022年卡塔尔世界杯&#xff08;英语&#xff1a;FIFA World Cup Qatar 2022&#xff09;是第二十二届世界杯足球赛&#xff0c;是历史上首次在卡塔尔和中东国家境内举行、也是第二次在亚洲举行的世界杯足球赛。除此之外&#xff0c;卡塔尔世界杯还是首次在北半球冬季举行、首次…

docker(八)compose

compose 一 简介&#xff1a; 通过前面几篇文章&#xff0c;我们了解了docker的基本知识&#xff0c;docker帮我们解决了服务打包安装的问题&#xff0c;但是随着服务的不断增多带来了如下问题&#xff1a; 多次使用Dockerfile Build Image或者DockerHub拉取Image;需要创建多…

Spark 动态资源分配参数与源码原理分析

1.1.1、Dynamic Allocation 1.1.1.1 参数说明 1.2 版本 参数名及默认值含义spark.dynamicAllocation.enabled false是否开启动态资源分配&#xff0c;主要是基于集群负载分配executorspark.dynamicAllocation.executorIdleTimeout60sexecutor空闲时间达到规定值&#xff0c…

程序人生:化解互联网 “寒冬” 危机,我教你摆脱困境

三年反复的yi情&#xff0c;近20年史无前例的互联网裁员潮汹涌而至。 寒冬来袭&#xff0c;每一个职场打工人&#xff0c;都感到了寒意。 互联网企业大裁员的底层逻辑&#xff0c;一方面是受宏观环境影响&#xff08;yq、互联网红利结束、政策变化等&#xff09;&#xff0c;…

ChatGPT震撼上市,AI也开始跟你卷了,来一起看看怎么用ChatGPT!!!

强大AI产品&#xff0c;ChatGPT震撼上市&#xff0c;程序员真的要失业了吗&#xff1f; 最近聊天机器人异常火爆&#xff0c;火爆到什么程度&#xff0c;卖个关子&#xff0c;下文解释。 OpenAI推出了ChatGPT&#xff0c;它能够回答各种各样的问题&#xff0c;包括生成代码&a…

Node.js学习下(70th)

一、Buffer 缓冲区 背景 1、浏览器没有储存图片文件等媒体文件的需求&#xff0c;JS 存的都是一些基本数据类型。 2、服务器需要存储图片/视频/音频等媒体文件&#xff0c;因此有了 Buffer 缓冲器。 1. Buffer 是什么 Buffer 是一个和数组类似的对象&#xff0c;不同是 Buf…

python代码学习1

\n 换行符号 \r 回车 \b 后退一个格 \t 制表符&#xff08;4个字符为一组&#xff0c;当不字符被占有时&#xff0c;重新生成一个制表符。如果被占据&#xff0c;不满4个字符时&#xff0c;生成剩余部分空格。&#xff09; #原字符 不希望字符串中转义字符起作用&#xff0…

FME Server 无代码环境中自动化您数据和应用集成工作流

专为现代企业打造 简化数据和应用程序集成&#xff0c;让您的数据为您所用。在FME Desktop中创作工作流&#xff0c;并使用 FME Server 将其自动化&#xff0c;以按计划或响应事件运行数据集成。 构建无代码 Web 应用程序&#xff0c;提供自助式数据提交和验证&#xff0c;并向…

Java学习之动态绑定机制

目录 举例说明 父类 子类 main类 运行结果 ​编辑 动态绑定 举例说明 父类 子类 main类 分析 运行结果 Java重要特性&#xff1a;动态绑定机制&#xff08;非常重要&#xff09; 举例说明 父类 class A {//父类public int i 10;public int sum() {return getI(…

2022年11月国产数据库大事记-墨天轮

本文为墨天轮社区整理的2022年11月国产数据库大事件和重要产品发布消息。 文章目录11月国产数据库大事记&#xff08;时间线&#xff09;产品/版本发布兼容认证排行榜新增数据库11月国产数据库大事记&#xff08;时间线&#xff09; 11月1日&#xff0c;国际知名研究机构 IDC …

什么是内存对齐

内存对齐 什么是内存对齐为什么要内存对齐内存对齐的规则结构体中内存对齐 sizeof无嵌套有嵌套 iOS中对象内存对齐 iOS中获取内存大小方式 class_getInstanceSize()malloc_size() iOS中内存对齐 实际占用内存对齐方式系统分配内存对齐方式问题 内存优化 总结 内存对齐 什么…

基于C++的AGV机器人无线控制

1 AGV系统概述 1.1AGV原理 AGV行走控制系统由控制面板、导向传感器、方向电位器、状态指示灯、避障传感器、光电控制信号传感器、驱动单元、导引磁条、电源组成。 AGV的导引&#xff08;Guidance&#xff09;是指根据AGV导向传感器&#xff08;Navigation&#xff09;所得到…

基于FFmpeg进行rtsp推流及拉流(详细教程)

目录 1.1 Windows系统 1.2 Ubuntu 和 Debian 系统 1.3 CentOS 和 Fedora 系统 1.4 macOS系统 2. 安装rtsp-simple-server 3. FFmpeg推流 3.1 UDP推流 3.2 TCP推流 3.3 循环推流 4 拉流 4.1 ffplay/VLC拉流显示 4.2 FFmpeg拉流保存成视频 1. 安装FFmpeg FFmpeg 是一…

tftp服务/nfs服务/二进制工具集/uboot基础

一、什么是系统移植 1&#xff09;系统移植就是给开发板搭建一个linux操作系统 2&#xff09;从官方获取源码&#xff0c;进行配置和编译&#xff0c;生成板子需要的镜像文件 二、为什么系统移植 1&#xff09;为后面学习驱动开发课程打基础 2&#xff09;驱动开发工程师必…