>>分享Java编程技术,对《Java面向对象编程》等书籍提供技术支持 书籍支持  卫琴直播  品书摘要  在线测试  资源下载  联系我们
发表一个新主题 开启一个新投票 回复文章 您是本文章第 27233 个阅读者 刷新本主题
 * 贴子主题:  面试必考-static、final和单例模式 回复文章 点赞(0)  收藏  
作者:sunshine    发表时间:2020-03-08 15:40:28     消息  查看  搜索  好友  邮件  复制  引用

                                                                                                

面试必考-static、final和单例模式

     static

     那天我朋友问了我个问题,static和单例模式有什么区别,所以我觉得static可以讲一下

     他的问题是,把对象弄成static是不是就不变了

     显然,这是还没弄清楚引用和对象的区别

     点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

      其实存放在静态区中的是引用,而不是对象。而对象是存放在堆中的。如果有这样一句话

                   public static final Book   book =   new Book();

      意思就是book这个引用,指向了这个new出来的对象。

     static的引用和正常的引用有什么区别?

     当你加载了这个类的时候(第一次使用这个类的时候会加载这个类到jvm),这个static引用会率先被加载。所以,当我们第一次调用Book.book的时候,这个静态的book引用就会一直存放在静态区里了(当fullGC回收整个类才会销毁这个引用)。

     而正常的引用,只能通过new出一个对象后才能使用,所以当对象被回收了,这个引用自然也回收了(而且非静态引用如果是方法中的引用,会存放在函数的栈里;如果是对象的引用,会和对象一起存放在heap里)。

     final

     final定义了之后,你就必须在一开始就需要赋值,所以上面那行代码就必须在一开始就赋值。而如果你想延迟加载,提高性能,那么就不可以用final。

     单例模式

     单例模式是如果实现的,就是通过调用这个类里的一个静态方法,弄一个if语句判断一下,如果有实例了,就返回这个实例,如果没有,就创建这个实例。其实并没有多大的技术含量。

     第一种,最基本的思维。

public class Book {
     private static Book  book =   new Book();
     private Book() {}
     public static Book getInstance() {
         if ( book ==   null) {
             book =   new Book();
        }
         return book;
    }
}

              这里为什么要判空呢?因为你这个是静态的,所以其他地方完全有Book.getInstance = null;的可能。

                 第二种,这里使用final,让引用的指向不可变,这样就不需要判空了

public class Book {
     private static final Book   book =   new Book();
     private Book() {}
     public static Book getInstance() {
         return book;
    }
}

                  第三种,延迟加载(线程不安全,假如有多个同时发现是空的,会创建出好多实例)

public class Book {
     private static Book  book;
     private Book() {}
     public static Book getInstance() {
         if ( book ==   null) {
             book =   new Book();
        }
         return book;
    }
}

                  第四种,添加线程安全功能,加一个关键字就可以

public class Book {
     private static Book  book;
     private Book() {}
     public static synchronized Book getInstance() {
         if ( book ==   null) {
             book =   new Book();
        }
         return book;
    }
}
这个方法在多线程下的工作表现很出色

                               第五种,规避不需要的同步,因为上面的同步范围太大,有点浪费性能,在引用有指向的时候,是不需要同步的
public class Book {
     private static Book  book;
     private Book() {}
     public static synchronized Book getInstance() {
         if ( book ==   null) {
             synchronized (Book. class) {
                 book =   new Book();
            }
        }
         return book;
    }
}

                  第六种,静态内部类

public class Book {
     private Book() {}
     public static synchronized Book getInstance() {
         return BookHolder. book;
    }
     private static class BookHolder {
         private static final Book   book =   new Book();
    }
}

                  第七种,枚举单例

public class Book {
     private Book(){}
     public static Book getInstance() {
         return BookEnum. BOOK.getInstance();
    }

     private static enum BookEnum {
         BOOK;
         private Book   book;
         private BookEnum() {
             book =   new Book();
        }
         public Book getInstance() {
             return book;
        }
    }
}
最优,但是枚举这个东西可读性不高

具体选择什么,看情况

                                                                                                        
----------------------------
原文链接:https://blog.csdn.net/qq_36523667/article/details/79014324

程序猿的技术大观园:www.javathinker.net



[这个贴子最后由 flybird 在 2020-03-08 23:21:56 重新编辑]
  Java面向对象编程-->继承
  JavaWeb开发-->自定义JSP标签(Ⅰ)
  JSP与Hibernate开发-->数据库事务的并发问题的解决方案
  Java网络编程-->通过JDBC API访问数据库
  精通Spring-->CSS过渡和动画
  Vue3开发-->组合(Composition)API
  JAVA锁相关知识总结
  HashMap中 get 和 put 操作的具体过程
  java万年历简单制作
  小数在内存中是如何存储的?
  java常见的几种调用机制:同步调用,异步调用,回调
  Java多线程volatile详解
  JNI_Java Native Interface的用法
  Eclipse使用指南:工作空间(Workspace)
  Java入门实用代码:压栈出栈的方法实现字符串反转
  Java入门实用代码:链表元素查找
  Java 入门实用代码:取最大和最小值
  Java入门实用代码:查找字符串最后一次出现的位置
  java Pattern和Matcher详解
  Java程序代码优化技巧
  JDBC使用8.0驱动包连接mysql设置时区serverTimezone
  更多...
 IPIP: 已设置保密
树形列表:   
1页 0条记录 当前第1
发表一个新主题 开启一个新投票 回复文章


中文版权所有: JavaThinker技术网站 Copyright 2016-2026 沪ICP备16029593号-2
荟萃Java程序员智慧的结晶,分享交流Java前沿技术。  联系我们
如有技术文章涉及侵权,请与本站管理员联系。