基于《Java编程思想》第四版

前言

“程序就是算法加数据结构”,而算法就是控制语句加操作符,编写一个程序就是使用控制语句加操作符去操作数据结构,因此我从Java的控制语句、操作符以及如何组织数据结构开始入手。因为有C/C++的基础,所以不免会以对比的方式去理解Java。

控制语句

除了没有goto,Java的控制流程的关键字和C++是一样的,很好理解。不过Java中的breakcontinue除了C++的正常作用外(跳出或继续当前循环),还有类似C++中goto的功能,但是使用上是有限制的,即标签与forwhile(){}do{}while()switch之间不能有其他语句,否则就会有编译错误。

  • 使用break跳转到标签后,会直接跳过标签后紧跟着的循环或者switch代码,而不是从标签位置重新开始执行。
int[] a = {1,2,3,4};
Label:
// 这里不能有任何语句
for( int i : a ){
    System.out.println("loop 1 i = " + i);
    for( int j : a ){
        System.out.println("loop 2 j = " + j);
        break Label;
    }
}
// break Lable后会直接执行下面的代码,而不是继续循环
System.out.println("loop over");
  • 使用continnue跳转到标签后,会继续执行标签后紧跟着的循环代码,但并非重头开始执行而是从原本的基础上继续执行
int[] a = {1,2,3,4};
Label:
// 这里不能有任何语句
for( int i : a ){
    System.out.println("loop 1 i = " + i);
    for( int j : a ){
        System.out.println("loop 2 j = " + j);
        continue Label;
    }
}
System.out.println("loop over");

运行以上代码就会发现break Label的含义就是跳出Label标识的循环,而continue Label的含义是继续循环Label标识的循环,这和C++的goto是不同的。C++中的goto会将让程序执行流回到Label的位置,重新执行Label后的代码。

操作符

Java多了一个无符号右移操作符>>>,其他都和C/C++一样,也很好掌握。不过Java中无法进行操作符重载,因此理论上操作符应该只能作用于数值类型。但实际上,Java的String类型也可以使用=++=操作符,我想应该是因为字符串的赋值和拼接是很常见的操作,所以Java就在内部偷偷给String类型做了这些操作符的重载。这虽然带来了一定的便利,但是因为String类型的其他操作符并没有重载,所以让我感觉不一致,比较难受。比如下面这段代码,因为String==并未重载,所以并不会打印"same string"

String s1 = new String("hello");
String s2 = new String("hello");
if( s1 == s2 ){
    System.out.println(“same string”);
}

在C++中,则可以通过操作符重载,使得std::string类型可以使用==操作符比较是否为相同字符串,很一致。

还有一点,Java中并没有sizeof操作符。我想这是因为Java不想让程序员去关注内存分配,自然也就无需关心类型大小,再者基础类型的大小在Java中是固定的,所以sizeof就无用武之地了。C中分配内存的函数,如malloc等,都是需要指定大小的,且基础类型在不同平台的大小可能是不一样大的,因此必须有sizeof计算大小。

类型

Java有以下基础类型

这些基础类型的大小都是固定的,而且所有数值类型都是有符号的。

Java通过class关键字来自定义类型,其结构与C++类似,只是不需要在}后加;

class MyType{
     ...
}

C++中的自定义类型除非指定继承否则是没有继承关系的,但是在Java中所有类型都隐式继承自Object。Java中有很多已经定义好的类型,比如基础类型的包装器类型、String等等,学习并使用这些已经定义好的类型是水磨工夫,起初了解一下就可以了。

Java的函数的定义语法和C++是一模一样的,但是函数只能在类型的命名空间里即只能在class {这里面}定义,而不能在全局命名空间中定义。函数在Java中应该叫方法,不知道叫函数会不会有误解。
Java的自定义类型中可以包含其他类型的变量或者继续定义类型(内部类)。其他类型的变量,C++中叫成员变量,但似乎Java中叫域。

实例化类型

Java实例化类型的语法和C++一模一样,但是有一些限制。

  • 基础类型只能直接实例化,无法用new实例化
int x = 1;
  • 特定类型,比如基础类型的包装器类型、String类型等,可以直接赋值(本质上是编译器帮你做了一次隐式转换),或使用new实例化
Integer n1 = 1;
Integer n2 = new Integer(1);
String s1 = "hello";
String s2 = new String("hello"); // 不推荐这么用,转换后的字节码更多
  • 其余类型的实例化必须使用new关键字
MyType m = new MyType(1);
// MyType m = 1; 不会进行一次隐式转换,编译报错

可以感觉到很强烈的不一致!!

基础类型的变量空间存储的是真实数值,而其他类型的变量空间存储的是实例化对象的引用。Java中的引用和C++的引用并不是一个意思,Java中的引用更像是C++中的指针。在C++中,引用是一个实例对象的别名,一旦确定就无法变更其引用的对象,但是在Java中可以变更引用的实例化对象,比如

Integer a = new Integer (1);
a = new Integer(2);

在函数传参中,这点就更明显了,比如下面的函数,我们叫ab是引用,但实际呢,这只是值传递swap()中的交换并不会影响实际对象的值。整个函数就是交换了一下ab这两个局部变量指向的对象而已。

void swap(Integer a, Integer b){
    Integer tmp = a;
    a = b;
    b = tmp;
}

就类似于以下C++代码

void swap(int* a, int* b){
    int* tmp = a;
    a = b;
    b = tmp;
}

从上面看所谓对象的引用其实就是把对象的地址值(不是内存地址,只需要是一个唯一位置的标识即可)保存到了变量空间里。从这个角度去理解,基础类型的变量和其他类型的变量存储的东西可以认为是一样的。Java中只有值传递

访问控制

和C++一样,Java也有针对类、方法、域的访问权限控制。Java除了publicprotecetedprivate这些权限外,还有一种包访问权限。当不带另外三个权限关键字时,就是包访问权限了。在Java中可以将一些源文件定义为一个包,因此就有了包访问权限,即同一包内可以访问。Java中的包类似于C++的动态库,C++中虽然没有明确说包(库)访问权限,但实际上是有的,比如Linux下可以通过链接时的参数version-script指定动态库的导出符号,那些未导出的符号就是包(库)访问权限了。

文件组织

一个.java源文件中只能有一个public类,且源文件名必须和这个public类的名字保持一致。其他类只能是包访问权限,当然内部类是不受这个限制的,可以是任意权限。每个类型都可以有一个public static void main(String[] agrs),这是执行的入口。因为函数都是在类的命名空间里,所以存在多个main()也是可以的,指定执行的类就会调用对应的main()

结语

因为IDE的强大,所以很多东西只需要脑子里有点印象,做到写代码时看到错误提示就能想到是为什么就可以了,熟能生巧。

Java学习点滴——初识Java的更多相关文章

  1. SSH 框架学习之初识Java中的Action、Dao、Service、Model-收藏

    SSH 框架学习之初识Java中的Action.Dao.Service.Model-----------------------------学到就要查,自己动手动脑!!!   基础知识目前不够,有感性 ...

  2. Java学习-002-Java初识

    此文主要讲述什么是 Java,以及 Java 常识性知识,方便亲们进一步了解 Java 语言相关的常识. 一.Java 概述 Java 语言是美国 Sun Microsystems 公司于 1995 ...

  3. JAVA学习笔记--初识容器类库

    一.前言 JAVA中一切皆为对象,因而,持有对象显得尤为重要. 在JAVA中,我们可以通过创建一个对象的引用的方式来持有对象: HoldingObject holding; 也可以创建一个对象数组来持 ...

  4. Java学习路线图,Java学习计划建议

    怎么学习Java,这是很多新手经常遇到的问题,现在我简单描述下一个Java初学者到就业要学到的一些东西:     首先要明白Java体系设计到得三个方面:J2SE,J2EE,J2ME(KJAVA).J ...

  5. Java学习之路 -- Java怎么学?

    @ 目录 java基础怎么学? 学完基础学什么? 几个常用框架学完学什么? MQ JVM的知识跑不掉 微服务等等 其他 数据结构和算法 java基础怎么学? 当时,作为懵懂的小白,大一学习了c和c++ ...

  6. Java学习笔记之—Java基础

    将学习到的JAVA基础用xmind记录了下来,需要原件的可以私信

  7. Java学习笔记--通过java.net.URLConnection发送HTTP请求

    http://www.cnblogs.com/nick-huang/p/3859353.html 使用Java API发送 get请求或post请求的步骤: 1. 通过统一资源定位器(java.net ...

  8. java 学习笔记1 java语言概述及开发环境

    高级语言运行机制 高级语言按程序的执行方式分为编译型和解释型两种. java语言比较特殊,Java程序的执行必须经过先编译后解释的步骤. 1 编译生成字节码,只面向JVM(.class) 2Jvm执行 ...

  9. Java 第一章 初识Java

    第一章笔记 什么是计算机程序:算机为完成某些功能生产的一系列有序指令集合 Java技术包括: java SE:标准版 java EE:企业版 Java ME:移动版 开发Java程序步骤:1.编写 2 ...

随机推荐

  1. 软硬件协同编程 - C#玩转CPU高速缓存(附示例)

    写在前面 好久没有写博客了,一直在不断地探索响应式DDD,又get到了很多新知识,解惑了很多老问题,最近读了Martin Fowler大师一篇非常精彩的博客The LMAX Architecture, ...

  2. SSRS报表服务随笔(rdl报表服务)-报表参数

    上一篇我们说了创建一个简单的显示报表,但在实际工作中,我们有很多要带条件的报表 现在先认识一下报表数据,首次打开SSDT,报表数据在窗口的左侧,要是找不到了,没关系,在工具栏-视图-最下面的报表数据 ...

  3. cannot be cast to java.lang.Comparable

    Exception in thread "main" java.lang.ClassCastException: com.myradio.People cannot be cast ...

  4. 腾讯云发布runC容器逃逸漏洞修复公告

    尊敬的腾讯云客户,您好:  近日,腾讯云安全中心监测发现轻量级容器运行环境runc被爆存在容器逃逸漏洞,攻击者可以在利用该漏洞覆盖Host上的runc文件,从而在Host上以root权限执行代码. 为 ...

  5. MySQL 复制 - 性能与扩展性的基石 3:常见问题及解决方案

    主备复制过程中有很大可能会出现各种问题,接下来我们就讨论一些比较普遍的问题,以及当遇到这些问题时,如何解决或者预防问题发生. 1 数据损坏或丢失 问题描述:服务器崩溃.断电.磁盘损坏.内存或网络错误等 ...

  6. Asp.Net Core对接钉钉群机器人

    钉钉作为企业办公越来越常用的软件,对于企业内部自研系统提供接口支持,以此来打通多平台下的数据,本次先使用最简单的钉钉群机器人完成多种形式的消息推送,参考钉钉开发文档中自定义机器人环节,此次尝试所花的时 ...

  7. Netty源码—四、事件处理

    前面经过channel初始化.注册,所需要的数据结构(epoll_event)基本上准备好了,serverSocket也处于监听状态,可以接收来自客户端的请求了.NioServerSocketChan ...

  8. Java并发编程面试题 Top 50 整理版

    本文在 Java线程面试题 Top 50的基础上,对部分答案进行进行了整理和补充,问题答案主要来自<Java编程思想(第四版)>,<Java并发编程实战>和一些优秀的博客,当然 ...

  9. SSM+Maven+MySQL实现简易的挂机修仙页游

    一段时间没有写过SSM的项目了,最近重新整合框架做了一个小Demo 学Java的萌新可以看一看:大佬呢,欢迎指出不足! 我一直钟爱挂机类游戏,同时也喜欢修仙和武侠小说,于是突发奇想,自己搞一个小游戏? ...

  10. 从On-Premise本地到On-Cloud云上运维的演进

    摘要: 从用户的声音中,我们听到用户对稳定.弹性.透明的诉求,我们也在不断升级ECS的运维能力和体验,助力用户建立主动运维体系,赋能业务永续运行.为了让大家更好的了解和用好ECS弹性计算服务,从本期开 ...