Thinking in Java 系列 ---(一)基本语法和操作

前言

本系列由阅读Think in java 4th英文原版完成。Think in java 作为最权威的java书籍之一,读起来其实并不通俗易懂,并不适合初学者。但是他的解释和语言是java运行的标准。当我读的时候有一些语句是非常直接且到位的表达了一种机制和他最简单的存在的意义。相信只有清楚的描述了每种机制或语法是如何发明出来的,才能够了解他如何使用。这也是本书的精髓。

本系列会陆续进行更新。

第一章主要简要的介绍一下基本语法和操作符合流程控制语法,具体一些非常基础的语法就不进行介绍了。

编译和运行java

java文件执行过程

一次编译多次运行。

  1. 源文件,Party.java
  2. 编译java文件, 执行javac Party.java命令
  3. 得到Party.class二进制文件bytecode,编译后的二进制文件与平台无关
  4. 编译后的文件也就是.class文件需要在java虚拟机上JVM运行,而不同的平台有不同的java虚拟机,安装jvm后就可以来运行Party.class文件,执行java Party来运行java程序

note:java文件名必须和public类名相同,需要有Main函数作为入口函数。java从main方法开始执行,一个java程序至少有一个main方法,如果有多个则需要指定从哪个来执行。

java调用.class文件中的几种方式

和调用正常的方法一样调用.class文件中的方法,即使不提供.java文件,一样可以调用.class,编译的时候一些IDE会提示错误但是可以正常编译,因为运行的时候都是执行.class文件,如果使用intellij idea,需要把所调用的.class文件放到out文件夹中,out文件夹存放的是所有的编译后的文件.class文件。然后运行程序。编译器会报错无法找到调用方法,但是可以运行,只要所调用的方法都在out文件夹中的.class文件中就可以正常执行。

Everything Is an Object (任何都是对象)

内存管理

c++ 和java都是混合语言,但是c++是C的超集所以包含了很多功能而变得复杂。

  1. register: 存在于处理器中,速度最快,程序员不直接控制,而是在需要的时候会被调用。
  2. stack:由stack pointer 被处理器控制。存储对象引用,和本地变量。
  3. heap: 所有的对象存储位置。
  4. constant storage:常量存储区,直接存在代码中
  5. Non-RAM storage:存储在程序以外的空间。

RAM中分为stack 和heap
具体的系统内存管理可以查看我的另一篇文章
内存管理详解

java的八大基本类型如下:

基本类型都存储在stack中:
在这里插入图片描述

相同种类杯子中,小杯子可以倒到大杯子中(int可以直接转换成long),而大杯子不能倒入小杯子中。而boolean和char是单独的类型。不属于数值类型不能互相倒。
一切皆对象,除了基本类型都是引用类型,string 字符串存储在常量池中。
Java does not need a sizeof( ) operator for this purpose, because all the data types are the same size on all machines. You do not need to think about portability on this level—it is designed into the language.没有sizeof因为java中的数据类型在所有机器上都是相同的大小。

int 所占空间及取值范围

一个 Integer 类型占 4 字节byte(1kb = 1024 byte),一个字节占 8 位二进制码bit,因此一个 Integer 总共占 32 位二进制码。去除第一位的符号位,剩下 31 位来表示数值。所以int的取值范围是 -2^31 ~ 2^31

//A.java
public class A {
public static void main (String[] args) {
 System.out.println("I Rule!");
 }}
wrap自动包装

看声明的时候是什么类型

char c = 'x';//存储在stack
Character ch = new Character(c);//创建字符存储在heap
Character ch = new Character('x');
//Java SE5 autoboxing will automatically convert from a primitive to a wrapper type:
Character ch = 'x';//创建并存储在heap
char c = ch;//存储在stack

八大基本类型自动包装

public static void main(String[] args) {
        boolean b = false;
        char c = 'x';
        byte t = 8;
        short s = 16;
        int i = 32;
        long l = 64;
        float f = 0.32f;
        double d = 0.64;
        
        Boolean B = b;
        System.out.println("boolean b = " + b);
        System.out.println("Boolean B = " + B);
        
        Character C = c;
        System.out.println("char c = " + c);
        System.out.println("Character C = " + C);
        Byte T = t;
        System.out.println("byte t = " + t);
        System.out.println("Byte T = " + T);
        Short S = s;
        System.out.println("short s = " + s);
        System.out.println("Short S = " + S);
        Integer I = i;
        System.out.println("int i = " + i);
        System.out.println("Integer I = " + I);
        Long L = l;
        System.out.println("long l = " + l);
        System.out.println("Long L = " + L);
        Float F = f;
        System.out.println("float f = " + f);
        System.out.println("Float F = " + F);
        Double D = d;
        System.out.println("double d = " + d);
        System.out.println("Double D = " + D);
    }
null

When Java sees null, it recognizes that the reference in question isn’t pointing to an object.当java使用null则说明这个引用没有指向任何对象,如果使用这个引用则会报错。

描述很大的数据用:
BigInteger supports arbitrary-precision integers. This means that you can accurately represent integral values of any size without losing any information during operations.

BigDecimal is for arbitrary-precision fixed-point numbers; you can use these for accurate monetary calculations, for example.

scope

如果都是本地变量,则在一个作用域内不能重复声明该变量。

{
    int x = 12;
    {
        int x = 96; // Illegal,declare in large viriable
    }
}

对象的scope解决了内存泄漏的问题。Java可以自动回收内存。

初始化变量

It’s best to always explicitly initialize your variables.
成员变量会被默认初始化。(当然最好自己初始化)
局部变量必须初始化,不然编译器报错。

public class Main {
    private static int i;
    private static char c;//'\u0000'
    private static RouterTest routerTest;
    public static void main(String[] args) {
        System.out.println(i);//0
        System.out.println(c);//'\u0000'
        System.out.println(routerTest);//null
    }
}
method

在Java中本书把方法叫做method而不是function(C,C++)

面向对象编程

简单来说:把信息传给对象
Object-oriented programming is often summarized as simply “sending messages to objects”

static

static 修饰的变量只会在类创建时候创建一次,他是每个对象共享的。

 public static void main(String[] args) {
        //System.out.println("This is a test for jar to exe!");
        System.out.println(RouterTest.sharedInt);//5
        RouterTest routerTest1 = new RouterTest();
        routerTest1.sharedInt++;
        RouterTest routerTest2 = new RouterTest();
        routerTest2.sharedInt++;
        System.out.println(RouterTest.sharedInt);//7

    }
命令行输入参数

main中的args是用来接收命令行传入的参数的

class CommandLineExample{  
public static void main(String args[]){  
for(int i=0;i<args.length;i++)  
System.out.println(args[i]);  
}  
}  


compile by > javac A.java  
run by > java A sonoo jaiswal 1 3 abc  
Output: sonoo
       jaiswal
       1
       3
       abc
javadoc

可以提取类名和注释生成javadoc文档,intelliJ中tool->generate javaDoc

Operator 操作符

Almost all operators work only with primitives. The exceptions are “=”, ‘==’, and “!=”, which work with all objects (and are a point of confusion for objects). In addition, the String class supports ‘+’ and ‘+=’.

所有的操作符几乎都用于基本类型,但是’=’,’==’,’!=’, 可以用于所有对象。 String类型支持+和+=

When the compiler sees a String followed by a ‘+’ followed by a non-String, it attempts to convert the nonString into a String.

	int x = 0, y = 1, z = 2;
		String s = "x, y, z ";
		System.out.println(s + x + y + z);
		System.out.println(x + y + " " + s); //  1 x,y,z Converts x to a String
分配

基本类型是把值复制后给另一个,而对象类型两个引用指向同一个对象。

按引用传递,如果该方法修改了对象中的值,则方法外这个对象会被修改。

public class Main {
    static void f(Letter y) {
        y.c = 'z';
    }
    public static void main(String[] args) {

        Letter x = new Letter();
        x.c = 'a';
        System.out.println("1: x.c: " + x.c);
        f(x);//把引用传进方法
        System.out.println("2: x.c: " + x.c);
    }
}

class Letter {
    char c;
}
数学表达式

languages: addition (+), subtraction (-), division (/), multiplication (*) and modulus (%, which produces the remainder from integer division). Integer division truncates, rather than rounds, the result.取余会得到int,是整数部分不含小数,而不是四舍五入部分。

int x = 0;
        int a = 7;
        x = -a;
        System.out.println(x);//-7

++a is equivalent to (a = a + 1)
在for循环里++i 和i++没有区别

int i = 1;
		System.out.println("i	: " + i);//1
		System.out.println("++i	: " + ++i);	//2 Pre-increment 先增
		System.out.println("i++	: " + i++);	//2 Post-increment 算后增量
		System.out.println("i	: " + i);//3
		System.out.println("--i	: " + --i); //2 Pre-decrement
		System.out.println("i--	: " + i--); //2 Post-decrement
		System.out.println("i	: " + i);//1
随机数

不含参数的Random以当前时间作为seed,每次生成随机数不同,而含参的Random根据seed生成随机数,每次生成的随机数是固定的,比如每次都生成一个85。

Random rand = new Random(1);
        int i, j, k;
        // Choose value from 1 to 100:
        j = rand.nextInt(1000);
        System.out.println(j);
对象比较相等

The operators == and != compare object references, so the output is actually “false” and then “true.” Naturally, this surprises people at first.
Most of the Java library classes implement equals( ) so that it compares the contents of objects instead of their references.

Integer n1 = new Integer(47); 
Integer n2 = new Integer(47);
System.out.println(n1 == n2);//false
System.out.println(n1.equals(n2));//true

如果是自己创建的对象如果要比较则需要重写equals方法

进制

java会根据传入的值判断是多少进制然后转换为十进制,八进制0开头, 十六进制0x开头

int i1 = 0x2f; // Hexadecimal (lowercase)十六进制
System.out.println(i1);//47
System.out.println(Integer.toOctalString(i1));//57 转化为八进制
System.out.println(Integer.toHexString(i1));//2f 十进制转化为十六进制
System.out.println("i1: " + Integer.toBinaryString(i1));//101111  转换为二进制
int i3 = 0177; // Octal (leading zero)八进制
System.out.println(i3);//127
System.out.println("i3: " + Integer.toBinaryString(i3));//1111111
指数
// Uppercase and lowercase 'e' are the same:
		float expFloat = 1.39e-43f;
		float expFloat2 = 1.39E-43f;
		System.out.println("expFloat: " + expFloat);
		System.out.println("expFloat2: " + expFloat2);
		double expDouble = 47e47d; //'d' is optional
		double expDouble2 = 47e47; //Automatically double
		System.out.println("expDouble: " + expDouble);
		System.out.println("expDouble2: " + expDouble2);
类型转换

除了boolean型,java的基本类型都可以相互转换。但是大的转小的可能丢失精度。

Java allows you to cast any primitive type to any other primitive type, except for boolean, which doesn’t allow any casting at all. Class types do not allow casting. To convert one to the other, there must be special methods. (You’ll find out later in this book that objects can be cast within a family of types; an Oak can be cast to a Tree and vice versa, but not to a foreign type such as a Rock.)

int i = 200;
long lng = (long) i;//cast not required but can be clarify
    
long lng2 = 300;
i = (int) lng2; // Cast required

double above = 0.7, below = 0.4;
System.out.println("(int)above:" + (int)above);//0 截断
print("Math.round(above): " + Math.round(above));//四舍五入

That are smaller than an int (that is, char, byte, or short), those values will be promoted to int before performing the operations, and the resulting value will be of type int.小于int类型都用Int类型进行计算,结果是int型
In general, the largest data type in an expression is the one that determines the size of the result of that expression; if you multiply a float and a double, the result will be double; if you add an int and a long, the result will be long.大类型和小类型计算,会都转化成大类型然后得到计算结果也为大类型。

数值Overflow

但数值过大的时候会overflow,但是不会提示错误,而会运行出一个不想得到的值。

int big = Integer.MAX_VALUE; 
System.out.println("big = " + big); //2147483647
int bigger = big * 4; 
System.out.println("bigger = " + bigger);//-4

Controlling

java 中不允许用其他类型做判断,只能用boolean型
if else, while, do-while, for
do-while用的比较少,for用的最多

在循环或者if中判断必须是boolean,比如while(){}中需要用boolean 来判断而不能用integer值来判断break跳出循环或者switch语句

foreach
public static void main(String[] args) {
Random rand = new Random(47);
float f[] = new float[10];
for (int i = 0; i < 10; i++) f[i] = rand.nextFloat();
for (float x : f) System.out.println(x);//assigns each element of f to x.
    //把数组f中每个元素分配给x

Any method that returns an array is a candidate for use with foreach.任何一个返回array的方法都适合用foreach来进行取值。

 public static void main(String[] args) {
        for (char c : "An African Swallow".toCharArray()) System.out.print(c + " ");
    }

As you’ll see in the Holding Your Objects chapter, foreach will also work with any object that is Iterable. foreach 对于任何iterable的对象都可以使用。

return, break ,continue

return: 终止当前method,也就是所在{}范围

break和continue都是根据循环来说的
break:终止当前循环,退出整个循环Out of loop,或switch
continue:停止当前的iteration,直接跳到开始执行 next iteration

A second form of the infinite loop is for(;😉. The compiler treats both while(true) and for(;😉 in the same way, so whichever one you use is a matter of programming taste. 无限循环while(true)和**for(;😉**一样,具体使用按自己喜好。

Although goto is a reserved word in Java, it is not used in the language; Java has no goto. goto是java保留关键字,但是java不用goto

switch

switch用break来退出该swtich,最后default可以加break或者不加。expression是 integers, byte, short, char, strings and enums.这些类型。通常使用enums它与switch的使用非常匹配。

    switch(expression) {
   case value :
      // Statements
      break; // optional
   
   case value :
      // Statements
      break; // optional
   
   // You can have any number of case statements.
   default : // Optional
      // Statements
      break;//optional
}

无break的情况,这里如果foo=0则他会执行0,1,default都执行一遍,如果foo=1则他会执行1后面的,在java中是有效的,但是尽量不要使用,他不符合习惯。

switch (foo) {
    case 0:
        doSomething();
    case 1:
        doSomethingElse();
    default:
        doSomeOtherThing();
}
exercise
  • 斐波那契数列:第三个数是前两个数之和
public static void main(String[] args) {
        int[] arrayFab = {};
        arrayFab = fibonacci(10);
        for (int temp : arrayFab) {
            System.out.print(temp + ",");//1,1,2,3,5,8,13,21,34,55,
        }

    }

    private static int[] fibonacci(int count) {
        int[] arrayTemp = new int[count];
        int sumTemp = 0;
        for (int i = 0; i < count; i++) {
            if (i == 0) arrayTemp[i] = 1;
            else if (i == 1) arrayTemp[i] = 1;
            else arrayTemp[i] = arrayTemp[i - 1] + arrayTemp[i - 2];
        }
        return arrayTemp;
    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Charles Ray

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值