精华内容
下载资源
问答
  • 深入理解Java中的可变对象

    千次阅读 2020-03-20 10:49:23
    二哥,你能给我说说为什么 String 是 immutable 类(可变对象)吗?我想研究它,想知道为什么它就可变了,这种强烈的愿望就像想研究浩瀚的星空一样。但无奈自身功力有限,始终觉得雾里看花终隔一层。二哥你的...

    二哥,你能给我说说为什么 String 是 immutable 类(不可变对象)吗?我想研究它,想知道为什么它就不可变了,这种强烈的愿望就像想研究浩瀚的星空一样。但无奈自身功力有限,始终觉得雾里看花终隔一层。二哥你的文章总是充满趣味性,我想一定能够说明白,我也一定能够看明白,能在接下来写一写吗?

    收到读者小 R 的私信后,我就总感觉自己有一种义不容辞的责任,非要把 immutable 类说明白,否则我就怎么地——你说了算!

    01、什么是不可变类

    一个类的对象在通过构造方法创建后如果状态不会再被改变,那么它就是一个不可变(immutable)类。它的所有成员变量的赋值仅在构造方法中完成,不会提供任何 setter 方法供外部类去修改。

    还记得《神雕侠侣》中小龙女的古墓吗?随着那一声巨响,仅有的通道就被无情地关闭了。别较真那个密道,我这么说只是为了打开你的想象力,让你对不可变类有一个更直观的印象。

    自从有了多线程,生产力就被无限地放大了,所有的程序员都爱它,因为强大的硬件能力被充分地利用了。但与此同时,所有的程序员都对它心生忌惮,因为一不小心,多线程就会把对象的状态变得混乱不堪。

    为了保护状态的原子性、可见性、有序性,我们程序员可以说是竭尽所能。其中,synchronized(同步)关键字是最简单最入门的一种解决方案。

    假如说类是不可变的,那么对象的状态就也是不可变的。这样的话,每次修改对象的状态,就会产生一个新的对象供不同的线程使用,我们程序员就不必再担心并发问题了。

    02、常见的不可变类

    提到不可变类,几乎所有的程序员第一个想到的,就是 String 类。那为什么 String 类要被设计成不可变的呢?

    1)常量池的需要

    字符串常量池是 Java 堆内存中一个特殊的存储区域,当创建一个 String 对象时,假如此字符串在常量池中不存在,那么就创建一个;假如已经存,就不会再创建了,而是直接引用已经存在的对象。这样做能够减少 JVM 的内存开销,提高效率。

    2)hashCode 的需要

    因为字符串是不可变的,所以在它创建的时候,其 hashCode 就被缓存了,因此非常适合作为哈希值(比如说作为 HashMap 的键),多次调用只返回同一个值,来提高效率。

    3)线程安全

    就像之前说的那样,如果对象的状态是可变的,那么在多线程环境下,就很容易造成不可预期的结果。而 String 是不可变的,就可以在多个线程之间共享,不需要同步处理。

    因此,当我们调用 String 类的任何方法(比如说 trim()substring()toLowerCase())时,总会返回一个新的对象,而不影响之前的值。

    String cmower = "沉默王二,一枚有趣的程序员";
    cmower.substring(0,4);
    System.out.println(cmower);// 沉默王二,一枚有趣的程序员
    

    虽然调用 substring() 方法对 cmower 进行了截取,但 cmower 的值没有改变。

    除了 String 类,包装器类 Integer、Long 等也是不可变类。

    03、自定义不可变类

    看懂一个不可变类也许容易,但要创建一个自定义的不可变类恐怕就有点难了。但知难而进是我们作为一名优秀的程序员不可或缺的品质,正因为不容易,我们才能真正地掌握它。

    接下来,就请和我一起,来自定义一个不可变类吧。一个不可变诶,必须要满足以下 4 个条件:

    1)确保类是 final 的,不允许被其他类继承。

    2)确保所有的成员变量(字段)是 final 的,这样的话,它们就只能在构造方法中初始化值,并且不会在随后被修改。

    3)不要提供任何 setter 方法。

    4)如果要修改类的状态,必须返回一个新的对象。

    按照以上条件,我们来自定义一个简单的不可变类 Writer。

    public final class Writer {
        private final String name;
        private final int age;
    
        public Writer(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        public int getAge() {
            return age;
        }
    
        public String getName() {
            return name;
        }
    }
    

    Writer 类是 final 的,name 和 age 也是 final 的,没有 setter 方法。

    OK,据说这个作者分享了很多博客,广受读者的喜爱,因此某某出版社找他写了一本书(Book)。Book 类是这样定义的:

    public class Book {
        private String name;
        private int price;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getPrice() {
            return price;
        }
    
        public void setPrice(int price) {
            this.price = price;
        }
    
        @Override
        public String toString() {
            return "Book{" +
                    "name='" + name + '\'' +
                    ", price=" + price +
                    '}';
        }
    }
    

    2 个字段,分别是 name 和 price,以及 getter 和 setter,重写后的 toString() 方法。然后,在 Writer 类中追加一个可变对象字段 book。

    public final class Writer {
        private final String name;
        private final int age;
        private final Book book;
    
        public Writer(String name, int age, Book book) {
            this.name = name;
            this.age = age;
            this.book = book;
        }
    
        public int getAge() {
            return age;
        }
    
        public String getName() {
            return name;
        }
    
        public Book getBook() {
            return book;
        }
    }
    

    并在构造方法中追加了 Book 参数,以及 Book 的 getter 方法。

    完成以上工作后,我们来新建一个测试类,看看 Writer 类的状态是否真的不可变。

    public class WriterDemo {
        public static void main(String[] args) {
            Book book = new Book();
            book.setName("Web全栈开发进阶之路");
            book.setPrice(79);
    
            Writer writer = new Writer("沉默王二",18, book);
            System.out.println("定价:" + writer.getBook());
            writer.getBook().setPrice(59);
            System.out.println("促销价:" + writer.getBook());
        }
    }
    

    程序输出的结果如下所示:

    定价:Book{name='Web全栈开发进阶之路', price=79}
    促销价:Book{name='Web全栈开发进阶之路', price=59}
    

    糟糕,Writer 类的不可变性被破坏了,价格发生了变化。为了解决这个问题,我们需要为不可变类的定义规则追加一条内容:

    如果一个不可变类中包含了可变类的对象,那么就需要确保返回的是可变对象的副本。也就是说,Writer 类中的 getBook() 方法应该修改为:

    public Book getBook() {
        Book clone = new Book();
        clone.setPrice(this.book.getPrice());
        clone.setName(this.book.getName());
        return clone;
    }
    

    这样的话,构造方法初始化后的 Book 对象就不会再被修改了。此时,运行 WriterDemo,就会发现价格不再发生变化了。

    定价:Book{name='Web全栈开发进阶之路', price=79}
    促销价:Book{name='Web全栈开发进阶之路', price=79}
    

    04、总结

    不可变类有很多优点,就像之前提到的 String 类那样,尤其是在多线程环境下,它非常的安全。尽管每次修改都会创建一个新的对象,增加了内存的消耗,但这个缺点相比它带来的优点,显然是微不足道的——无非就是捡了西瓜,丢了芝麻。

    最后,一定会有不少读者想要问我怎么学习 Java 的,那我干脆就把我看过的优质书籍贡献出来:

    1)入门版:《Head First Java》、《Java 核心技术卷》

    2)进阶版:《Java编程思想》、《Effective Java》、《Java网络编程》、《代码整洁之道》

    3)大牛版:《Java并发编程》、《深入理解Java虚拟机》、《Java性能权威指南》、《重构》、《算法》

    就先介绍这么多,希望对那些不知道看什么书的同学有所帮助。

    对了,我介绍的这些书籍,已经顺便帮你整理好了,你可以在我的原创微信公众号『沉默王二』回复『书籍』获取哦

    有收获?希望老铁们来个三连击,给更多的同学看到这篇文章

    1、老铁们,关注我的原创微信公众号「沉默王二」,专注于有趣有益的程序人生,保证你看完有所收获,不信你打我。

    2、给二哥点个赞呗,可以让更多的人看到这篇文章,顺便激励下我,嘻嘻。

    作者info
    作者:沉默王二,CSDN 2019年度博客之星,《Web全栈开发进阶之路》作者
    原创公众号:『沉默王二』,已写了 250 多篇文章,专注于有趣的 Java 技术和有益的程序人生,期待你的关注。
    转载说明:务必注明来源(注明:来源于公众号:沉默王二, 作者:沉默王二)

    展开全文
  • 一、是什么BOM (Browser Object Model),浏览器对象模型,提供了独立于内容与浏览器窗口进行交互的对象其作用就是跟浏览器做一些交互效果,比如如何进行页面的后退,前进,刷...

    一、是什么

    BOM (Browser Object Model),浏览器对象模型,提供了独立于内容与浏览器窗口进行交互的对象

    其作用就是跟浏览器做一些交互效果,比如如何进行页面的后退,前进,刷新,浏览器的窗口发生变化,滚动条的滚动,以及获取客户的一些信息如:浏览器品牌版本,屏幕分辨率

    浏览器的全部内容可以看成DOM,整个浏览器可以看成BOM。区别如下:

    二、window

    Bom的核心对象是window,它表示浏览器的一个实例

    在浏览器中,window对象有双重角色,即是浏览器窗口的一个接口,又是全局对象

    因此所有在全局作用域中声明的变量、函数都会变成window对象的属性和方法

    var name = 'js每日一题';
    function lookName(){
      alert(this.name);
    }
    
    console.log(window.name);  //js每日一题
    lookName();                //js每日一题
    window.lookName();         //js每日一题
    

    关于窗口控制方法如下:

    • moveBy(x,y):从当前位置水平移动窗体x个像素,垂直移动窗体y个像素,x为负数,将向左移动窗体,y为负数,将向上移动窗体

    • moveTo(x,y):移动窗体左上角到相对于屏幕左上角的(x,y)点

    • resizeBy(w,h):相对窗体当前的大小,宽度调整w个像素,高度调整h个像素。如果参数为负值,将缩小窗体,反之扩大窗体

    • resizeTo(w,h):把窗体宽度调整为w个像素,高度调整为h个像素

    • scrollTo(x,y):如果有滚动条,将横向滚动条移动到相对于窗体宽度为x个像素的位置,将纵向滚动条移动到相对于窗体高度为y个像素的位置

    • scrollBy(x,y):如果有滚动条,将横向滚动条向左移动x个像素,将纵向滚动条向下移动y个像素

    window.open() 既可以导航到一个特定的url,也可以打开一个新的浏览器窗口

    如果 window.open() 传递了第二个参数,且该参数是已有窗口或者框架的名称,那么就会在目标窗口加载第一个参数指定的URL

    window.open('htttp://www.vue3js.cn','topFrame')
    ==> <a href="http://www.vue3js.cn" target="topFrame"></a>
    

    window.open() 会返回新窗口的引用,也就是新窗口的 window 对象

    const myWin = window.open('http://www.vue3js.cn','myWin')
    

    window.close() 仅用于通过 window.open() 打开的窗口

    新创建的 window 对象有一个 opener 属性,该属性指向打开他的原始窗口对象

    三、location

    url地址如下:

    http://foouser:barpassword@www.wrox.com:80/WileyCDA/?q=javascript#contents
    

    location属性描述如下:

    属性名例子说明
    hash"#contents"utl中#后面的字符,没有则返回空串
    hostwww.wrox.com:80服务器名称和端口号
    hostnamewww.wrox.com域名,不带端口号
    hrefhttp://www.wrox.com:80/WileyCDA/?q=javascript#contents完整url
    pathname"/WileyCDA/"服务器下面的文件路径
    port80url的端口号,没有则为空
    protocolhttp:使用的协议
    search?q=javascripturl的查询字符串,通常为?后面的内容

    除了 hash之外,只要修改location的一个属性,就会导致页面重新加载新URL

    location.reload(),此方法可以重新刷新当前页面。这个方法会根据最有效的方式刷新页面,如果页面自上一次请求以来没有改变过,页面就会从浏览器缓存中重新加载

    如果要强制从服务器中重新加载,传递一个参数true即可

    四、navigator

    navigator 对象主要用来获取浏览器的属性,区分浏览器类型。属性较多,且兼容性比较复杂

    下表列出了navigator对象接口定义的属性和方法:

    五、screen

    保存的纯粹是客户端能力信息,也就是浏览器窗口外面的客户端显示器的信息,比如像素宽度和像素高度

    六、history

    history对象主要用来操作浏览器URL的历史记录,可以通过参数向前,向后,或者向指定URL跳转

    常用的属性如下:

    • history.go()

    接收一个整数数字或者字符串参数:向最近的一个记录中包含指定字符串的页面跳转,

    history.go('maixaofei.com')
    

    当参数为整数数字的时候,正数表示向前跳转指定的页面,负数为向后跳转指定的页面

    history.go(3) //向前跳转三个记录
    history.go(-1) //向后跳转一个记录
    
    • history.forward():向前跳转一个页面

    • history.back():向后跳转一个页面

    • history.length:获取历史记录数

    --The End--

    系列正在更新:21/33

    篇副有限,扫下方二维码查看往期

    展开全文
  • 面向对象思想--谈谈你对面向对象理解

    万次阅读 多人点赞 2018-01-21 15:15:08
    面向对象可以说是对现实世界理解和抽象的方法,是计算机编程技术发展到一定阶段的产物。 它的特点:抽象 封装 继承 多态 用我的话说,其实可以这么理解,假如我是上帝,我要造 人 (这是对象)。 首先,我要...

    面向对象

    面向对象编程,即OOP,面向对象的概念和应用已经超越了程序设计、软件开发领域,现在已经发展到了各个领域。

    面向对象可以说是对现实世界理解和抽象的方法,是计算机编程技术发展到一定阶段的产物。

    它的特点:抽象  封装  继承   多态

    用我的话说,其实可以这么理解,假如我是上帝,我要造 人 (这是对象)。

    首先,我要知道人类要有哪些最基本的东西   ?

    人要有思想,人还要有肉体

    这个过程呢就是(抽象

    因为人的数量很庞大,所以我需要找别人帮我一起造人,但是我不想让他知道我造人的技术(人的脸需要用多少克泥巴,需要怎么用手去捏鼻子等等),我可以把我的造人的技术封装起来,别人只需要知道他要做什么样的人类就好了。【封装

    当我自己造人的时候,我可能造着造着就累了,我可能就要用我之前造出来的某个泥人作为模板“复制”,“粘贴

    用模板创出来的泥人具有模板的特征,就像孩子一样具有父母的性状。我们称这个过程为【继承

    但是呢  好多泥人都是我后来偷懒用模板复制出来的,为了让人类更丰富多彩一些,我对他们又进行了改变。这个过程可以叫【多态

    接下来我举个栗子来区分面向过程和面向对象

    例子:是如何将大象装进冰箱

    为了解决这个问题,我们采用两种方案,一种是面向过程方案,另一种是面向对象方案

    面向过程

    总共分三个过程,第一个过程:冰箱门打开(关着门的冰箱)     返回值是打开门的冰箱

       第二个过程:大象装进去(打开门的冰箱)     返回值是打开着门,装着大象的冰箱

                        第三个过程:冰箱门关上(打开着门,装着大象的冰箱)    返回值关着门的装着大象的冰箱

    面向对象

    总共分三个动作,(每个动作都有一个对象去执行)

      第一个动作:冰箱.开门()

      第二个动作:冰箱.装进(大象)

    第三个动作:冰箱.关门()

    或者是链式调用冰箱.开门().装进(大象).关门()


    ***********************************************************************************************************************

             完结✿✿ヽ(°▽°)ノ✿  谢谢观看~~

    展开全文
  • 谈谈你对this对象理解

    千次阅读 2019-09-23 14:50:48
    理解: 1.this是js 的一个关键字,随着函数的使用场合的不同,this 的值会发生变化。 2.一个总原则:即this指的是调用函数的那个对象。 3.一般情况下,this 是全局对象,可以作为方法调用。 转载于:...

    理解:

    1.this是js 的一个关键字,随着函数的使用场合的不同,this 的值会发生变化。

    2.一个总原则:即this指的是调用函数的那个对象。

    3.一般情况下,this 是全局对象,可以作为方法调用。

    转载于:https://www.cnblogs.com/dhpong/p/10569661.html

    展开全文
  • 谈谈我对面向对象以及类与对象理解

    千次阅读 多人点赞 2018-02-26 22:43:12
    对于刚接触JAVA或者其他面向对象编程语言的朋友们来说,可能一开始都很难理解面向对象的概念以及类和对象的关系。面向对象首先,一言和先百度,得到如下定义:一切事物皆对象,通过面向对象的方式,将现实世界的...
  • 谈谈你对面向对象理解

    万次阅读 多人点赞 2015-07-07 17:40:41
    所谓的面向对象就是将我们的程序模块化,对象化,把具体事物的特性属性和通过这些属性来实现一些动作的具体方法放到一个类里面,这就是封装。封装是我们所说的面相对象编程的特征之一。除此之外还有继承和多态。继承...
  • 系列最后一篇来说说Python中的类与对象,Python这门语言是无处不对象,如果你曾浅要了解过Python,你应该听过Python是一种面向对象编程的语言,所以你经常可能会看到面向“对象”编程这类段子,而面向对象编程的语言...
  • 在上篇文章《一篇文章全面了解Java反射机制》中我们学习了Java反射机制的基本使用,留心的朋友可能已经注意到了,在文中提到了三种获取Class对象的方法。 如果面试中涉及到Java反射,那么遇到该面试题的概率将大大...
  • 面试|能说说理解的泛型吗

    千次阅读 多人点赞 2019-07-17 02:07:43
    ,什么意思呢,就是说定义的ArrayList和ArrayList并影响到ArrayList,可以理解为一种形参和实参。 注意:参数化类型一般用单个的大写字母来表示,JDK中用“E”,"K"或者"V"等来表示参数化类型,尽量避免小写,...
  • javascript中的面向对象理解(一)

    千次阅读 2016-10-19 23:48:23
    因此,我们先复习下,传统意义上,面向对象的相关概念,以便我们后面更好的将javascript与其他语言的面向对象概念区分开来: 1.其他面向对象语言:面向对象的语言有一个标志,即拥有类(class)的概念,抽象实例对象...
  • 说说你对Java反射的理解

    千次阅读 2019-10-09 20:29:09
    对象不为空,则尝试从 ReflectionData 对象中获取declaredMethods属性。如果是第一次,或则被GC回收之后,重新初始化后的类属性为空,则需要重新到JVM中获取一次,并赋值给 ReflectionData ,下次调用就可以使用缓存...
  • Java面向对象的三大特征以及理解

    万次阅读 多人点赞 2018-05-26 16:01:36
    Java面向对象的三大特征为:封装、继承和多态,本文说说我对三大特性的理解。1.封装Java中的封装是指一个类把自己内部的实现细节进行隐藏,只暴露对外的接口(setter和getter方法)。封装又分为属性的封装和方法的...
  • 说说你对依赖注入的理解

    千次阅读 2019-07-19 22:44:36
    DI—Dependency Injection,即“依赖注入”:组件之间...通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而需要关心具体的资源来自何处,由谁实现。 ...
  • 理解什么是的面向对象设计

    千次阅读 2017-03-31 22:46:20
    现在最流行的设计模式就是面向对象,那么什么是面向对象呢?   首先我们来看下官方的定义。在维基百科上说: >  面向对象程序设计(英语:Object-oriented programming,缩写:OOP)是种具有...
  • 【java基础】-谈谈对面向对象理解

    千次阅读 多人点赞 2019-11-26 08:25:18
    我想要谈对象,你要谈么?
  • 下面,我说说自己的想法, 首先,谈谈“面向过程”vs“面向对象” 我觉得这两者是思考角度的差异,面向过程更多是以“执行者”的角度来思考问题,而面向对象更多是以“组织者”的角度来思考问题,举个例子,比如我...
  • java基础之关于面向对象和面向过程的理解
  • 面试官:说说你对DOM的理解,常见的操作有哪些?

    千次阅读 多人点赞 2021-03-10 00:37:55
    一、DOM文档对象模型 (DOM) 是 HTML 和 XML 文档的编程接口它提供了对文档的结构化的表述,并定义了一种方式可以使从程序中对该结构进行访问,从而改变文档的结构,样式和内容任何...
  • Mybatis与hibernate-自己理解 Hibernate做了写优化,比如一二三级缓存,把数据存放在缓存里面,这里是通过OID去区分是否为同一个对象,存放在内存。 今天同事问了我下:Hibernate中get/load区别以及为什么能...
  • MyBatis面试题(2020最新版)

    万次阅读 多人点赞 2019-09-24 16:40:33
    通过sqlsession执行数据库操作 4、 调用session.commit()提交事务 5、 调用session.close()关闭会话 请说说MyBatis的工作原理 在学习 MyBatis 程序之前,需要了解一下 MyBatis 工作原理,以便于理解程序。...
  • js面向对象理解

    千次阅读 2016-11-03 22:40:22
    js面向对象理解(二) 前面总结了js面向对象的一些基础概念,接下来想说说关于js面向对象中创建对象这块的内容,以下是我个人的一些见解,有任何纰漏的地方还请大家批评指正! 一、创建对象: 1.创建单个对象: ...
  • displayName() 没有自己的局部变量。然而,由于闭包的特性,它可以访问到外部函数的变量 二、使用场景 任何闭包的使用场景都离开这两点: 创建私有变量 延长变量的生命周期 ❝ 一般函数的词法环境在函数返回后就...
  • 在说明com对象在易语言中的使用之前,让我们先来了解一下几个问题 什么是com? com全称是组件对象模型(compoment object model),他是一组规范,是MicroSoft创建的一组二进制和网络标准,用于解决两个组件之间的...
  • 个人对反射定义的理解: 首先得说说什么叫反射。对于一个新手来说,反射这个概念常常给人一种似懂非懂的 感觉,知道该如何下手操作。 反射是指:指在PHP运行状态中,扩展分析PHP程序,导出或提取出关于类、方法、...
  • 说说你对servlet 的理解或者 servlet 是什么?

    万次阅读 多人点赞 2017-08-06 21:57:55
    说说你对servlet的理解或者 servlet 是什么? Servlet(Servlet Applet),全称Java Servlet,是用Java编写的服务器端程序。而这些Servlet都要实现Servlet这个接口。其主要功能在于交互式的浏览和修改数据,生成...
  • 说说你对GC理解,什么是GC?

    千次阅读 2018-11-22 23:13:42
    GC(GarbageCollection)是垃圾回收机制(垃圾回收器),GC是JVM对内存(实际上就是对象)进行管理的方式。 Java是由C++发展来的。它摈弃了C++中一些繁琐容易出错的东西。其中有一条就是这个GC。 写C/C++程序,...
  • 那么,我们再来说说删除吧,就是这样: 一目了然,绝对的一目了然! 在周末之际,哦。。。,在字典结束之际。。。。╮(╯▽╰)╭ 周末要加班( ⊙ o ⊙ )啊!  如果说,从字典中读取一个...
  • 说说自己对ssm整合的看法

    千次阅读 2017-03-24 20:20:52
    最简单的说就是mybatis写Dao层,springmvc写视图层,然后通过spring耦合 单独使用mybatis的时候,我们总是要去获得...具体怎么配置我就说了 在服务层注入持久层的mapper对象 eg @Autowired private userMapper
  • js面试题

    千次阅读 多人点赞 2019-04-09 19:42:32
    JavaScript 的组成 JavaScript 由以下三部分...BOM(浏览器对象模型):提供了浏览器窗口之间进行交互的对象和方法 JS 的基本数据类型和引用数据类型 基本数据类型:undefined、null、boolean、number、string、s...
  • 面向对象面试题

    万次阅读 多人点赞 2018-01-09 09:45:46
    1) 面向对象的优点? 答案 Icon ...易扩展 易维护,面向对象三大特征(封装,继承,多态...对于一些必须要初始化的代码,必须是写在静态块里面,如果写在构造器里面,有多个构造器的时候一定执行初始化. 3) 接口与

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 111,034
精华内容 44,413
关键字:

对象不理解自己的说说