您的位置:首页 > 编程语言 > Java开发

JAVA实用教程(一)

2015-09-01 00:00 465 查看
摘要: 为JAVA初学和进阶者设计的参考教程。从项目入手,根据项目编写过程解释基本语法和自带类库,外加一些引申用法。

#Hello World

在百度贴吧 java吧 老是有人说求教程啥的。其实网上能找到的教程太多了,但java吧貌似没有自己吧里的一套教程。

这个系列的博客就是为了回应这种现象。毕竟总要有人做吧= =吧主们都是上班一族,挺忙的,这种耗时没准还不讨好(稍微写错一点就会有很多人喷)的工作确实不会有什么兴趣,那么这个任务只好吧友完成了。

##本期任务流程

JAVA

JDK

Eclipse

使用Eclipse写一段具有输出“hello world”这一串文字功能的JAVA程序。

##JAVA
JAVA编译为字节码后,运行于JVM(JAVA Virtual Machine,JAVA虚拟机)上。

JAVA是“跨平台”的,它可以一次编译,随处使用。但“跨平台”只是它的口号。实际上,JVM就是一个平台。

JVM由C编写,并在多个平台上调整源码并编译,完成一个对实际机器的隐藏。

这有点像Adapter设计模式

Adapter=适配器。很多人家里以前都有“猫”,现在都光纤入户了,把“猫”换成了“光猫”。

“光猫”就是一个适配器。它将输入的光信号转化为计算机网卡能够识别的电信号。在设计模式中,适配器模式也类似,将某种功能提供的接口封装为另一种形式。

JVM把每条JAVA字节码适配成机器能够理解的指令。实际上如果你使用JDK自带的反编译工具可以看到,最终的字节码每条都差不多都能对应一条汇编。

前面说,JAVA运行在JVM上,那么如果我们要运行java程序,就必须有JVM。如何获取JVM呢?官方将JVM提供在JRE(JAVA Runtime Environment,JAVA运行时)中。可以在这里下载安装最新版本的JRE(通常外行说的JAVA,指的大多是JRE)

以前在Windows系统下似乎需要手动配置环境变量。但现在都由安装程序帮你配置好了。

Windows : 打开cmd(Win+R,输入cmd,回车)

OSX : 打开终端(触摸板四指靠拢,其他,终端)

输入

java -version

你应该会看到类似这样的信息

Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)

如果Windows中提示“不是内部或外部变量”bulabulabula...,说明环境变量没有帮你配置好(基本都是自己作死调安全设置或者用360了)。

这里又要科普了。什么是环境变量?

##环境变量
平时你要使用一个文件会怎么做?(本文只在关键处以Windows举例,次要部分只说OSX)

打开Finder,在左侧选择宗卷或者前往电脑,然后一层层打开文件夹定位到你要的文件,然后打开。

那么在命令行呢?你需要

cd / (切换到根目录)
cd Users (切换到/Users目录)
...
重复进入目录直到找到

即使最简单的做法也要写很多字:

cd /Users/wkgcass/Documents/.../.../

这是不可避免的。

如果每次都这么做太麻烦了,所以有了“环境变量”。

比如你经常访问/Users/wkgcass/Documents,你可以将其设定在环境变量中。以后便不需要写这么多。命令行在当前目录找不到时将尝试从环境变量的目录中寻找。

所以,环境变量不是什么高深的东西,仅仅是为了方便而设计。当然有些程序也会读取环境变量,就像JRE的许多jar包和dll(windows下是dll,osx貌似是so)的存放位置。

(jar以后说,dll和so不解释,好奇可以百度)

这种问题可以直接点这里。如果安装时自己调了安装路径对初学者来说那是作死行为,自己解决。

##JDK
前面说了一堆JAVA运行时,那也只能运行别人写的java程序,怎么开发呢?

JDK=JAVA Development Kit (java开发套件)

实际上,JDK中包含了JRE。前面让你们先装JRE其实是逗你们玩的 : )

好吧。。前面装JRE是为了让你们以后部署工程时知道是怎么一回事。

##安装JDK
点击这里下载最新版的JDK。网络有时候快有时候慢,别急,等待的时候可以继续看教程嘛= =

以前Windows下要配置环境变量,现在安装程序都帮你配好了。

进入命令行,输入

javac -version

如果输出类似这样的信息:

javac 1.8.0_45

说明已经配置完成。你现在已经可以开发java了。

如果Windows中提示“不是内部或外部变量”bulabulabula...,说明环境变量没有帮你配置好

这种问题依旧直接点这里

##Eclipse
Eclipse是一个IDE

IDE=Integrated Developing Environment 集成开发环境

使用Eclipse编写java是非常省时省力的事情。

推荐直接使用最新版的Eclipse IDE for Java EE Developers

##什么是SE, EE
JAVA根据使用场景,分为了

SE standard edition 标准版

常用于桌面软件

EE enterprise edition 企业版

用于开发网站系统

ME micro edition 微缩版

用于嵌入式消费电子设备

更多信息自行百度。

##使用Eclipse
Eclipse貌似不用安装,解压就能运行。

Windows下双击Eclipse图标。

OSX下推荐先把Eclipse拖动到应用程序里,再打开。

加载时会问你选择一个WorkSpace,自己定一个目录即可。

第一次进入会有整个屏幕的欢迎页,直接无视关掉,并不能提供什么帮助。

##创建HelloWorld工程
先别急。你可以看到,右上角有JaveEE,还有一个Java。没看到的话把它全拖出来就看到了。

这个叫做Perspective(英文直接翻译不解释)。预置了一些内置的IDE功能的排列情况。推荐点一些那个Java。我们这里并不创建EE工程。

接下来File-->new-->Project。在输入框里写java,筛选出名字带java的Wizard(Wizard直接翻译不解释)。

选择Java Project。下一步。

里面看英文就能知道含义。

这里要讲的是:JRE的选择。

##版本

Java 1.5 - 主要有 范型,自动装/拆包,注解,增强for,枚举,多参数

Java 1.6 - 没什么重要的语言层面的增强,自行百度

Java 1.7 - 范型自动推断,集合支持这种写法[e0,e1,e2]和{k0:v0,k1:v1}

Java 1.8 - lambda表达式,接口默认方法

学习时候直接选1.8,省得麻烦。

也可以选前面的,但千万别选择1.5之前的,那时候语言特性太死板了。

##继续工程
跟着Wizard一步步走即可。英文要是看不懂自行百度翻译

创建完成后,左侧会出现一个工程图标。

点击左边的小加号,会看到src目录,以及JRE System Library。其实除了src其他都和我们没啥关系。

右键src目录->new->package,创建一个包

##包
编程时总会用到其他人写的类库。而类库的名称不可能保证不相同。

比如甲看了这篇文章,写了HelloWorld类。乙也看到了,它也写了一个HelloWorld类。如果甲和乙都把自己的类传给我,我把它们放到工程里,就会出现重名问题。所以需要一个“命名空间”

JAVA的“命名空间”就是包。包直接以文件夹的形式进行管理。

举个例子,java中描述的net.cassite.pure.ioc,物理目录就是net/cassite/pure/ioc

其中,net是一个包,net.cassite是一个包,net.cassite.pure是一个包,net.cassite.ioc是一个包。这在讲解可见性时会再次提到。

通常我们习惯把自己的包写成url反过来的形式。

##创建HelloWorld类
在你创建好的包上右键->new->Class创建一个类。出现的窗口你可以设置继承,实现,修饰符等。你可以看到有个public static void main,不过既然初学,建议不勾上而是手写。

创建完成后,将看到

public class ClassName{

}

其中:

##修饰符
java中常用以下修饰符:

访问:

public 表示可在任何地方访问

protected 仅同包的类和子类可访问

(无修饰符) 默认(default),仅同包的类可访问

private 仅本类中可访问

变量:(有些含义将在下面解释)

static 静态,无需实例化即可访问

final 变量必须在定义时赋值。如果对非静态成员修饰则必须在定义时赋值或在构造函数中赋值。不可修改。 如果修饰方法,说明这个方法不可被重写。 如果修饰类,说明这个类不能被继承。

abstract 表明类不能实例化。

其他现在不说,有兴趣到java.lang.reflect包里的Modifier类中看public static final int的那些成员变量。或者百度

##类
###定义

通过

class 类名

定义一个类。(这里不说类是什么,说了其实白说,我自己实际体会。初学OOP根本不知道为什么要有类。只需要知道能干什么就好)

###构成
一个类中有 成员变量Field, 构造函数(也叫构造器)Constructor,方法Method

Field, Constructor, Method 统称 Member(成员)

这里不细讲。

###实例化
一个没有被abstract修饰的类可以被实例化。只带有private构造函数的类也不可以实例化,但是通过反射是可以做到的(以后再说)。

类名 变量名=new 类名(要使用的构造函数的参数表)

通常实例化也说成: 构造,构建,初始化,new

###构造函数
构造函数是在实例化类时调用的函数。

使用

类名(参数表)

来定义。

###参数表
参数表不是一个日常中说的‘表’,而是数据结构的‘表’。

参数基本格式:

类型 变量名

真正的参数表通过英文的逗号(,)将多个“参数基本格式”连接起来,写在括号里。

比如说

(int a, int b)
(Object obj)
(int i, Strng str)

java 5 和之后都支持不定参数个数

(Object objs...)

实际上等于

(Object[] objs)

避免歧义,只允许参数表最后一个参数使用不定个数

(int i, String... strs) <=正确
(String... strs, int i) <=错误
(String[] strs, int i) <=如果一定要放前面只能这么写

在方法内获取时按照数组的格式获取

##数组
声明一个数组

类型[] 变量名

你可以在声明时定义长度,或者包含的元素。

类型[] 变量名 = new 类型[长度];
类型[] 变量名 = new 类型[]{
元素0,元素1,元素2
};

使用

数组变量.length

获取数组长度。

使用

数组变量[下标]

获取数组内元素

使用

数组变量[下标]=新元素

设定对应下标数组元素值

下标从0开始。0代表第一个,1代表第二个,...

其中 类型 也可以是基本类型,不会有影响。

###类型
类型 写为 基本类型/类/接口/枚举类型的名字。

表示通过某个类型来访问这个变量。

基本类型有8种,他们各自对应一种“包装类型”。包装类型指的是把基本类型包装为引用类型。何为引用类型后面说。

int 整型,代表一个整数

int i=1;


boolean 布尔型,代表一个逻辑真假

boolean b=true/false;


double 双精度型,代表小数,32位不具有原子性

double d=0.1;


float 浮点型,代表小数,精度更低但具有原子性

float f=0.1f;


char 字符类型,本质是int,表示一个字符

char c='a';


byte 字节类型,表示一个字节(8位),所以数值上只允许 -256到255,一般没人会真把它当数值去使用

byte byt=1;


long 长整型,表示一个比较长的整数,32位不具有原子性

long l=1l;


short 短整型,实际上就是一个int,而且初始化,赋值和操作麻烦,然并卵,没人用

short s=(short)1;


其中没提到是不是原子性的都具有原子性。64位都具有原子性。

参考某新浪博客

运行发现程序在while循环时进入了死循环,这是因为使用的JVM是64bits。在64位JVM中double和long的赋值操作是原子操作。
在eclipse中修改jre为一个32bit的JVM地址,则会有如下运行结果:
1111111111111111111111111111111111111111111111111111111111111111
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000011111111111111111111111111111111
//很明显test的值被破坏了
4294967295

##[扩展]原子性
两线程同时赋值和取一个不具有原子性的基本类型可能发生错误。因为赋值操作不是一次完成的。对于long和double,赋值操作不是一步。如果第一步完成了,另一个线程就取出,那么取到的值将有误。

解决:加上volatile修饰符

##开始写HelloWorld吧!
扯了这么多,终于回到正题了。

在你创建的类的{里面},输入

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

保存,点击Eclipse上方中间位置的绿色右箭头,代表运行。
运行后查看Eclipse的控制台信息。如无意外,会显示:

hello world

--

#发生了什么?
void main(String[] args)

是方法的声明。
表示这是一个不返回值的方法。

##方法

返回类型 方法名(参数表)

返回类型如果设为void则表示不返回值。

方法名,在这里设为main。这是因为JVM会寻找static的main(String[])方法作为入口,传递启动时给定的参数作为字符串数组到参数表第一个参数中(String[])去

比如:

java Test arg0 -i 5

则传递进的数组为

String[]{ "arg0", "-i", "5" }

##方法体
{
...
}
本例中,方法体为

System.out.println("hello world");

如果是带返回值的方法,则必须保证能够返回一个值,即使返回的是null值。

另外,返回类型为基本类型的,不可使用null值。

##调用
System是一个类。

out是一个public static的成员变量

在调用时,使用

System.out

即可取得System类中的out成员(因为out是static所以不用实例化System就能取到)

而println是out对象的一个方法。

这样调用

.out.println(...)

即可执行println方法。

而里面的参数 "hello world" 是String类型。

这个语句的功能是,获取System类中的out静态成员,然后调用其println方法,调用时参数为一个String类型的 "hello world" 。

##执行
println表示向输出流输出参数中的信息。

而System.out绑定的是标准输出。所以,执行println时将向标准输出流输出信息。

所谓标准输出,如果参数没调过(我也不知道怎么调),表示运行这个程序所在的控制台。

##结果
你看到控制台上有一行

hello world
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 教程