java(基础二)

1.System.exit(int status):main方法正常退出时,程序的退出代码为0(通常都不写这句,默认的),表示成功运行了程序,若要返回其他退出代码,使用System.exit方法。System.exit方法的作用是中断虚拟机运行,使程序结束运行。return的作用是退出本方法,返回上一层(调用者)

2.三种注释。注释不会出现在可执行程序中,只是在源码中,是给人看的

            a). // 

            b). /*   */

            c). /**    */可以用来自动生成注释文档

3.强类型:一个变量在确定了其数据类型后,其数据类型就固定了不会变,除非进行强制类型转换操作

   弱类型:数据类型区分没强类型那么严格,如String a=1,在运算操作时,a可以是字符串1,也可以是数字1,而不需要强制类型转换就可以直接参与运算。

4.动态语言:数据类型是在运行时确定的。

   静态语言:数据类型是在编译时确定的。详细解释

5.数据类型:8种基本数据类型,byte(1),short(2),int(4,整形默认),long(8);float(4),double(8,浮点型默认,浮点数是不准确的,精度问题需要特别注意,2.0-1.1并不等于理想中的0.9);char(2或4);boolean(1或4)

boolean(1或4)的理由来源是《Java虚拟机规范》一书中的描述:“虽然定义了boolean这种数据类型,但是只对它提供了非常有限的支持。在Java虚拟机中没有任何供boolean值专用的字节码指令,Java语言表达式所操作的boolean值,在编译之后都使用Java虚拟机中的int数据类型来代替,而boolean数组将会被编码成Java虚拟机的byte数组,每个元素boolean元素占8位”。这样我们可以得出boolean类型占了单独使用是4个字节,在数组中又是1个字节。那虚拟机为什么要用int来代替boolean呢?为什么不用byte或short,这样不是更节省内存空间吗。大多数人都会很自然的这样去想,我同样也有这个疑问,经过查阅资料发现,使用int的原因是,对于当下32位的处理器(CPU)来说,一次处理数据是32位(这里不是指的是32/64位系统,而是指CPU硬件层面),具有高效存取的特点。

6.特殊值:正无穷大,负无穷大,NaN(判断x是否为NaN,Double.isNaN(x))

int.class == Integer.TYPE//true

int.class == Integer.class//false

基本类型的包装类都有三个静态变量BYTES、SIZE、TYPE用来表示对应的基本类型存储所用的字节数,位数和class对象(Boolean只有TYPE,没有BYTES和SIZE,因为java规范没具体指明boolean需要占据几个字节,单独使用时占据4个,boolean数组则每个boolean元素占据1个)

Character类的charCount方法用来判断一个给定的代码点对应的字符是哪种类型的,如果大于等于0x10000则返回2,小于则返回1。对于传进来的代码点参数是否有效,该方法不进行验证,需要调用者自己调用isValidCodePoint方法自行验证

bitCount方法统计数值二进制形式中1的个数

unicode是字符集的名称,utf-8/16/32等是具体的实现方法

7.char字符集和编码方式:utf-16,代码点(代码值,类似于编号)和代码单元(2个字节大小,详见卷一P36-37),每个字符都有唯一的一个代码点(编号),用16位来表示一个代码单元,基本的字符只需一个代码单元,有的字符需要两个代码单元来表示,基本的字符并没有把65536(2的16次方)个编号都用完,还剩下2048个编号,这2048个编号分成两份A(a1~a1024)和B(b1~b1024),每份1024个编号,用两个编号如a1b1来表示基本字符之外的那些字符,这样有1024x1024种组合(如果采取排列的方法,应该可以有A(2048,2)即2048x2047种组合,可以表示更多字符),然后根据有关的算法,每种组合表示一个代码点。string.length()求的是代码单元数,string.codePointCount()求的是代码点数(实际的字符数)

8.类常量:static final修饰

for(;;)是一个死循环,相当于while(true)

9.运算符:&&和||为“短路”方式的逻辑与和逻辑或;三元运算符?:

当&的两个操作数不是boolean型变量时,则进行按位与运算,同理|也是

<<,>>(高位填充符号位),>>>(高位填充0)

原码,反码和补码

数值在计算机中是以补码的形式存储的

一. 机器数和真值

在学习原码, 反码和补码之前, 需要先了解机器数和真值的概念.

1、机器数

一个数在计算机中的二进制表示形式,  叫做这个数的机器数。机器数是带符号的,在计算机用一个数的最高位存放符号, 正数为0, 负数为1.

比如,十进制中的数 +3 ,计算机字长为8位,转换成二进制就是00000011。如果是 -3 ,就是 10000011 。

那么,这里的 00000011 和 10000011 就是机器数。

2、真值

因为第一位是符号位,所以机器数的形式值就不等于真正的数值。例如上面的有符号数 10000011,其最高位1代表负,其真正数值是 -3 而不是形式值131(10000011转换成十进制等于131)。所以,为区别起见,将带符号位的机器数对应的真正数值称为机器数的真值。

例:0000 0001的真值 = +000 0001 = +1,1000 0001的真值 = –000 0001 = –1


二. 原码, 反码, 补码的基础概念和计算方法.

在探求为何机器要使用补码之前, 让我们先了解原码, 反码和补码的概念.对于一个数, 计算机要使用一定的编码方式进行存储. 原码, 反码, 补码是机器存储一个具体数字的编码方式.

1. 原码

原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值. 比如如果是8位二进制:

[+1]原 = 0000 0001

[-1]原 = 1000 0001

第一位是符号位. 因为第一位是符号位, 所以8位二进制数的取值范围就是:

[1111 1111 , 0111 1111]

[-127 , 127]

原码是人脑最容易理解和计算的表示方式.

2. 反码

反码的表示方法是:

正数的反码是其本身

负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.

[+1] = [00000001]原 = [00000001]反

[-1] = [10000001]原 = [11111110]反

可见如果一个反码表示的是负数, 人脑无法直观的看出来它的数值. 通常要将其转换成原码再计算.

3. 补码

补码的表示方法是:

正数的补码就是其本身

负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)

[+1] = [00000001]原 = [00000001]反 = [00000001]补

[-1] = [10000001]原 = [11111110]反 = [11111111]补

对于负数, 补码表示方式也是人脑无法直观看出其数值的. 通常也需要转换成原码在计算其数值.

三. 为何要使用原码, 反码和补码

在开始深入学习前, 我的学习建议是先"死记硬背"上面的原码, 反码和补码的表示方式以及计算方法.

现在我们知道了计算机可以有三种编码方式表示一个数. 对于正数因为三种编码方式的结果都相同:

[+1] = [00000001]原 = [00000001]反 = [00000001]补

所以不需要过多解释. 但是对于负数:

[-1] = [10000001]原 = [11111110]反 = [11111111]补

可见原码, 反码和补码是完全不同的. 既然原码才是被人脑直接识别并用于计算表示方式, 为何还会有反码和补码呢?

首先, 因为人脑可以知道第一位是符号位, 在计算的时候我们会根据符号位, 选择对真值区域的加减. (真值的概念在本文最开头). 但是对于计算机, 加减乘数已经是最基础的运算, 要设计的尽量简单. 计算机辨别"符号位"显然会让计算机的基础电路设计变得十分复杂! 于是人们想出了将符号位也参与运算的方法. 我们知道, 根据运算法则减去一个正数等于加上一个负数, 即: 1-1 = 1 + (-1) = 0 , 所以机器可以只有加法而没有减法, 这样计算机运算的设计就更简单了.

于是人们开始探索 将符号位参与运算, 并且只保留加法的方法. 首先来看原码:

计算十进制的表达式: 1-1=0

1 - 1 = 1 + (-1) = [00000001]原 + [10000001]原 = [10000010]原 = -2

如果用原码表示, 让符号位也参与计算, 显然对于减法来说, 结果是不正确的.这也就是为何计算机内部不使用原码表示一个数.

为了解决原码做减法的问题, 出现了反码:

计算十进制的表达式: 1-1=0

1 - 1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原= [0000 0001]反 + [1111 1110]反 = [1111 1111]反 = [1000 0000]原 = -0

发现用反码计算减法, 结果的真值部分是正确的. 而唯一的问题其实就出现在"0"这个特殊的数值上. 虽然人们理解上+0和-0是一样的, 但是0带符号是没有任何意义的. 而且会有[0000 0000]原和[1000 0000]原两个编码表示0.

于是补码的出现, 解决了0的符号以及两个编码的问题:

1-1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原 = [0000 0001]补 + [1111 1111]补 = [0000 0000]补=[0000 0000]原

这样0用[0000 0000]表示, 而以前出现问题的-0则不存在了.而且可以用[1000 0000]表示-128:

(-1) + (-127) = [1000 0001]原 + [1111 1111]原 = [1111 1111]补 + [1000 0001]补 = [1000 0000]补

-1-127的结果应该是-128, 在用补码运算的结果中, [1000 0000]补 就是-128. 但是注意因为实际上是使用以前的-0的补码来表示-128, 所以-128并没有原码和反码表示.(对-128的补码表示[1000 0000]补算出来的原码是[0000 0000]原, 这是不正确的)

使用补码, 不仅仅修复了0的符号以及存在两个编码的问题, 而且还能够多表示一个最低数. 这就是为什么8位二进制, 使用原码或反码表示的范围为[-127, +127], 而使用补码表示的范围为[-128, 127].

因为机器使用补码, 所以对于编程中常用到的32位int类型, 可以表示范围是: [-231, 231-1] 因为第一位表示的是符号位.而使用补码表示时又可以多保存一个最小值.

10.Math类:Math.sqrt(x),Math.pow(x,a),Math.round(),Math.PI,Math.E,Math.random()返回一个[0,1)之间的浮点数,更精确的还有StrictMath

11.静态导入:import static java.lang.Math.*,也可以静态导入某一个特定的静态数据域或静态方法

12.数值类型转换:不同类型的数值进行运算,会将操作数转换成同一类型再进行计算,

     转换的优先级为double>float>long>int

13.强制类型转换

14运算符优先级和结合性:先看优先级,优先级相同再看结合性,大多数为左结合,少数几个为右结合,如赋值,三元运算符,+=类和一元运算符。三元运算符前面的如果为真,后面的就不会执行了

int a = 1,b = 2,s = 0;

s = a>0?100:b++;

System.out.println(s);//100

System.out.println(b);//2


a+=b+=c相当于a+=(b+=c),

int a = 1,b = 2,c = 3;

a+=b+=c;

System.out.println(a);//6

a?b:c?d:e相当于a?b:(c?d:e)//先执行前面的

int a = 1,b = 2,s = 0;

s = a>0?b:++b>2?200:300;

System.out.println(s);//2

System.out.println(b);//2

15.枚举类型:举例如下

enum Size {S,M,L,XL}

Size s = Size.S;

16.字符串StringString类被final修饰,而且String对象所维护的值是不可变的,对于String s = "hello","hello"才是真正的对象,而且是不可变对象,s只不过是指向这个字符串常量的一个引用。

final修饰变量,如果是基本类型,则变量不能被从新赋值,而且值也不会变;如果是引用类型,则不能再引用(指向不能再改变)其他对象,但是指向的对象本身的内容可以变(不可变类除外)。

final修饰方法,可以被继承,但是不能被重写

final修饰的类,不能被继承,成员变量可以是final的,也可以不是,但成员方法自动为final

不可变类:对象一旦被创建完成,对象的成员变量的值将不能被改变

 如果一个类要被声明为static的,只有一种情况,就是静态内部类

17.String类的API

subString(m,n):包前不包后

equals():注意与==的区别,==比较的是内存地址,即是否为同一个对象,String的equals方法已经重写过了,Object类的equals方法实际上就是==

equalsIgnoreCase()

compareTo()

endsWith(),startsWith()

toLowerCase(),toUpperCase()

length(),codePointCount()

trim(),replace(),format()

注意subString等方法和+产生的都是新的String对象

18.StringBuilder(StringBuffer效率比StringBuilder低,但是线程安全)append和toString方法

String根据字符串本身的内容重写了hashCode方法,StringBuilder和StringBuffer没有,值为内存地址(并非真的内存地址,而是在虚拟机中的内存地址

19.标准输入Scanner in = new Scanner(System.in);

String name = in.nextLine();//next line

String color = in.next();//next word

int age = in.nextInt();//next int

上面的输入是可见的,如果读取密码的话,用下面的(只能在终端,不能使用IDE,否则会报空指针错误,因为IDE占用了console对象,console对象是单例对象)

Console cons = System.console();

String username = cons.readLine("User name: ");

char[] password = cons.readPassword("Password: ");//密码使用数组存储,因为使用字符串不安全

字符串放在常量池,存在的时间长,且不能被修改,使用完后不能马上覆盖掉(直到gc回收),使用完后,需要将数组的值覆盖掉

20.局部变量初始化:不一定要在声明的时候立刻初始化,如

     int a;

     a = 2;这是完全可以的

21.大数值:BigInteger(大整数)和BigDecimal(大浮点数)

    大数值运算不能使用+,-,*,/,%符号,而是使用对应的方法

add    subtract    multiply    divide    mod    compareTo    valueOf

22.数组

    int[] a = {1,2,3,4,5};

    int[] a = new int[] {1,2,3,4,5};

    new int[] {1,2,3,4,5};//创建匿名数组

    int[] a = new int[10];//数组长度可以是变量 int n = 10;int[] a = new int[n];

    创建一个整数数组时,所有元素初始化为0;boolean数组元素都为false;对象数组元素都为null

23.一些接口

    Formattable    

    Iterable

24.一些API

    Arrays.toString(a)//将数组a转换成字符串(形如[1,2,3])

    Arrays.deepToString(a)//将二维数组转换成字符串

    Arrays.copyOf(a,length)//将a数组的每个元素拷贝到长度为length的新数组,

    若length<a.length,则拷贝前面的;若length>a.length,则多余的用默认值填充

    Arrays.sort(a)//使用快速排序法对数组进行排序

    Arrays.binarySearch(a,b)//返回b在数组a中的索引值,若a中没有b,则返回一个负数r,-r-1是保持a有序b应该插入a中的位置

    Arrays.equals(a,b)//比较两个数组是否相同,如果长度相同,且a[i]和b[i]相同,则返回true

    Random:

    nextInt(n):生成一个0~n-1的随机数

25.for each

    for(type variable : collection) {...}//collection为数组或者实现了Iterable接口

    for(int x : a) {System.out.println(x);}

26.main方法的参数String[] args的意义

27.类之间的关系

    依赖(uses-a):类A的方法操作类B的对象,A只是单纯的new一个B的对象,然后调用对象的方法

    聚合(has-a):类A的对象包含类B的对象,即A数据域是B类型的如兔子有腿

    继承(is-a):类A继承于类B

28.有的类没有数据域,只有方法域(如Math)

29.除了构造方法和类同名,其他的方法也可以跟类的名字一样

30.对象变量和对象:一个对象变量并不包含一个对象,它只是对象的引用,new操作符的返回值就是一个引用

31.Date和GregorianCalendar,前者表示的是一个时间点(距离1970年1月1日00:00:00的毫秒数),后者是日历表示,是时间点的表示,同一个时间点表示形式有多种

GregorianCalendar月份从0开始计数

二者之间的转换Date time,GregorianCalendar calendar;time = calendar.getTime(); calendar.setTime(time)

32.隐式参数this:类的方法(静态方法除外)有个隐式(implicit含蓄的)this,指向调用该方法的对象本身

33.更改器方法的好处:封装性,而且可以在修改前进行错误检查

34.访问器方法:在编写访问器的时候,如果访问的字段是一个对象,那不应该返回该对象的引用(根据实际情况决定),因为返回对象的引用使得该对象可以被外面的程序修改,破坏了数据的私有性,而应该先对该对象进行克隆(深克隆),再返回克隆对象,当然像String类型的不可变对象除外,因为String对象不能被修改

35.一个方法可以访问该方法所属类的所有的对象的私有数据,如

    class A {

         private String name;

         public boolean myEquals(A other) {

                    return name.equals(other.name);

                }

    }

当执行harry.equals(boss)的时候,equals方法不仅访问了harry的name,还访问了boss的name

36.final修饰数据域的时候,应该用于基本类型(primitive)或不可变类(如String,String之所以是不可变类,不是因为有关键词final修饰,而是String对象维护的值不可变,String对象维护着一个final修饰的char[]),对于可变的类会造成混乱。注意两种变:对象变量所指向的对象发生改变(堆中的对象本身改变),对象变量的指向发生改变(对象变量本身的值变了),指向了其他的对象(详见卷一p115)

37.静态域(static修饰又称类域),静态常量(static final修饰),静态方法(不能访问自身类的非静态属性和非静态方法,可以访问自身类的静态域和静态方法)

38.java函数传参总是按值调用,方法得到的是所有实参值的一个拷贝,并不能修改实参值(卷一p121)

39.构造器没有对类的数据域进行初始化的话(不良的习惯),数据域会有默认的初始化值,数值为0,布尔为false,对象引用为null,这是和局部变量的区别,局部变量必须明确的初始化

40.如果一个类没有编写构造函数,会自动提供一个无参数的构造函数,所有的数据域会被默认初始化;但是如果编写了构造函数,那就不再自动提供构造函数

41.构造函数的形参命名技巧:a.使用数据域一样的名字,方法内添加this区分;b.数据域的名字+前缀a,如数据域为name,形参就用aName

42.构造器中调用另一个构造器:在一个构造器中使用this(...)的形式调用另一个构造器(必须放在第一句)

43.数据域的初始化:构造函数中初始化,声明的时候初始化,初始代码块中初始化

44.初始化块(卷一p130-131):包在一对花括号中的代码{...},每次构造对象的时候都会执行一次

45.静态代码块(卷一p131):static{...},只在类第一次加载的时候执行(所以一个类没有main方法也能执行,记得在静态代码块最后加一句System.exit(0),否则报没定义main方法的错误信息)

46.执行顺序

    ①静态代码块(类第一次加载执行,只执行一次)和静态数据域初始化——数据域默认初始化——按照声明的顺序或初始化块的顺序执行声明时的初始化(如果有的话)和初始化块——如果构造器中第一行调用了另一个构造器A,则执行构造器A,再执行本构造器

    ②父类静态代码块和静态数据域初始化——子类静态代码块和静态数据域初始化——父初始化(非静态)——父构造器——子初始化(非静态)——子构造器

47.finalize方法

48.如果在源文件头没有package语句,则这个类放在一个没有名字的默认的包中

49.如果没有指定public或private,那么可以被同一个包中的所有方法访问(包可见)

50.一些安全机制:JDK实现者禁止类加载器加载用户定义的包名以"java."开头的类。用户可以使用包密封机制,将一个包密封起来,就不能再向这个包添加类了

51.呵呵,国家法律为啥要绑定微信?

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

推荐阅读更多精彩内容

  • 这是16年5月份编辑的一份比较杂乱适合自己观看的学习记录文档,今天18年5月份再次想写文章,发现简书还为我保存起的...
    Jenaral阅读 2,731评论 2 9
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,567评论 18 399
  • 有没有一种方法,让没有一点电脑基础的朋友也能批量加到真实、活跃、本地的宝妈好友? 答案肯定是有的,方法也很简单,只...
    临界点人阅读 2,895评论 0 0
  • 【每日一诗】 天净沙·冬 元代:白朴 一声画角谯门, 半庭新月黄昏, 雪里山前水滨。 竹篱茅舍, 淡烟衰草孤村。 ...
    灵宝王欢凤阅读 209评论 4 2
  • 某日,与姐姐一起出门。在等地铁时姐姐说在地铁门里看到一帅哥。我说在哪在哪?姐姐说后面后面。我往后瞧了瞧。没有啊!我...
    99姑娘阅读 181评论 0 0