Java面试要点06 - static关键字、静态属性与静态方法

news2024/11/24 17:44:45

在这里插入图片描述

本文目录

    • 一、引言
    • 二、静态属性(Static Fields)
    • 三、静态方法(Static Methods)
    • 四、静态代码块(Static Blocks)
    • 五、静态内部类(Static Nested Classes)
    • 六、静态导入(Static Import)
    • 七、最佳实践与注意事项
    • 八、总结


一、引言

在Java中,static关键字用于声明属于类层面的成员,而不是实例层面的成员。static成员在类加载时就会被初始化,并且被该类的所有实例所共享。深入理解static关键字的使用对于编写高效的Java代码和设计良好的类结构至关重要。本文将详细探讨static关键字在不同场景下的使用方法和注意事项。

二、静态属性(Static Fields)

静态属性属于类而不是实例,所有实例共享同一个静态属性。这使得静态属性成为实现计数器、缓存和常量等功能的理想选择。

public class StaticFieldExample {
    // 静态常量
    public static final String COMPANY_NAME = "TechCorp";
    
    // 静态变量作为计数器
    private static int instanceCount = 0;
    
    // 实例变量
    private String name;
    
    // 静态变量用于缓存
    private static final Map<String, StaticFieldExample> cache = new HashMap<>();
    
    public StaticFieldExample(String name) {
        this.name = name;
        instanceCount++;  // 记录实例创建次数
    }
    
    // 获取创建的实例数量
    public static int getInstanceCount() {
        return instanceCount;
    }
    
    // 使用缓存的工厂方法
    public static StaticFieldExample getInstance(String name) {
        return cache.computeIfAbsent(name, StaticFieldExample::new);
    }
    
    // 演示静态属性的共享特性
    public static void main(String[] args) {
        System.out.println("初始实例数: " + getInstanceCount());
        
        StaticFieldExample obj1 = new StaticFieldExample("Instance 1");
        System.out.println("创建第一个实例后: " + getInstanceCount());
        
        StaticFieldExample obj2 = new StaticFieldExample("Instance 2");
        System.out.println("创建第二个实例后: " + getInstanceCount());
    }
}

三、静态方法(Static Methods)

静态方法不需要创建类的实例就可以调用,它们通常用于实现工具方法或工厂方法。静态方法不能访问非静态成员,因为它们不属于任何实例。

public class StaticMethodExample {
    private int instanceValue;
    private static int staticValue = 0;
    
    // 静态工具方法
    public static int calculateSum(int[] numbers) {
        int sum = 0;
        for (int number : numbers) {
            sum += number;
        }
        return sum;
    }
    
    // 静态工厂方法
    public static StaticMethodExample createInstance() {
        StaticMethodExample instance = new StaticMethodExample();
        instance.instanceValue = ++staticValue;
        return instance;
    }
    
    // 错误示例:静态方法不能访问非静态成员
    /*
    public static void incorrectMethod() {
        System.out.println(instanceValue); // 编译错误
    }
    */
    
    // 正确示例:静态方法访问静态成员
    public static void correctMethod() {
        System.out.println(staticValue);
    }
    
    // 实例方法可以访问静态成员
    public void instanceMethod() {
        System.out.println("Static value: " + staticValue);
        System.out.println("Instance value: " + instanceValue);
    }
}

// 静态方法的使用示例
class StaticMethodDemo {
    public static void main(String[] args) {
        // 直接通过类名调用静态方法
        int[] numbers = {1, 2, 3, 4, 5};
        int sum = StaticMethodExample.calculateSum(numbers);
        System.out.println("Sum: " + sum);
        
        // 使用静态工厂方法创建实例
        StaticMethodExample instance1 = StaticMethodExample.createInstance();
        StaticMethodExample instance2 = StaticMethodExample.createInstance();
    }
}

四、静态代码块(Static Blocks)

静态代码块用于类的初始化,它在类加载时执行,且只执行一次。这使得它成为初始化静态资源的理想场所。

public class StaticBlockExample {
    private static Map<String, String> configMap;
    
    // 静态代码块
    static {
        System.out.println("静态代码块执行");
        configMap = new HashMap<>();
        loadConfig();
    }
    
    // 第二个静态代码块(按声明顺序执行)
    static {
        System.out.println("第二个静态代码块执行");
        configMap.put("version", "1.0");
    }
    
    private static void loadConfig() {
        configMap.put("name", "MyApp");
        configMap.put("author", "Developer");
    }
    
    // 获取配置值
    public static String getConfig(String key) {
        return configMap.get(key);
    }
    
    public static void main(String[] args) {
        System.out.println("应用名称: " + getConfig("name"));
        System.out.println("版本: " + getConfig("version"));
    }
}

五、静态内部类(Static Nested Classes)

静态内部类是一种特殊的嵌套类,它不持有外部类的引用,可以独立于外部类的实例而存在。

public class StaticNestedClassExample {
    private static String outerStaticField = "Outer Static";
    private String outerInstanceField = "Outer Instance";
    
    // 静态内部类
    public static class StaticInner {
        private String innerField;
        
        public StaticInner(String value) {
            this.innerField = value;
        }
        
        public void printInfo() {
            // 可以访问外部类的静态成员
            System.out.println("Outer static field: " + outerStaticField);
            // 不能直接访问外部类的实例成员
            // System.out.println(outerInstanceField); // 编译错误
        }
    }
    
    // 内部类的使用示例
    public static void main(String[] args) {
        // 创建静态内部类实例不需要外部类实例
        StaticInner inner = new StaticInner("Inner Value");
        inner.printInfo();
    }
}

六、静态导入(Static Import)

静态导入允许我们直接使用静态成员,而不需要类名限定。虽然方便,但过度使用可能导致代码可读性降低。

import static java.lang.Math.PI;
import static java.lang.Math.max;
import static java.lang.System.out;

public class StaticImportExample {
    public static void main(String[] args) {
        // 使用静态导入的成员
        out.println("PI value: " + PI);
        out.println("Max of 10 and 20: " + max(10, 20));
        
        // 不使用静态导入的写法
        System.out.println("Regular import: " + Math.PI);
    }
}

七、最佳实践与注意事项

在使用static关键字时,需要注意一些重要的最佳实践和潜在问题:

  1. 静态成员的内存考虑:
public class StaticMemoryExample {
    // 注意:静态成员会一直占用内存
    private static final List<String> cache = new ArrayList<>();
    
    // 建议提供清理方法
    public static void clearCache() {
        cache.clear();
    }
}
  1. 线程安全考虑:
public class StaticThreadSafetyExample {
    // 静态成员在多线程环境下需要同步
    private static int counter = 0;
    
    // 线程安全的计数方法
    public static synchronized void incrementCounter() {
        counter++;
    }
    
    // 使用原子类型保证线程安全
    private static final AtomicInteger atomicCounter = new AtomicInteger(0);
    
    public static void safeIncrement() {
        atomicCounter.incrementAndGet();
    }
}

八、总结

static关键字是Java语言中一个强大的特性,它使我们能够创建类级别的成员,实现工具方法,并优化内存使用。通过合理使用static关键字,我们可以实现更好的代码组织和更高的性能。然而,在使用static时需要谨慎考虑内存管理和线程安全等问题,确保在正确的场景下使用这个关键字。

今天的内容就到这里了,希望可以对你有帮助。

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

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

相关文章

【测试】【Debug】vscode pytest 找不到测试用例测试文件 行号部位没有绿色箭头

出现这种情况首先检查&#xff1a; 是否安装pytest点击vscode的这个图标如果其中都是空的&#xff0c;没有识别上&#xff0c;并且写好的.py测试文件的行号前面没有运行符号&#xff0c;要检查名称是否按照pytest的要求写&#xff0c;不然会识别不到。 命名规则注意&#xff1…

区块链技术在电子政务中的应用

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 区块链技术在电子政务中的应用 区块链技术在电子政务中的应用 区块链技术在电子政务中的应用 引言 区块链技术概述 定义与原理 发…

【Java Web】Servlet

文章目录 Servlet APIServlet生命周期Servlet配置注解配置文件全局参数 Servlet获得内置对象升级示例3 Servlet 是一种用于构建 Java 服务器端应用程序的技术&#xff0c;允许开发者创建动态的 web 内容。Servlets 在 Java 平台上运行&#xff0c;并由 Java Servlet API 提供支…

linux命令详解,存储管理相关

存储管理 一、内存使用量&#xff0c;free free 命令是一个用于显示系统中物理内存&#xff08;RAM&#xff09;和交换空间&#xff08;swap&#xff09;使用情况的工具 free -m free -m -s 5参数 -b 功能: 以字节&#xff08;bytes&#xff09;为单位显示内存使用情况。说…

流体力学ansys Fluent二次开发scheme_eval模块剖析

在ANSYS Fluent的二次开发中&#xff0c;scheme_eval 是 Scheme 编程语言中一个非常重要的模块&#xff0c;它允许用户执行动态的 Scheme 表达式和函数&#xff0c;从而扩展 Fluent 的功能。scheme_eval 模块通常与 Fluent 的计算和自定义脚本操作紧密结合。下面我们会对这个模…

中仕公考:大四在校生考公怎么规划?

还在就读的大学生&#xff0c;大三下学期就可以备考&#xff0c;大四以应届生的身份参加考试&#xff0c;中仕不建议大家把备考战线拉得太长或者太短&#xff0c;时间太长容易疲惫&#xff0c;时间太短容易备考不到位。 考公流程&#xff1a; 查看公告职位表→网上报名一资格…

【363】基于springboot的高校竞赛管理系统

摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统高校竞赛管理系统信息管理难度大&#xff0c;容错率低&am…

网站架构知识之Ansible模块(day021)

1.Ansible模块 作用:通过ansible模块实现批量管理 2.command模块与shell模块 command模块是ansible默认的模块&#xff0c;适用于执行简单的命令&#xff0c;不支持特殊符号 案列01&#xff0c;批量获取主机名 ansible all -m command -a hostname all表示对主机清单所有组…

计算机网络:网络层 —— 软件定义网络 SDN

文章目录 软件定义网络 SDN远程控制器OpenFlow协议SDN 广义转发流表简单转发负载均衡防火墙 SDN 控制器 软件定义网络 SDN 软件定义网络&#xff08;Software Defined Networking&#xff0c;SDN&#xff09;是一种新兴的网络架构&#xff0c;旨在通过网络控制与数据转发的分离…

使用 .NET Core 7 和 SignalR 构建实时聊天应用程序

动动你可爱的小手&#xff0c;请关注下本人公众号&#xff0c;继续为您提供更多原创技术文章。谢谢给为的支持 SignalR 是一个 ASP.NET 库&#xff0c;它支持实时 Web 功能&#xff0c;允许服务器立即将更新推送到客户端&#xff0c;从而提高应用程序的效率和响应能力。它通过简…

响应式网页设计--html

一&#xff0c;HTML 文档的基本结构 一个典型的 HTML 文档包含了几个主要部分&#xff0c;基本结构如下(本文以下出现的所有代码都可以套入下面示例进行测试)&#xff1a; <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8&q…

欢迎 Stable Diffusion 3.5 Large 加入 Diffusers

作为Stable Diffusion 3的改进版本&#xff0c;Stable Diffusion 3.5 如今已在 Hugging Face Hub 中可用&#xff0c;并可以直接使用 &#x1f9e8; Diffusers 中的代码运行。 https://hf.co/blog/sd3 本次发布包含两套模型参数: https://hf.co/collections/stabilityai/stable…

Ubuntu22.04中使用CMake配置运行boost库示例程序

Ubuntu22.04中使用CMake配置运行boost库示例程序 boost是一个比较强大的C准标准库&#xff0c;里面有很多值得学习的东西&#xff0c;比较asio网络库可以用来编写C TCP客户端或者TCP服务端接收程序。本文主要讲解如何在Ubuntu22.04中使用Cmake配置boost库&#xff0c;以及运行…

高效档案管理案例介绍:文档内容批量结构化解决方案解析

一、项目背景介绍 档案文件中包含的内容丰富且形式多样&#xff0c;通常不仅包括文本&#xff0c;还可能包含表格、图片、标题、段落、注释等多种内容元素。传统的档案管理往往依赖人工对文档内容进行归档、分类和标注&#xff0c;这种方式耗时费力&#xff0c;且在管理庞大数…

如何在vscode中安装git详细新手教程

一、安装git后点击vscode中的设置 今天教大家如何在VScode中编写代码后提交到git仓库&#xff0c;如果我们不想切换到git的命令行窗口&#xff0c;可以在VScode中配置git&#xff0c;然后就可以很方便快捷的把代码提交到仓库中。 二、在输入框中输入 git.path &#xff0c;再点…

负梯度方法与Newton型方法-数值最优化方法-课程学习笔记-4

今天我们继续来学习数值最优化方法的第三章内容的后续知识 Newton方法 Newton方法是Newton方法的基础, 本节主要讨论的是基本Newton方法, 阻尼Newton方法以及修正Newton方法的构造和特性, 这类方法适合解决中小型最优化问题 基本Newton方法 对于 f ( x ) f(x) f(x)如果有连续…

element-plus的Tree 树形控件添加图标

该文章为本菜鸡学习记录&#xff0c;如有错误还请大佬指教 本人刚开始接触vue框架&#xff0c;在使用element-plus组件想实现树形控件&#xff0c;发现官网的组件示例没有图标区分显示 实现效果 代码 <temple 部分 <el-tree :data"data" node-click"hand…

Visual Studio Code从安装到正常使用

Visual Studio Code的汉化 下载的Visual Studio Code的话可以去应用商店也可以去官网下载。 Visual Studio Code只是一个编译器&#xff0c;不具备编译器功能。因此需要下载一个编译器MinGW MinGW的安装 官网链接MinGW官网链接 一步到位的链接 添加环境变量 进入cmd界面…

netty之关闭连接源码分析

写在前面 本文看下netty关闭channel相关源码。 1&#xff1a;前置准备 为了测试&#xff0c;我们需要使用netty源码中examples模块的echoserver和echoclient&#xff0c;但是echoclient因为会不断的发送消息&#xff0c;并不会断开连接&#xff0c;所以&#xff0c;我们需要…

Linux(CentOS)yum update -y 事故

CentOS版本&#xff1a;CentOS 7 事情经过&#xff1a; 1、安装好CentOS 7&#xff0c;系统自带JDK8&#xff0c;版本为&#xff1a;1.8.0_181 2、安装好JDK17&#xff0c;版本为&#xff1a;17.0.13 3、为了安装MySQL执行了 yum update -y&#xff08;这个时候不知道该命令的…