Java学习点滴——初识Java

基于《Java编程思想》第四版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计算大小。oop

类型

Java有如下基础类型

这些基础类型的大小都是固定的,并且全部数值类型都是有符号的。学习

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

class MyType{
     ...
}

C++中的自定义类型除非指定继承不然是没有继承关系的,可是在Java中全部类型都隐式继承自Object。Java中有不少已经定义好的类型,好比基础类型的包装器类型、String等等,学习并使用这些已经定义好的类型是水磨工夫,起初了解一下就能够了。code

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的强大,因此不少东西只须要脑子里有点印象,作到写代码时看到错误提示就能想到是为何就能够了,熟能生巧。

相关文章
相关标签/搜索