JAVA SE 基础部分讲解

一.java开发前的了解

1.Java程序运行机制

Java语言既有编译型语言的特征也是解释型语言的特征(java程序必须先编译后解释),是一种特殊的高级语言。

编译型语言:(compile)

使用专门的编译器,针对特定平台(操作系统)将某种高级语言的源代码一次性编译成可被平台硬件识别的机器码(包括机器指令和操作数)并包装成该平台所能识别的可执行性程序的格式,因为是特定平台下的机器码,所以可以脱离环境独立运行,若是移植,则必须根据特定平台进行源代码修改,至少要用编译器重新编译。

特点:    编译生成的可执行性程序可以脱离开发环境,在特定的平台独立运行,运行效率高,若要移植则要重新编译

解释型语言:(interpreted)

使用专门的编译器,对源程序逐行解释成特定平台的机器码并立即执行的语言,不会进行整体的编译和链接处理。解释型语言相当于把编译语言中的编译和解释过程综合在一起完成。每执行一次解释型语言的程序都要进行编译一次,故而效率较低,但跨平台比较容易,只需提供特定平台的解释器。移植是牺牲程序效率为代价的 

2.JVM(Java Virtual Machine)java虚拟机

java程序运行的特点:

java编写的程序经过编译步骤的时候生成的是平台无关的字节码(*.class)文件,必须用java解释器来解释执行(java虚拟机),即由运行java字节码文件的虚拟计算机(java虚拟机)来解释执行,所有平台的JVM向编译器提供相同的编程接口,编译器用来生成虚拟机能理解的代码,交给虚拟机执行。

说白了就是JVM是一个转化器,左边对应着字节码文件,左边对应着特定平台的机器码(不同的操作系统),这就是传说中java平台无关性的体现。

二.java开发Hello world

1.java运行必须条件:

JDK(Java Developer's Kit):java标准版开发包,提供一套用于开发java应用程序的开发包,提供编译,运行java程序所需要的各种工具和资源(java编译器,java运行时环境,java常用类库等),说白了就是一些java程序运行的依托

JRE(Java Runtime Environment):java运行时环境,里面包含了JVM甚至加载器,字节码效验器,以及java的其他环境支持等

1.安装JDK(Java Developer's Kit):本人默认安装到C:\Program Files (x86)\Java\jdk1.6.0_10,《李刚疯狂讲义中》劝谏不能带空格,否则会出现一些未知的问题,建议安装在根目录下。安装完后会有如下的目录

Bin: 存放JDK的各种工具命令,常用的javac,java等命令就放在该路径下

Demo:JDK的演示代码,初学者可学习

JRE:安装的就是运行java程序所必备的JRE环境

Lib:存放的是JDK工具命令的实际执行程序

Sample:JDK提供的一些简单的示例代码,初学

Src.zip:  java所有核心类库的源代码

这里取String的源代码声明如下,就是eclipe中连接源代码之后的底层实现,可不必注意这些,越往后越会发现,Src.zip的牛,这里体现了java的开源

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence
{
    /** The value is used for character storage. */
    private final char value[];

}

2.设置环境变量PATH,CLASSPATH

PATH: 指定命令搜索路径,在cmd命令行下面执行命令如javac编译java程序时,它会到PATH变量所指定的路径中查找看是否能找到相应的命令程序
           配置环境的时候,需要在环境变量添加jdk安装目录下的bin目录增加到现有的PATH变量中

CLASSPATH:指定搜索路径,JVM通过CLASSPTH来寻找类的。就是寻找自己编写.java文件的路径,需要把jdk安装目录下
                  的lib子目录中的dt.jar和tools.jar设置到CLASSPATH中,目录“.”也必须加入到该变量中(告诉Java解释器需要
                  在当前路径下搜索java类)可实现在当前路径下运行非当前路径下的的java程序

JAVA_HOME:它指向jdk安装目录,Eclipse/NetBeans/Tomcat等软件就是通过搜索JAVA_HOME变量来找到并使用安装好的jdk。

注意:

       classpath:中配置尾没有加上;是为了提高阅读性,避免在非当前路径在运行未知路径下的java程序

具体配置如下:(因为Linux操作系统的原因,环境变量区分大小写,Windows不区分)

JAVA_HOME:JDK的安装路径

CLASSPATH:.;%java_home%\lib\dt.jar;%java_home%\lib\tools.jar

PATH:%java_home%\lib;

这是我的第一个HelloWorld

本人犯了个错误

1.CLASSPATH没有正确配置好,可以在cmd中直接用set classpath 直接查看其目录是否正确(set classpath=,;%CLASSPATH%)运行即可出效果

    我在D盘下写的程序,却没有找到正确的路径(编译好的*.class文件的具体位置)在CMD中D:才是转到d盘(或者直接在环境变量中设置正确即可)

---有关CMD的用法,这就不用介绍了,因为主要还是研究java,谷歌一下还是很多的

二.java基础

自我经验感觉基本上每一门语言都有自己的注释,标示符,关键字,变量和常量,数据类型划分,运算符,表达式,语句,数组,方法....感觉这些东西都是很基础的东西,很多课本很愿意介绍这些基本的概念,在此不做个过多的介绍,下面给出自己总结的细节问题

1.文档注释:     

    /*  */是多行注释   

  /**  */是文档注释 

文档注释是用来生成API文档的,API文档用于说明类的属性,方法

开发一个大的文档需要成千上万个类,而且需要很多人参与开发,每个人都会开发一些类,并在类中开发一些方法和属性供人们使用,需要提供一个说明文档说明每个类每个方法的具体使用,也就是通过调用应用程序接口(API)  来编程。API就是用于说明这些应用程序接口的文档

2.用javadoc工具生成自己的API文档 ,javadoc标记(这两项不作过多的介绍,都是一些比较硬性的规定,但是我感觉也是比较重要的) 代码即文档     

3.   注意点:

java语句可以跨行多写,字符串和变量名不能跨越多行

保留字 :goto,const还未使用这两个单词作为关键字,未来会三个特殊的直接量(literal):true,false,null

注意1:如果直接将一个较小的整数常量(在byte或short类型的表数范围内)赋给一个byte或short变量,系统会自动把这个整数常量当成byte或short来 处理         

注意2:如果使用一个巨大的整数常量(超出了int类型的表数范围)时,java不会自动把这个整数常量当做long 类型来处理。如果希望系统把一个整数常量当做long类型来处理,应该在整数常量后面加上一个L作为后缀(强制类型转化的由来)          

注意3:可以把一个较小的整数常量直接赋给一个long类型的变量,并不是因为java会把这个较小的常量当做long来处理,依然会把它当做int来处理,只是这个int类型的值会自动类型转到long类型(隐式转换的由来)

5.数据类型分类:

解释:相对于javaScript(脚本)的无类型语言的只用一个var声明变量,具体类型将根据需要进行数据类型转换,java是一种强类型(strongly typed),也就是说所有的变量必须先声明,后使用,类型限定了变量,表达式的值,好处是,在编译的时候进行更严格的语法检查,从而减少编程错误

java语言支持的类型分为两类:基本类型(primitive type)和引用类型(reference Type)

以上数据的  1字节 = 8位 = -128~127(可表示的数据范围),说白了就是在java中声明后编译的时候会在未使用的内存空间中寻找一块指定大小的空间供此变量使用,这个所谓的空间的大小就有Type来决定了。

这个空间的大小问题又引来两个问题数据的溢出数据类型的转换

  byte i = Byte.MAX_VALUE;
  System.out.println("此时输出的是byte的最大值-->"+i);
  System.out.println("此时输出的是byte的最大值+1-->"+(byte)(i+1));
  System.out.println("此时输出的是byte的最大值+2-->"+(byte)(i+2));
  System.out.println("此时输出的是隐式转化后int类型-->"+(i+1));
  System.out.println("此时输出的是隐式转化后int类型-->"+(i+2));

运行后的效果如下:

用两张图可以解释程序的执行原理:

下面是一些细节总结

     String是个类(正如上面Src.zip源代码中所示),不可继承的类(final修饰)

     把任何基本类型的值和字符串连接运算时,基本类型的值将自动类型转换为字符串类型,虽然字符串不再是基本类型,而是引用类型 

     (如果希望把基本类型的值转换为对应的字符串,可以把一个基本类型的值和一个空字符串进行连接)常用方法

     null可以转换为任意类型(是引用类型中一个特殊的直接量)   

     java中整数型常量的三种表示方式:o开头  8进制  ox开头  16进制  10进制

     字符通常用于表示单个字符,必用 ' '      有三种表示形式    

              1..单个字符指定                ’a’,’9’,’o’        

              2..转义字符表示特殊字符常量    ‘\n’,’\t’        

              3..直接通过unicode值来表示字符常量 ‘\uxxxx’ xxxx代表16进制的整数

     只有浮点类型才能使用科学计数的形式(也可表现出十进制形式必含小数点)   51200 整数  5.12E2 浮点

     三个特殊的浮点数值      正无穷大,负无穷大和非数(用于表示溢出和出错)        

              1...一个正数除以0得到 正无穷大        

              2.. 一个负数除以0得到 负无穷大       

              3..0.0除以0.0或对一个负数开方将得到一个非数。        

              4..正无穷大通过Double或Float的POSITIVE_INFINITY表示       

              5..负无穷大通过Double或Float的NEGATIVE_INFINITY表示        

              6..非数通过Double或Float的NaN表示 

              7..所有正无穷大数值都相等,所有负无穷大数值都相等。而NaN不与任何数值相等,甚至和NaN都不相等 (NaN相当于SQL Server中的null)

              8..只有浮点数除以0才可以得到正无穷大或负无穷大,因为java语言会自动把和浮点数运算的0(整数)当成0.0(浮点数)处理

       强制类型转化(也称缩小转换,我认为这样比较容易理解)Narrow Conversion  语法格式:(targetType)value 

       计算机以补码的形式保留所有的整数    

                1..正数补码和原码完全相等      int 3    二进制  11  补码 11   

                2..负数的补码是其反码加一 ,负数在计算机底层都是以补码的形式存在

                3..反码是对原码按位取反,除了最高位(符号位)保持不变

                   特别规定:-128的补码为10000000,所以有符号字节的补码表示范围为:-128---127

                  -128不在表数范围之内,所以没有反码。 但是-128有补码,8位二进制位补码的表数范围是:-128≤X≤127。

      运算符        算术,赋值,比较,逻辑,位,类型相关运算符 

                +:字符串的连接符 

                /:  如果除法运算符的两个运算符都是整数类型,则计算结果也是整数,就是将自然除法的结果截断取整19/10的结果为1     

               若两个都是整数则除数不能为0     

               若两个运算数有一个是浮点数,或者2个都是浮点数,则计算结果也是浮点数(即允许除数是0,或0.0,得到的结果是正无穷大或负无穷大) 

              %:运算结果不一定总是整数    

                     1.. 因为求余运算也需要进行除法运算,则第二个不能是0   

                     2..有1或2个是浮点数,允许为0或0.0 结果是非数NaN     

                     3..0或0.0对零以外的任何数求余都将得到0或0.0   

      Java复杂的运算符,如需要完成复杂的乘方,开方,可借助于java.lang.Math类的工具方法完成

      赋值表达式是有值的  =:赋值的值就是右边被赋的值   A =  v =  b =  7 ; //支持连续赋值(导致可读性降低,不推荐)

      位运算符 

            & :按位与 

            | :按位或 

            ~ : 按位非 

            ^ :   按位异或 

           << :左位移运算符(被移位的二进制不发生有效位数字丢失)  相当于乘以2的N次方  >> ://

           >>> :右位移运算符  无符号右移运算符  

             注意1:       左移左边舍弃的位中数字通常是无效的,右移右边舍弃的位常常是有效地。  

             注意2:       进行位移运算时不会改变操作数本身的,它只是得到了一个新的运算结果,原来的操作数本身是不会改变的

     比较运算符       

               97=='a';//true       3.0==3;//true    引用类型必须指向同一个对象    

               自动装箱:就是可以直接把一个基本类型的值赋给一个包装类实例 ,由于java是面向对象,即一切皆是对象,数据类型的封装也就变成了类 ,而且封装前后的大小,     运行效率等都发生了变化,这里用到了缓存       

          String instance = new String("黑马");
          String instance2 = new String("黑马");
          System.out.println("这是实例化"+instance==instance2);//false
          String str = "黑马";
          String str2 = "黑马";
          System.out.println("这是体现缓存"+str==str2);//true

        个人观点:以前总是认为这个str是在栈声明的,其后是str2也在栈中声明,声明了两个"黑马",实际上是里面只有一个"黑马",第二次执行,系统会中先检查缓存是否有一个String实例,系统会直接让这个引用指向这个String实例,这个才是真正相同的原因

           --------------------------------------------------------------------------------------------------------------------

             Integer  a=2;         

             Integer  b=2;        

             System.out.println(“两个2自动装箱是否相等:+(a==b)”);  //输出true

             Integer  biga=128;         

            Integer  bigb=128;         

            System.out.println(“两个128自动装箱是否相等:+(biga==bigb)”);//输出false              

      查看java系统的中的java.lang.Integer类的源代码        

   Static final Integer[] cache = new Integer[-(-128)+127+1];        

    Static {           

       //执行初始化,创建-128到127的Integer实例,并放入cache数组        

      for(int I = 0;I < cache.length;I++)         

      Cache[i]  =  new Integer(I - 128);     

    }        

  理解如下:               

           系统把一个-128到127之间的整数自动装箱成Integer实例,放入名为cache的数组缓存起来。既是-128到127之间的整数自动装箱成Integer,实际上是直接指向对应的数组元素(都是同一个数组,所以不全部相等),不在-128到127之间的整数装箱时系统总是会重新创建一个Integer实例  类似的还有String   一种优秀的设计模式 逻辑运算符:用于操作两个布尔型的变脸或常量         

       &&:与(短路与)      前后均ture才ture 否false   

       &: 不短路与,  作用与上相同,但不会短路(总是执行前后两个操作数)     

      ||: 或         前后有一个true就true 否false          

      |: 不短路或   作用与上相同,但不会短路        

      !:非 只需要一个操作数,如果操作数为true,返回false          

      ^: 异或 当两个操作数不同才true    |与|| 的区别           

       int a = 1;           

       int b  = 2 ;   

       if(a<2|b++>1)

      {  

          System.out.println(“a的值是”+a+” b的值是”+b); //结果为a为1  b为3; 若是换成||   结果仅为a为1 (第二个表达式没有机会,有定义可知

      }

  

 

原文地址:https://www.cnblogs.com/nauy/p/2797745.html