Java 编程思想笔记:Learn 1

对象的特性

  1. 类 == 数据结构;常见的数据结构就是语言已经实现的可供调用的类。
  2. 程序员就是扩展编程语言,为解决问题定义一些新的数据结构。

UML

表示类

UML(Unified Model Language),统一建模语言。
一个方框分三部分,上部分类名,中间属性,最下方方法。

实心黑色菱形表示组合
zuhe.png
空心三角形表示继承
super.png

接口

接口就是一个标准。

权限控制

权限控制的出现背景:厘清类库开发者和类库使用者之间代码权限。

  • public,类库开发者专门为使用者准备的 API。
  • private 表明,除了类库开发者创建的内部方法,其他任何人都不可以调用。
  • protectd,子类可以访问 父类的 protected 方法/属性。
  • friendly,也称为包访问权限,同一个包中可以随便访问。

前期绑定 / 后期绑定

  • 前期绑定:编译器将产生对一个具体函数名字的调用,而运行时将这个调用解析到将要被执行的代码的绝对地址;
  • 后期绑定:当向对象发送消息时,被调用的代码直到运行时才能确定。编译器确保被调用的方法存在,并且对调用参数和返回值执行类型检查。在 C++ 中,使用 virtual 关键字来声明后期绑定。

向上转型(upcasting)/向下转型(downcasting)

向上转型

向上,来源于类图中父类型与字类型的位置;
转型,模具塑模时的动作。
在以父类为参数的地方,传入子类的实例同样合法。

public class Father{}
public class Sub extends Father{}
public void test(Father f){}
Sub s = new Sub();
test(s);

向下转型

把 Obejct 对象转化为某种子类型,这个操作是有风险的,因此要考虑异常。

例子:如声明一个数组List<Object>,可以向里面放入Integer / String 等类型。但是元素放进去以后就会丢失身份,再取出来的元素全部都是 Object,使用的时候还需要把 Object 转化为 Integer / String 等类型。

单根继承

单根指所有的类都继承自 Object。
好处:

  • 使垃圾回收变得简单
  • 确保某些功能所有的对象都具备

容器

ArrayList / LinkedList
ArrayList 访问一个元素的时间固定,LinkedList 插入元素用时更少。

泛型

用一对尖括号,里面是类型信息,这就是泛型。

堆(heap)/生命周期

C++ 是在栈中创建对象,在栈中创建存储空间和释放存储空间通常各需要一条汇编指令即可。编译器可以确定对象的存活时间。
Java 在堆(heap)也被称为内存池中动态地创建对象。在这种方式中,直到运行时才知道需要多少对象,它们的生命周期如何,以及它们具体的类型。存储空间在运行时被动态管理的,所以需要大量的时间在堆中分配存储空间,这可能远远大于在栈中创建存储空间的时间。编译器不知道对象的生命周期。所以 Java 需要垃圾回收机制。

对象存储的位置

  • 寄存器,最快的存储区,它位于处理器(CPU)内部,但是寄存器的数量极其有限,程序员不能控制。
  • 栈(stack),位于通用RAM(随机访问存储器),但是通过堆栈指针可以从处理器那里获得直接支持。堆栈指针向下移动,则分配新的内存;上移,则释放内存。这是一种快速有效的分配存储方法,仅次于寄存器。创建程序时,Java 系统必须知道存储在栈内所有项的确切生命周期,以便上下移动指针。这点限制了程序的灵活性,所以 Java 把对象的引用放在栈中,但是对象不放在栈中。
  • 堆。一种通用的内存池(也位于RAM区),用于存放所有 Java 对象。堆不同于栈的好处在于:编译器不需要知道存储的数据在堆里的存活时间。因此,在堆里分配内存有很大的灵活性,当需要一个对象时,只需要 new 写一行简单的代码,当执行这行代码时,会自动在堆里进行存储分配。坏处就是:用堆进行存储分配和清理比用栈进行存储分配需要更多时间。
  • 常量存储。常量直接存放在程序代码内部。
  • 非 RAM 存储。流对象和持久化对象。对象转化为字节流,发送给另外的机器;持久化对象可以存放到数据库里。

存储的特例——基本类型

8种基本类型,boolean / char / byte/ int / short / long / float / double /void, 它们都存储在栈中。

static

  • 普通方法必须和实例联系起来才能运行。实例是类的具象,所以具有类的种种特征,所以实例能调用静态方法。
  • 静态方法和实例无关,而普通方法必须和实例关联,所以静态方法和普通方法无关,也就是说静态方法不能调用普通方法。
  • 静态方法只需要一份存储空间。

main

public static void main(String[] args)

args 用来存储命令行参数。

赋值 / 别名引用

对基本类型赋值是复制,对对象赋值是引用。
基本类型直接在栈上创建,开销小,编译器知道生命周期,所以赋值都是复制。

a = 1111
b = 2333
a = b
a = 7777
print(b) #2333

对象在堆上创建,赋值给变量名的只是一个句柄,指向内存池中的对象。所以 a = b, 是把指向内存池中对象地址也指向了b,所以如果发生了改变,都会改变

class Tank:
  level = 0

class Assignment:
  # t1 / t2 都是一个句柄而已,指向的都是内存池中的实例化的对象。
  t1 = Tank() //指向实例 t1
  t2 = Tank() // 指向实例 t2
  t1.level = 2555
  t2.level = 2777
  t1 = t2 // 这个操作含义是,t1 指向 (t2 指向在内存池中的对象)
  print(t1, t2)

以上操作对于 Python / Java 来说都一样,在编程思想中认为以上对于属性的操作实在让人懵逼,所以推荐使用修饰符。

自动递增 / 递减

i++ /++i 的区别

i++ / ++i 对于 i 的影响是相同的,i 都会加1.
但是对于下面的 front 和 end 来说是有区别的:

        Integer m = 0;
        Integer n = 0;
        Integer front = null;
        Integer end = null;
        Integer counter = 0;
        while(counter < 5){
            front = m++;
            end = ++n;
            System.out.println("front "+front+" end "+end);
            counter++;
        }

执行结果发现,front 最终为4,end 最终结果为5;

这说明 m++ 对于 front 来说是先赋值后加,++n 对于 end 来说是先加后赋值。

我记这个,是通过哪个离等号近来判断的,m离等号近说明是先赋值再加,+离等号近说明是先加再赋值。

另外 ++n 在多线程环境下会造成异常,因为 ++n 不是原子性操作。

== / equals

  • 八大基本类型(char,byte,boolean,float,double,int,long,short)由于直接在栈上创建,它们没有引用,所以直接用 == 判断基本类型是否相等即可。
  • a == b,对于非基本类型的a、b而言,a 和 b 需要是同一个对象的实例并且值相等(也就是同一个内存地址),才会返回 true
  • equals,类库的大都重写了 equals 方法,使 equals 只是作为比较对象值是否相等的工具。
  • 但是如果新建一个类,不重写 equals 方法,使用父类 object 的 equals方法的话,那就是引用了,必须两个变量指向的内存地址相等才是相等。
public class Inc{
    public int i;
}
Inc a = new Inc();
Inc b = new Inc();
a.i = b.i = 100;
System.out.println( a == b); /false
System.out.println(a.equals(b)); //false

逻辑运算的短路

我经常碰到下面的这种情况,逻辑运算中的两个条件是有联系的,比如 result有可能是null, 如果是 null 的话,result + 3会直接抛异常了。

    @Test
    public void autoIncTest() {
        Integer result = foo(0);

        if (result == null || result + 3 >7){
            System.out.println("ok");
            return;
        }
    }

    public Integer foo(Integer arg){
        if(arg == 0){
            return null;
        } else {
            return 3;
        }
    }

以前我没理解逻辑短路之前,代码不敢写成上面这种,而是这么实现:

    @Test
    public void autoIncTest() {
        Integer result = foo(0);
        if (result == null){
             System.out.println("ok");
             return;
        }
        if ( result + 3 >7){
            System.out.println("ok");
            return;
        }
    }

学了逻辑短路之后踏实了,因为一旦能够明确无误地确定整个表达式的值,就不再计算表达式余下的部分了。因此整个逻辑表达式靠后部分有可能不计算!这句话真是福音 + 定心丸!

    public boolean test1(){
        System.out.println("i am test1");
        return true;
    }

    public boolean test2(){
        System.out.println("i am test2");
        return false;
    }

    public boolean test3(){
        System.out.println("i am test3");
        return true;
    }

    @Test
    public void testBoolean(){
//        boolean bool = test1() && test2() && test3();
        boolean bool = test1() || test2() || test3();
        System.out.println(bool);
    }

这个短路的例子也表明 Java 不会对所有的表达式求知,一旦算出了结果,便会立即返回。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • 写一段小文字。 说来我挺想每天都写点什么的,然而繁杂的工作千篇一律,实在冗长琐碎,不稀的写。当然,这可能是我不热爱...
    小知了阅读 123评论 0 0
  • 对于创业,多数人的理解集中在两端,要么是觉得创业很容易,注册一家公司搭个戏台就能把一个小作坊搞起来,要么是觉得创业...
    卧仑丁阅读 282评论 0 0
  • 用了一段时间的 Vue,基本熟悉了讨论,看到 Vue2.0 已经发布,而且文档已经比较齐全,刚好学习和迁移一下 V...
    马文Marvin阅读 1,620评论 1 1
  • 《摔跤吧,爸爸》是我迄今为止看的第二部印度电影,而且两部的主人公都是阿米尔汗。第一部是他演的《三傻大闹宝莱坞》,第...
    耳畔的肖邦阅读 651评论 2 3
  • 今天是心痛和开心互相交杂的一天。 今天,我的母亲开车带我去到屏南县看电影,那是最近经常被宣传的《寻梦环游记》。...
    小爱希阅读 399评论 1 0