• <sup id="mk476"></sup>
    <dl id="mk476"></dl>
  • <progress id="mk476"><tr id="mk476"></tr></progress>
    <div id="mk476"><tr id="mk476"></tr></div>
    <sup id="mk476"><ins id="mk476"></ins></sup>
  • <progress id="mk476"></progress>
    <div id="mk476"></div>
    <div id="mk476"><tr id="mk476"></tr></div>
  • <div id="mk476"></div>
    <dl id="mk476"><s id="mk476"></s></dl><dl id="mk476"></dl><div id="mk476"></div>
  • <div id="mk476"></div>
    <dl id="mk476"><ins id="mk476"></ins></dl>

    Java学习点滴——初识Java

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

    前言

    “程序就是算法加数据结构?#20445;?#32780;算法就是控制语句加操作符,编写一个程序就是使用控制语句加操作符去操作数据结构,因此我从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中无法进行操作符重载,因此理论上操作符应该只能作用于数值类型。但?#23548;?#19978;,Java的String类型?#37096;?#20197;使用=++=操作符,我想应该是因为字符串的赋值和拼接是很常见的操作,所以Java就在内?#23458;?#20599;给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等,都是需要指定大小的,?#19968;?#30784;类型在不同平台的大小可能是不一样大的,因此必须有sizeof计算大小。

    类型

    Java有以下基础类型

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

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

    class MyType{
         ...
    }

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

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

    实例化类型

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

    • 基础类型只能直接实例化,无法用new实例化
    int x = 1;
    • 特定类型,比如基础类型的包装器类型、String类型等,可以直接赋值(本质上是编译器帮你做了一?#25105;?#24335;转换),或使用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; 不会进行一?#25105;?#24335;转换,编译报错

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

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

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

    在函数传参中,这点就更明显了,比如下面的函数,我们叫ab是引用,但?#23548;?#21602;,这只是值传递swap()中的?#25442;?#24182;不会影响?#23548;识?#35937;的值。整个函数就是?#25442;?#20102;一下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;
    }

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

    访问控制

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

    文件组织

    一个.java源文件中只能有一个public类,?#20197;?#25991;件名必须和这个public类的名字保持一致。其他类只能?#21069;?#35775;问权限,?#27604;?#20869;部类是不受这个限制的,可以是?#25105;?#26435;限。每个类型都可以有一个public static void main(String[] agrs),这是执行的入口。因为函数都是在类的命名空间里,所以存在多个main()也是可以的,指定执行的类就会调用对应的main()

    结语

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

    posted @ 2019-04-12 11:46 一罪 阅读(...) 评论(...) 编辑 收藏
    江苏11选5软件 vr火星五分彩开奖官网 快乐12中奖方法 香港赛马会脑筋 浙江体彩6+1查询 网球教学视频 西甲第10轮巴萨皇马 吉林11选5前2 安徽快三走势图爱彩 单双中特公试规律 江西时时彩豹子历史遗 安徽25选5中奖规则 五子棋价格 如意彩票官网3d谜语 福建十三水游戏下载 姚记扑克258背面认花色