Java入门和概述

1、Java分类
    Java SE:Java Standard Edition(原来称J2SE,Java 2 Platform, Standard Edition),java标准版本,是JDK、JVM以及Java标准API的合集,是ee和me的基础。
    Java EE:Java Enterprise Edition(原来称J2EE),java企业版本,基于SE的一套接口规范(协议, API, 服务),发行商依据这些接口规范实现自己的框架,  比如现在常用的Java开发三大框架Spring、Struts和Hibernate,而它们中又包含了很多开发组件,例如:Servlet,JSP,JDBC、JSTL。ee用来做企业级应用,主要是Java Web,具体为分布式、多层次、以组件为基础、以Web为基础的应用。
    Java ME:Java Mobile Edition(原来称J2ME),java移动版本,它为移动设备(手机、PAD等)提供了基于SE的开发平台及api合集。由于后来有了安卓,所以手机移动开发现在大都用的是andriod sdk和框架,而不是ME。 

    Java由Sun创造,JCP是Java标准委员会,JSR是Java标准规范,Java SE9的主要规范是在JSR 379文件中。由于Sun被Oracle收购,所以Sun JDK也就是Oracle JDK, IBM根据JSR还实现了自己的IBM JDK,后来Sun又推出了开源的Open JDK。


2、Java运行及开发

    编译型语言:指针对不同操作系统平台,使用编译器一次性生成可在该平台运行的机器码,并将其封装成该平台能识别的可执行程序,比如C/C++。

    解释性语言:指使用专门的解释器对代码解释成特定平台的执行码并立即执行,相当于执行程序的时候再进行编译,所以效率较低,比如python。    

    JAVA SE可以分为四个主要部分:JRE、JVM、JDK和JAVA语言,要运行java程序,必须使用JVM,JVM包括在JRE中,所以又必须安装JRE,要开发Java程序需要先获得JDK。

    JVM:Java Virtual Machine即Java虚拟机,Java不同于一般的编译语言和直译语言(解释性语言),它首先将源代码编译成字节码文件(.class文件,又称位码文件),然后依赖各种不同平台上的JVM来解释字节码从而执行程序,这就实现了“一次编写,到处运行”的跨平台特性,即JVM使Java可以跨平台。当使用java命令运行一个java程序的时候就会启动一个java虚拟机进程对该字节码进行加载解释和执行(可以不生成可执行文件直接运行),字节码文件就是JVM的可执行文件,JVM负责与底层系统沟通和管理java程序的各种资源。

     不使用字节码其实也可以实现跨平台,即JVM直接解释源码文件,这就像Ruby或Python一样,执行ruby / python命令实际是把源码编译到字节码然后再解释执行。Java显示使用字节码的好处是字节码更便于JVM读取,所以解析速度更快,可以在编译时提前做编译优化,还可以在字节码文件中增加版本信息,字节码比源码也更加紧凑,文件尺寸更小,方便网络传输,字节码也可以由其他语言生成,如scala。

     为了能运行JAVA程序必须要有JVM,而JVM包括在JAVA执行环境(JRE)中,所以又必须安装JRE。(由于Java编译器和虚拟机的不同对Java代码的性能影响比语言本身的影响大的多,所以统一讨论Java的程序的性能经常是有误导性的,比如在同样的硬件上,不同时期的JDK版本的性能差距很大,即使是在同一时期,不同公司的JDK和JRE的性能也不一样,比如SUN、IBM、BEA等公司都有自己开发的JDK和JRE)。

    JRE:Java Runtime Environment,即Java运行环境,包括JVM、字节码校验器、类加载器、基础类库(Java SE API)等。

    JDK:Java SE Development Kit即java se开发包,这是开发JAVA程序必须使用的,包含javac、java、javadoc等工具程序,而且也包含了JRE,这样才能执行java程序。Java EE也有对应的软件开发包Java EE SDK。编写java程序才需要JDK,如果只需要执行java程序的话只要安装JRE就可以了,因为需要JVM和Java SE API。

    Java EE适用于开发分布式、多层次、以组件为基础、以Web为基础的应用,比较熟悉的技术有JSP,Servlet, JavaMail, Enterprise JavaBeans(EJB)等,在做企业项目的时候java ee和其衍生出来的spring提供的框架使开发更加方便、快捷和稳定。 Java EE SDK就是Java EE Software Development Kit,即java ee开发包。

    常用的java IDE有Eclipse、NetBeans、IntelliJ,构建工具有Ant、项目工具有Maven或Gradle。

3、编写Java程序应注意的几点

    大小写敏感:Java是大小写敏感的,这就意味着标识符Hello与hello是不同的。 

    标识符规则:类名、变量名、方法名这些标识符只能以字母、美元符$、数字、下划线_组成,且不能以数字开头。

    类名:对于所有的类来说,类名的首字母应该大写。如果类名由若干单词组成,那么每个单词的首字母应该大写,例如 MyFirstJavaClass。

    方法名:所有的方法名都应该以小写字母开头。如果方法名含有若干单词,则后面的每个单词首字母大写,例如myFirstJavaMethod。

    源文件名:如果源文件里定义了一个public类,那么这个public类名必须与该源文件的名称相同,所以一个java源文件里最多有一个public类或接口(切记Java是大小写敏感的),文件名的后缀为.java。(如果文件名和类名不相同则会导致编译错误)。

    字节码文件:编译生成的字节码文件总是以源文件中类名作为文件名,并以.class后缀。

4、编译和执行Java程序

    以下为最简单的一个java程序,java规定所有的程序代码都必须定义在类中:

//HelloWorld.java

public class HelloWorld
{
	public static void main(String[] args)
	{
		System.out.println("hello world!");
	}
}

  当我们下载和安装完JDK后就可以使用JDK中的javac命令来编译java代码文件为字节码文件,使用java命令来启动JVM解释java字节码和执行程序。首次使用javac或java命令的时候可能会失败,因为cmd不知道javac程序的位置,我们可以通过设置PATH环境变量来添加指令目录,Windows下可以选择计算机-属性-高级-环境变量,然后在PATH下新建一个javac所在目录的变量值。也可以新建一个JAVA_HOME的环境变量,其值设置为jdk的安装目录,然后在PATH下新建值%JAVA_HOME%\bin。Linux下进入home路径编辑.bash_profile文件,如:PATH=.:$path:$home/BIN:/HOME/jAVA/JDK1.8.0/bin,其中的$PATH用来引用原来的PATH变量值,冒号: 用来区分多个路径,然后还要在文件最后添加export PATH来到处PATH环境变量,最后是重新登录Linux或执行source .bash_profile命令来让新设置的PATH变量生效。  设置好PATH环境变量后可以使用java -version命令来测试JDK和环境变量是否设置成功。

   编译java代码文件以生成字节码文件:进入cmd,输入 javac -d 目标文件夹 源文件,如 javac HelloWorld.java 为编译当前目录下的源文件HelloWorld.java,并将生成的.class字节码文件保存在当前目录,javac -d dest src/Test.java为编译当前src下源文件Test.java到当前dest目录下(dest目录不存在的话会自动生成)。

    如果要编译的当前文件HelloWorld.java中使用到了其它文件中的一个自定义的类Foo,如果使用的是该类的源码文件的话,可以将Foo类源码放到HelloWorld所在目录中,或者使用-sourcepath来指定Foo类所在目录,如javac -sourcepath C:\java\classes HelloWorld.java 表示编译当前目录下HelloWorld.java文件,HelloWorld中使用到的其它类的源码从C:\java\classes中搜索,这样HelloWorld字节码会在当前目录生成,Foo类的字节码会在C:\java\classes下生成。编译的时候如果HelloWorld源码文件与Foo类源码文件不在同一目录,默认生成的字节码文件也就不在同一目录,如果编译的时候加上-d来指定字节码生成目录的话,则HelloWorld和Foo类字节码都会生成在这一个目录。如果编译的时候还没有该类的字节码的话会生成,有的话会自动更新。如果使用的不止是一个类而是了好几个类,而这些类中有的已经生成了字节码文件,有的还没有生成,每次编译默认都会重新编译这些类,我们可以在编译的时候加上-cp,如javac -sourcepath C:\java\classes -cp C:\java\classes HelloWorld.java,这样如果上次编译后该类的源文件没有修改就不会再重新编译该类而是直接使用原来生成的字节码。

    如果要编译的当前文件HelloWorld.java中使用到了其它文件中的一个自定义的类Foo,如果使用的是该类的字节码文件,可以将该字节码文件放到与HelloWorld.java相同目录中,然后HelloWorld.java所在目录执行javac HelloWorld.java来编译字节码到当前目录。也可以通过-cp指定使用的字节码目录:javac -cp 字节码所在目录 HelloWorld.java,这样HelloWord字节码就在当前目录生成了,还可以通过上面说过的javac命令的-d选项生成HelloWorld字节码的目录。还有一种不用将Foo字节码放到HelloWorld.java目录下的编译方法,那就是将Foo字节码所在的目录设置到CLASSPATH环境变量中,然后进入HelloWorld.java目录后直接执行javac HelloWorld.java。

    启动JVM解释字节码并执行java程序:有三种方法,后面两种方法可以不进入字节码所在的目录来执行指定的字节码:①、进入字节码所在目录,输入java 类名,eg:java HelloWorld 为执行当前目录下的HelloWorld类(HelloWorld.class字节码文件)。如果HelloWorld中使用到了另一个类的话,将该类的字节码放入HelloWorld字节码目录即可。②、使用-classpath(缩写为-cp)指定使用的字节码目录,,如java -classpath C:\java_class HelloWorld 为执行C:\java_class下的HelloWorld类,可以使用分号 “;” 指定在多个目录下搜索类,eg: java -classpath .;C:\java_class HelloWorld 为执行HelloWorld类,HelloWorld类在当前目录和C:\java_class下依次搜索。如果HelloWorld中使用到了另一个类Foo的话,执行java命令的时候要使用-cp来指定要解释的类字节码所在目录和使用的Foo类字节码所在的目录,如java -cp.;Foo类字节码所在目录 HelloWorld(当前在HelloWorld字节码所在目录)。可以看到,如果使用-cp的话,即使当前在HelloWorld字节码所在目录,-cp中也要加上.以指定所有字节码所在的目录。③、设置系统的环境变量CLASSPATH为字节码所在的目录,需要注意的是设置了CLASSPATH后JRE就只会在环境变量的目录下搜索字节码文件,而不会在当前目录下搜索java类,可以在CLASSPATH值中添加.以增加当前目录到环境变量,如:.;C:\java_class。另一个需要注意的是环境变量CLASSPATH和-cp只能使用一个,即如果我们使用了-cp的话环境变量就不起作用了。补充一点,在命令行下引用环境变量的值的方法为:%EVN_VALUE%。

    在Eclipse中的话想要使用别人的类的话可以将类的源码文件放到同一目录下(这时候Eclipse会自动添加该文件名到项目组织目录),或者右键项目-build path-configure build path-source-link source-选择字节码(包)所在的目录。如果别人提供的是字节码文件的话,右键项目-build path-configure build path-libraries-Classpath-add External Class Folder-选择字节码文件所在目录。如果别人提供的是jar包的话,右键项目-build path-configure build path-libraries-Classpath-add external jars-选择jar文件。查看和设置Eclipse使用的JDK的话为右键项目-build path-configure build path-libraries。

    在IDEA中的话想要使用别人的类的话可以将类的源码文件放到同一目录下(这时候IDEA会自动添加该文件名到项目组织目录),或者右键项目-open moudle settings-modules-Sources-Add Content Root。如果别人提供的是字节码文件或jar包的话,右键项目-open moudle settings-modules-Dependencies-加号-JARs or Directories-选择字节码所在目录。查看和设置IDEA使用的JDK的话为右键项目-open moudle settings-Project-edit。

    使用java程序来执行java字节码实际上是启动jvm来解释字节码后来执行程序,可以看到执行一个java命令在任务管理器中进程列表就多出一个java.exe,所以jvm应该是启动一个进程来执行java程序的。如果有多个java进程,需要区分这些进程的话有以下方法:

      ①、使用ps -ef|grep java,通过pid来区分。 lsof -i:端口号,通过端口号来区分。

      ②、修改jdk下java.exe的名称为myName.exe,这样通过"myName 类名"生成的进程名就为myName.exe。或者是建立java.exe的一个链接来使用:ln -s /usr/bin/java /usr/local/bin/kallekula,windows下可以使用mklink。

      ③、对于Tomcat,找到Tomcat启动依赖的JDK安装路径,复制bin下的java.exe,重命名为myName.exe,找到Tomcat安装路径bin目录下的setclasspath.bat文件,修改属性【set _RUNJAVA="%JRE_HOME%\bin\myName"】。

      ④、如果是jar包的话使用全路径,如 java -jar /home/weblogic/test/hello.jar。

      ⑤、通过shell脚本来启动java,exec -a goodname java ...,这样ps的时候就会显示我们传入的"goodname"。

  对于JAR文档(实际使用ZIP格式压缩,其中包含.class文档)也可以把其当作目录来看待,如javac -cp C:\lib\abc.jar;c:\lib\xyz.jar App,可以使用*来表示使用一个目录中所有.jar文档,如java -cp .;C:\lib\* App。 javac认为源文件使用的是操作系统默认采用的编码格式,在编译的时候可以使用-encoding来声明源文件使用的字符集,如javac -encoding utf-8 -d . HelloWorld.java。

5、Java关键字

byte  1个字节,可以用来表示-128到127的整数,相当于C中的char
char   unicode字符,2字节
short  短整型,2字节  
int      整型,4字节
long   长整型,8字节
float   单精度浮点数,4字节
double  双精度浮点数 ,8字节
boolean  布尔类型, true或false

var  局部变量类型推断,Java10中增加,类似C++中的auto,其只能用于局部变量以及必须赋初始值。

final  声明一个变量值不能被修改(相当于C中const),或类不能被继承
abstract  抽象方法,抽象类的修饰符 
extends  表示一个类是另一个类的子类 
finally  无论有没有异常发生都执行代码 
implements  表示一个类实现了接口 
import  导入类 
instanceof  测试一个对象是否是某个类的实例 
interface  接口,一种抽象的类型,仅有方法和常量的定义 
native  表示方法用非java代码实现 
package  一系列相关类组成一个包 
static  表示在类级别定义,所有实例共享的 
strictfp  修饰类、接口、方法,表示使用精确的浮点型 
synchronized 表示同一时间只能由一个线程访问的代码块 
this  表示当前实例对象或者调用另一个构造函数  
throws  定义方法可能抛出的异常 
transient  修饰不要序列化的字段 
volatile  标记字段可能会被多个线程同时访问,而不做同步 
assert  断言条件是否满足 

continue  不执行循环体剩余部分 
default switch 语句中的默认分支 
do-while  循环语句,循环体至少会执行一次
else if 条件不成立时执行的分支 
enum  枚举类型 
for  for循环语句 
goto  用于流程控制 (保留字,暂不使用)
if  条件语句 
new  分配新的类实例 
private  表示私有字段,或者方法等,只能从类内部访问 
protected  表示保护类型字段 
public  表示共有属性或者方法 
return  方法返回值 
static  表示在类级别定义,所有实例共享的 
super  表示基类 
switch  选择语句 
throw  抛出异常 
try  表示代码块要做异常处理 
void  标记方法不返回任何值 
while while循环 
const 常量(保留字,暂不使用)
class  表示一个类
break  跳出循环
case  用于switch语句中
catch  try-catch异常处理
null   直接量,赋值给引用类型

6、强类型语言

    Java是一种强类型语言,强类型有两方面的含义:①所有的变量必须先声明后使用;②指定类型的变量只能接受类型与之匹配

的值。Java基本类型大致可以分为数值型和布尔型,其中数值型包括整形、浮点型、字符型,所有数值型之间可以进行类型转换,

包括自动类型转换和强制类型转换。

    ①自动类型转换:

        数值范围小的可以自动转换为数值范围大的,如short可以转换为int和long。特殊的是char类型,它可以转换为int、long等,

但byte和short不能转换为char,我猜因为char是unsigned类型的原因。数值范围大的不能转换为范围小的,如long、float不能

转换为int,特殊的是对于范围内的字面数值会自动将其作为相应类型而不是int:

		float f = 12.3; //错误,字面数12.3为double类型

		int i = 100000;
		long l = i;
		float f = i;
		short s = 1000;
		
		byte b = s; //错误,数值范围大的不能转换为小的

    ②强制类型转换

        如果想要将数值范围大的转换为范围小的只能使用括号来进行强制类型转换,但可能会有溢出问题。

    ③表达式中类型的自动提升

        byte、short、char之间的操作表达式的值会自动提升为int;整个算数表达式的类型自动提升到等级最高的操作数的类型。操作数类型的等级高低如下所示:

    

		short a = 1;
		short b = 2;
		short c = a + b; //出错,a + b结果类型为int

		short s = 123;
		char b = 123;
		short ss = b + s; //出错,b + s 结果类型为int
		
		short sValue = 10;
		sValue = sValue - 2; //出错,表达式类型为int
		
		float f = 3 / 2; //正确,但表达式类型为int,然后自动转换为float,所以f为1.0而非1.5
		
		str = 'a' + 10 + "TEST"; //由于加法的结合性为从左到右,所以先计算'a' + 10表达式的值为107,然后107再与字符串进行相加,107自动转换为字符串,所以str为"107TEST"
		String str = "TEST" + 'a' + 10; //str为"TESTa10"

7、数据类型说明

    对于字面数值默认是int和double,可以加上后缀L和F分别表示long和float。字面数值的前缀0b为二进制表示,0为八进制表示

,0x为十六进制表示。整数除0会抛出异常。

    char为unicode字符,两个字节,可以使用Unicode表示方法来对其赋值,eg:

		char ch = 'a';
		ch = 97;
		ch = '\r'; //java中转义字符与c++中相同,如'\n','\t','\\'等。
		ch = '\u0041'; //Unicode表示方法,0041为十六进制表示,对应十进制为65,故ch为'A'

     三个特殊的浮点数值:
正无穷大:正浮点数除以0得到,通过Double或Float类的POSITIVE_INFINITY表示。
负无穷大:负浮点数除以0得到,通过Double或Float类的NEGATIVE_INFINITY表示。
非数:0.0除以0.0或对一个负数开方得到,通过Double或Float类的NaN表示,非数与任何数都不相等,包括NaN。

eg:

		float f = Float.POSITIVE_INFINITY;
		System.out.println(1.0 / 0 == f); //输出为true
		System.out.println(0.0 / 0); //输出为NaN
		System.out.println(0.0 / 0.0 == Float.NaN); //输出为false

    boolean类型的true和false可以直接与字符串进行连接运算,其实,基本数据类型与字符串进行连接运算时都会自动转换为字符串,所以如果想把基本类型转换为字符串的话可以将其与空字符串进行连接。String的静态方法valueOf()也可以实现数值到String的转换,如:

		String str = true + "ing"; //str为"trueing"
		str = 666 + str; //str为"666trueing"
		System.out.println(str += 0.1);//str为"666trueing0.1"
		
		String str2 = String.valueOf(11.2); //str2为"11.2"

    如下为生成四位随机小写字母的方法,类似生成平常见到的验证码:

public class VerifyCode
{
	public static void main(String[] args)
	{
		String strCode = "";
		for (int i = 0; i < 4; i++)
		{
			int iVal = 'a' + (int)(Math.random() * 26);
			strCode += (char)iVal;
		}

		System.out.println(strCode);
	}
}

  由于LINUX下'\n'表示换行,Windows下"\r\n"表示换行,为了统一,java中使用"%n"来表示换行,在不同平台下转换为对应换行符,它主要用在System.out.printf()中,在print()和println()中无法使用。

8、运算符说明

    java中求余运算%与c++中不同,其操作数可以是浮点,得到的余数也可以是浮点型。与c++相同的是,求余的时候如果除数y是2的幂次方的话,求余可以用位运算&来实现,这样效率更高,如x % y相当于 x & (y - 1)。

    java中按位取反~称为按位非,增加了无符号右移运算符>>>(左边空出来的位补0而不是符号位)。

    与c++中的逻辑判断&&、||、!不同,java中逻辑判断只能针对布尔类型或常量,且增加了&&和||的非短路版本&和|,同时增加了逻辑异或(两个操作数相同返回false,不同返回true)。

9、文档注释

    如下为文档注释的标注方法,使用javadoc命令来生成文档注释,如javadoc -d ApiDoc *.java为为当前所有的源文件生成文档注释到当前的ApiDoc目录中。

/**
* Description
* <br>Program Name: javadoc test
* <br>Date: 2018/5/9 10:57
* <br>作者: leon
* <br>个人网站: <a href="https://blog.youkuaiyun.com/milanleon">milanleon的专栏</a>
*/
public class Test
{
	/**
	*简单测试成员变量
	*/
	public int age;
	/**
	*Test类的测试构造函数
	*/
	public Test()
	{
	}
	/**
	*获得打招呼字符串的方法
	*@param name 指定向谁打招呼
	*@return 返回打招呼的字符串
	*/
	public String hello(String name)
	{
		return name + ", 你好!";
	}
}

10、类版本

   可以使用javap -v命令来获得位码文件的主版本号major version和次版本号minor version,如下所示的Main.class是java 9生成的。在程序中可以使用System.getProperty("java.runtime.version")获得JRE版本信息,使用System.getProperty("java.class.version")获得JRE支持的位码版本号。

 

   在编译的时候可以使用-target指定编译出来的位码文件必须符合指定平台版本,使用-source要求编译的时候检查使用的语法不超过指定版本,如javac -source 1.9 -target 1.9 Main.java 指定编译出来的位码文件必须是1.9平台可以接受的版本,使用语法必须是1.9语法,而JDK9编译的时候默认的-target与-source都是1.9。除了指定-target和-source以外还需要使用-bootclasspath指定Bootstrap类加载器使用的版本,在JDK9下可以使用--release一次性同时指定-target、-source、-bootclasspath,如javac --release 9 Main.java。可以通过NetBeans的项目属性下的“源/二进制格式”来选择-source和-target使用的版本。

11、安装JDK

    我们一般百度JDK就可以获得oracle提供的JDK下载页面,里边会有JAVA SE 8或11等版本的JDK,选择合适的版本进行下载。安装的时候我们可以不选择安装public JRE,因为默认会在SDK安装目录下安装private JRE。安装完成后可以看到以下目录:

    bin: 存放JDK的工具命令,如编辑java源码的javac、执行java程序的java等命令。
    db: 安装Java DB的路径。
    include: 一些平台特定的头文件。
    jre: JRE环境。
    lib: JDK工具命令的实际执行程序,比如lib\tools.jar\sun\tools\
    javac\Main.class类就是javac.exe命令。
    src.zip: Java核心类库的源码。
    javafx-src.zip: Java FX核心类库源码。

    Java SE 9下的lib目录中的modules文档包含了Java SE API的.class文档的执行时期格式(Java SE 9中可以使用jlink来建立专用的执行时期映像,其中只包含你使用到的模块)。jmods目录下每个模块对应的.jmod中包括了编译完成的.class文档(Java SE 9引入了新的JMOD格式来封装模块,在过去JAR文档是封装.java或.class文档的主要格式)。

12、容器

  java中的容器(Container)就是执行于JVM上的java应用程序,比如Java EE中的Servlet/JSP是执行于Web容器中的,Web容器是Servlet/JSP唯一认识的HTTP服务器,所以必须知道Servlet/JSP如果与Web容器沟通,Web容器如何管理Servlet/JSP的各种对象。

  如下图所示的Web组件示意图,浏览器向Web服务器发送请求,如果请求的目标是HTML文件,Web服务器可以直接处理。如果请求的是Servlet或JSP页面,Web服务器将请求转发给Web容器,容器将查找并执行该Servlet或者JSP页面,Servlet和JSP页面都可以产生动态输出:

    类似的,EJB组件执行与EJB容器中,Applet组件执行与Applet容器中,Java应用程序客户端执行与应用程序客户端容器中,如下图所示:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值