转-Java基础全面解析——Java语言基础

转自CSDN博客,u010425776http://m.blog.csdn.net/u010425776/article/details/46854199

高级编程语言的组成:关键字、标识符、注释、常量与变量、语句、函数、数组,下面一一介绍各个组成元素。

 

a)  关键字

i.  定义:关键字是一些英文单词,但java中有特殊含义,自定义的变量不能和关键字重名。

ii.注:关键字一般都小写。

 

b)  标识符

i.  定义:标识符就是自定义的变量名

ii.规则:26个字母大小写、0-9_$组成

iii.1不能以数字开头

iv.2:不能含有关键字(其中const和goto被保留但未被使用)

 

c)  注释

i.  注释在编译时全被删除。

ii.作用:注解程序和调试程序。

iii.    注释能用JDK/bin中的javadoc工具去提取成软件说明书。

 

d)  常量和变量运算符

i.  类型转换原则:占用内存小的类型向占用内存大的类型进行转换,这样能保证不丢失精度。

ii.注:只要是整数就是int型!!!浮点数默认为double赋值运算会进行自动强转,纯算数运算也会自动强转,但算数运算且含有变量时不会自动强转

iii.注:JVM的自动强制类型转化只是针对需要强制类型转化的语句,如:byte b = 4;若是自动类型提升,JVM根本不会检查什么,直接提升就行了,如:byte b = 4;int a = b +10;

1.  Bytea = 4;实际上JVM首先会检查4这个int型的数字是否超过byte的长度,若没超过则自动进行强制转化,若超过了就报错。

2.  Bytea = 4+5;

     JVM发现45都是int型,那么进行自动检查,看一下9转换成byte后是否丢失精度,发现不丢失,则直接自动进行强制类型转化。但,

     byte a = 4,b = 5;

      Byte c = a + b;//此时会报错!

第一句话JVM也会首先检查45能否转化成byte类型,发现可以,就自动强转;但第二句话,JVM也会自动检查,但发现等号后面出现变量,即使该变量是的int类型能转化为byte,但此时也会报错!

3、整型和浮点型
类型              存储需求      bit   取值范围      备注
boolean        1字节          1*8      falsetrue

char             2字节          2*8
short            2字节           2*8    3276832767

int                4字节           4*8 
long             8字节           8*8

float              4字节           4*8                  float类型的数值有一个后缀F(例如:3.14F)
double          8字节           8*8                   没有后缀F的浮点数值(3.14)默认为double

  

综上:

a)  只要是数字就是int

b)  强制类型转化:所占内存大的类型赋值给所占内存小的类型

c)  自动类型提升:所占内存小的类型赋值给所占内存大的类型

d)  但大内存类型赋值给小内存类型的时候若不使用强转,JVM会自动判断大内存类型转换后是否会丢失精度,若不丢失精度,则自动强制类型转换,否则会报错。但这种赋值方法只适用于等号右侧是具体的值,不能使变量。

i.  Bytea = 10;//进行一次自动的强制类型转化

Ii. Byteb = 10;

    Byte a = b;//右侧是int型的变量,无法进行自动的强转

iii. Byteb = 10;

   Int a = b;//这是自动类型提升,不是强制类型转化,肯定不会丢失精度,这时候等号右侧是变量无所谓。

iv.自动类型提升:将所占内存小的类型——>所占内存空间大的类型

1.  Int a = 3;

2.  Byte b = 5;

3.  a =a + b;//发生一次自动类型提升

v.  强制类型转换:将所占内存小的类型——>所占内存大的类型

1.  byte c = 3;//强制类型转换

2.  c = c + 5;//报错:这里的5int型四个字节,3byte型一个字节,最后的结果要求是byte型,如果不进行强制类型转换就会报错。

3.c = (byte)(c + 5);//强制类型转换:只截取int型最低位一个字节,若一个数的二进制高于四位,那么经过强制类型转化后也只有4为,就会丢失精度。

vi.ASKII码表:二进制与字符对应表。

1.  0-48

2.  a-97

3.  A-65

vii.    Unicode国际标准码表:java使用的是Unicode码表,该表兼容任何国家的语言。

viii.  Charint转化

1.        System.out.println('a');//输出a

2.        System.out.println(97);//输出97

3.        System.out.println((char)(97));//强制类型转化int—>char

4.  注:charint短,所以charint要强制类型转化,而intchar只需自动类型提升。

e)  语句

i.  运算符共五种:算数运算符、赋值运算符、比较运算符、逻辑运算符、位运算符

ii.算数运算符 + -* / %(求余/取模) ++ --

1.  取模:正负只与前面那个数有关

2.  任何数%2结果都是0/1,可以实现开关交替运算

3.  a =i++运算过程

a)  Temp= i ;

b)  i =i+1;

c)  a = temp;

例:

Int i = 3;

I = i++;

System.out.println(“i=”+i);//i3

Temp = i; //temp = 3;

I = i+1;//i=4;

I = temp;//i=3;

iii.    赋值运算符=+=-=*=/=%=

1.  将左右两边运算后的值赋给左边

2.  例:

Short  s = 3;

S += 4;

S = s + 4;

问: S += 4;S = s + 4;这两句话有什么区别?

答:Short s = 3;这是讲int转换成short,需要进行强制类型转化,用自动类型提升的方法赋值时,JVM自动检查了一下,发现3这个int型值转化成short后不会发生精度丢失,因此就自动默默地转化了;但执行S = s + 4时,由于等号右侧有int型还有变量,JVM不会自动强转,报错!而S += 4不会报错,因为他是赋值运算,和Short s = 3一样,只要不丢失精度JVM都会做自动强转。

 

iv.比较运算符==!=><>=<=instanceof

比较运算符结果是boolean

“Hello”instanceof String 判断Hello是否是String类的对象

 

v.  逻辑运算符&|^!&&||

1.  ^:异或

只有真真=假,其余和或|一模一样

2.  &&&的异同

a)  同:他们的运算结果都是一样的

b)  异:a>0&a<10两条式子都要运算

a>0&&a<10左边一旦为false,右边不计算了,结果就是false

c)  &&优点:&&&效率高了一点点

3.  |||的异同

a)  同:他们的运算结果都是一样的

b)  异:a>0|a<10两条式子都要运算

a>0||a<10左边一旦为true,右边不计算了,结果就是true

c)  ||优点:|||效率高了一点点

vi.位运算符>><<>>>&|^~

1.  位运算符是针对二进制进行的

2.  与运算&

Java中只要是数字就是int型。

一个int四个字节(4bit),一个比特=8个二进制位。

然后上下两行分别作与运算,得出的结果转化为十进制就是6&3的值。

3.  异或运算^

a)  特点:对同一个二进制异或两次得到原始二进制。因此可用于对二进制文件加密解密

4.  取反运算~

a)  取二进制数的反码。

5.  左移运算<<

将二进制向左移动两位,高位丢掉,低位补足。

左移运算的运用:A左移几位就是A*2的几次方。

                              3<<10就是:3*210次方

6.  右移运算>>

               3>>10就是:3 / 210次方

    注:>><<运算都可以带正负,正负根据第一个数字的正负。

    因此,二进制的最高位是符号位,右移之后最高位应当说原二进制的最高位。

 

7.  无符号右移运算>>>

>>一样,只不过没有正负,因此,向右移动之后最高位用0补。

 

8.  三元运算符(条件表达式)?表达式1:表达式2

条件为true,执行表达式1

条件为false,执行表达式2

 

vii.  局部代码块

1.  局部代码块中声明的变量只在该代码块中有用,出了代码块该变量内存空间就被释放。

2.  局部代码块可以让程序员决定变量的生命周期,主动地释放变量内存,从而节省空间,提高性能!平时编程要注重这个!

3.  局部代码块中的局部变量生命周期:在局部代码块中被创建,到“}时结束。

注:函数中的其他局部变量只有当函数执行完后,函数从方法区中消失,紧接着函数中所有的局部变量从栈内存中消失。

 

viii.  判断语句if-else

ix.选择语句switch-case

switch(表达式)//表达式只支持:shortintbytecharString、枚举

{

case 取值1

执行语句;

break

case 取值1

执行语句;

break

default

执行语句;

break

}

注:switch-case语句中只有一个大括号。

注:default可以随便放,不管放哪儿都是最后一个执行。

注:按照case的摆放顺序执行,若都不满足最后找default

注:switch两种结束方式

1.执行到break结束

2.全部执行一遍后结束,因此最后一个casedefaultbreak可以不写!

注:

int x =3;

switch(x)

{

default:

System.out.println(“c”);

case 1:

System.out.println(“a”);

case 2:

System.out.println(“b”);

}

x=3先判断case1case2发现都不匹配,就执行default,此时已经找到了一个满足条件的东西了,而且那个里面没有break,此时不会再判断case是否满足条件,而是依次执行,直到遇到break或执行完一遍switch-case。因此现在输出:cab

注:提高switch-case复用性

case 3:

case 4:

case 5:

System.out.println(“lala”);

break;

x=345都执行同一条语句。

3.switch可以判断String(其实是转化为了hash值),和c不同(只能是整数)

 switch (status) {

            case "killed":

                break;

            case "alive":

                break;

            default:

                break;

            }

 

 

x.  转义字符

1.  用于字符串中“hello\nworld”,且转义字符都是针对\后的字符进行的。

a)  \n:回车

b)  \t:制表符

c)  \b:退格

d)  \r:按下回车键

i.  windows中回车符: \r\n

ii.linux中回车符: \n

e)  \”:在字符串中使用双引号

f)  \\:\

 

xi.break

1.  break:跳出(终止)

2.  break运用范围:switch、循环语句(forwhiledo-while)。

3.  break后不能再写语句了,写了会报错,因为break后语句永远也执行不到。

4.  for(inti = 0 ; i<3 ; i++){

if(i>1)

break;//break只作用于循环或switch,不作用于if,因此跳出for循环

}

5.  若有多层循环,break只跳出离他最近的循环。

6.  跳出指定循环

for(int i = 0 ;i<3 ; i++){

for(int j = 0 ;j<3 ; j++){

break;//默认跳出最内层循环

}

}

wangcai:for(inti = 0 ; i<3 ; i++){

xiaoqiang:for(intj = 0 ; j<3 ; j++){

Break wangcai;//跳出指定循环

}

}

 

xii.    continue

1.  continue:退出本次循环,进入下一次循环。continue后的语句不执行了。

2.  作用范围:循环(forwhiledo-while

3.  continue单独存在时后面不能有任何语句,否则会报错,因为continue后的语句永远也执行不到,continueif中,if外可以紧跟其他的语句,如:

for(int i = 0 ;i<5:i++){

continue;//错!!!

System.out.println(“xxx”);

for(int i = 0 ;i<5:i++){

if(i%2==0)

continue;//正确!

System.out.println(“xxx”);

}

4.  结束本次循环,进入指定的循环

wangcai:for(inti = 0 ; i<3 ; i++){

xiaoqiang:for(intj = 0 ; j<3 ; j++){

Continue wangcai;//进入指定的循环

}

}

 

 

f)  函数

i.  编译和运行的过程

javac XXX.java:启动了java的编译器,将xxx.java编译成xxx.class文件;java xxx:启动了java虚拟机,运行xxx这个java程序。-运行时,JVM首先找main函数,找不到报NoSuchMethedError,找到将main函数入系统栈,执行到add方法时,再将add方法入栈,计算完结果返回给main函数,add出栈,这时候再执行main函数。

ii.函数重载

1.  同一个类+函数名相同+(参数类型不同or参数个数不同)+返回值类型不同

2.  函数重载有个原则,函数重载是根据函数名和形参类型寻找合适的函数,若符合这两个条件却找到了两个函数,会报错。因此,不能出现有相同函数名和形参的函数。

 

 

g)  数组

i.  定义

1.  第一种定义方式int[] a = new int[3];

ii.JVM内存的划分

 

根据《Java虚拟机规范》的规定,运行时数据区通常包括这几个部分:程序计数器(Program Counter Register)Java(VM Stack)、本地方法栈(Native Method Stack)、方法区(Method Area)、堆(Heap)

 

 

 

1.  程序计数器

2.  本地方法区:调用操作系统的方法。

3.  方法区(数据共享区)

a)  方法区分为静态方法区、非静态方法区

b)  静态方法区存放静态函数、静态成员变量

c)  非静态方法区存放非静态函数、类

4.  栈内存

a)  存储局部变量变量所属的作用域运行结束,该变量就自动释放空间。(forwhiledo-while、函数、局部代码块中的变量都是局部变量)

5.  堆内存

a)  存储数组和对象和成员变量(其实数组就是对象)

b)  每一个对象都有首地址。

c)  publicstatic void main(String[] args){

int[] arr = new int[3];

}

执行main函数前JVMmain函数开辟一块内存空间,执行int[] arr时在main函数的栈内存中新建一个int类型的引用;接着执行new int[3],在堆内存中开辟一块连续的内存空间,堆内存中的对象都有首地址,=即为把堆内存的首地址赋给arr这个int类型的引用,从而建立起了从引用名到对象间的联系。

arr[2]=80即把堆内存中数组的值改为80

arr = null即把arr所对应的地址去掉变为null,即把箭头删掉,此时堆内存中的对象没有变量引用它,就变成了垃圾,等待JVM自动回收。

public static void main(String[] args){

int[] x = new int[3];

int[] y = new int[3];

x[0]=9;

y[0]=34;

}

进一步:x = y;   y = null;

xy指向了同一个对象。

 

6.  第二种定义方式int[] a = new int[]{89,20,300};

7.  第三种定义方式int[] a = {89,20,300};

8.  选择第一种定义方式:需要一个容器,知道容器的大小,但不明确容器中的数据。

选择第二、三中定义方式:需要一个容器,而且数据已知。

  三种方式左侧都不变。

 

h)  二维数组

i.  定义方法一:int[][] a = new int[3][2];

ii.内存分配过程

二维数组本质:一个大一维数组+n个小一维数组,大数组存放n个小数组的首地址,小数组存放数字。

首先执行main函数,JVMmain函数分配栈内存空间,执行int[][]a时在main方法栈中为局部变量a开辟一块内存空间初始化值为null。接着执行new int[3][2],首先在堆内存中开辟3个连续的空间,并且在这个三个空间中存放小数组的起始地址;紧接着分别开辟三个一维数组,并将起始地址赋给大数组,最后将大数组的起始地址赋给栈内存中的a

iii.    定义方法二

1.  先给大数组初始化,在分别给小数组初始化

int[][] arr =new arr[3][];//只给大数组分配3个连续空间

arr[0] = newint[2];

arr[1] = newint[1];

arr[2] = newint[3];

2.  注:二维数组中每个小数组长度可以不一样。

iv.定义方法三

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

 

v.  数组的输出

1.  int[]arr = new int[3];

System.out.println(arr);//输出:[@c1f3fe

注:输出的是这个一维数组的首地址,[表示它是一维数组,@后面的是地址的哈希值。

System.out.println(arr[0]);//输出:值

2.  int[][]arr = new int[3][2];

System.out.println(arr);//输出:[[@c1f3fe

注:[[表示二维数组

System.out.println(arr[0]);//输出:[@f7s8d

System.out.println(arr[0][0]);//输出值

3.  int[][]arr = new int[3][];

System.out.println(arr);//输出:[[@c1f3fe

注:[[表示二维数组

System.out.println(arr[0]);//输出:null

System.out.println(arr[0][0]);//发生空指针异常!

注:int[][] arr = new int[3][]这种定义方式只给大数组分配内存,未给小数组分配内存,因此访问小数组时出现空指针异常!

 

 

 

 

 

 

 

练习

1.高效计算2*8

乘法其实是二级制相乘,并且和十进制乘法法则一样。

2*8效率低,因为在底层进行了多次相乘和相加。

2 * 8 = 2 * 2的三次方,就是2<<3。这种方式效率高,不进行相乘相加操作,只要向左移位即可。

 

2.将两个值互换,不借助第三个变量

法一:

int a = 3,b = 4;

a = a+b;

b = a-b;

a = a-b;

弊端:若两个int长度过大,相加之后会超出int长度,从而精度丢失。

 

法二:

int a =3,b=4;

a = a^b; //

b=a^b;//a^b^b

a=a^b;//a^b^a

注:异或具有交换律:a^b^b = b^a^b=a

 

posted @ 2017-09-15 11:10  0402zhuhui  阅读(168)  评论(0编辑  收藏  举报