安装环境概念
- JVM
java 虚拟机( java virtual machine )运行 Java bytecode 的虚拟机, 以堆栈结构机器来进行实做. 有自己完善的硬件架构, 如处理器, 堆栈, 寄存器等, 还有相应的指令系统. JVM 屏蔽了与具体操作系统平台相关的信息, 使得 Java 程序只需生成在 Java 虚拟机上运行的目标代码(字节码), 就可以在多种平台上不加修改地运行. 通过对中央处理器( CPU ) 所执行的软件实现, 实现能执行编译过得 Java 程序码
理解: 对上提供统一的接口, 对下即操作系统分别进行封装, 实现编写一套代码, 多处使用. - JDK
java 开发工具包 (java development kit)
java 开发人员用来编译, 调试程序使用
包含组件:- 用于 Java 开发的组件: javac( 编译器, 将后缀名为.java 的源代码编译成后缀为.class的字节码 ); java(运行工具, 运行.class字节码); jar( 打包工具, 将相关类打包成一个文件); javadoc( 文档生成器, 从源码注释中提取文档, 注释需匹配规范); jdb debugger(调试工具); jps( 显示当前 java 程序运行的进程装填 ); javap( 反编译程序 ); appletviewer( 运行和调试 applet 程序的工具, 不需要使用浏览器 ); javah( 从 java 类生成 c 头文件和 c 源文件. 这些文件提供了连接胶合, 使java 和 c 代码可以进行交互 ); javaws( 运行 JNLP 程序 ); extcheck( 一个检测 jar 包冲突的工具 ); apt( 注释处理工具 ); jhat( java 堆分析工具 ); jstack( 栈跟踪程序 ); jstat( JVM 检测同级工具 ); jstatd( jstat 守护进程); jinfo( 获取 java 进程内存映射信息 ); idlj( IDL-to-Java 编译器. 将 IDL 语言转化为 java 文件 ); policytool( 一个 GUI 的策略文件创建和管理工具 ); jrunscript( 命令行脚本运行 )
- 完整的 JRE
- 样例程序, 展示 Java API
- JRE
java 运行时环境 (java runtime environment)
包括: java 虚拟机, java 基础类库
普通用户安装来运行 java 程序
安装
安装 JDK
在官网上下载
JDK: Java Development Kit
下载安装
查询本机 java 和 JDK 版本
1
2java -version //java 版本
javac -version //jdk 版本查看电脑里都安装了那些版本 jdk
1
/usr/libexec/java_home -V
会显示电脑里所有版本 jsk
JDK 版本切换
使用的是 zsh, 所以在 .zshrc 中添加别名进行切换
1
vi ~/.zshrc
添加如下内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14# 设置 JDK 7
export JAVA_7_HOME=`/usr/libexec/java_home -v 1.7`
# 设置 JDK 8
export JAVA_8_HOME=`/usr/libexec/java_home -v 1.8`(可确认到具体版本1.8.0_181)
# 某个项目使用指定版本 jdk8
export JAVA_HOME = JAVA_8_HOME /your_program_path
#默认JDK 7, 如果想全局使用某个版本, 将下面改为某个版本
export JAVA_HOME=$JAVA_7_HOME
#alias命令动态切换JDK版本
alias jdk7="export JAVA_HOME=$JAVA_7_HOME"
alias jdk8="export JAVA_HOME=$JAVA_8_HOME"执行
1
source .zshrc
切换 JDK
1
2jdk7 //切为1.7版本
jdk8 //切为1.8版本
homebrew 下载
1
2
brew tap caskroom/versions
brew cask install java8
下载完后包同上, 版本切换同上
编译运行
编写文件
存储类型为 .java类名需要和文件名一致, 不然会报错
正确
eg: helloWorld.java1
2
3
4
5public class helloWorld {
public class void main (String[] args) {
System.out.print("hello world");
}
}编译与运行
1
2javac helloWorld.java //compile
java helloWorld //operate错误
eg: helloWorld.java 类名为 HelloWorld1
2
3
4
5public class HelloWorld {
public class void main (String[] args) {
System.out.print("hello world");
}
}编译与运行
1
javac helloWorld.java
error: helloWorld.java:1: error: class HelloWorld is public, should be declared in a file named HelloWorld.java
public class HelloWorld{}
编译
1
javac helloWorld.java
运行
1
java helloWorld
知识点
- java 一个文件中只包含一个主类, 即用 public 声明的类, 文件名和主类名保持一致
- 测试文件与类文件分别放置
- 只用编译一个入口文件, 入口文件引用的相关的文件都会被编译, 并且在编译时会去判断正误, 在同一目录下,
一个文件中, 可以共存多个以 class 声明的类, 在编译时, 会单独编译出该 class 命名的文件, 文件名为该类名
声明变量
变量是保存对象的地址, 它指向对象存储的物理位置, 每个实例化的对象, 系统都会给其分配内存, 变量仅是用来是指向该内存地址
变量可以是对象的状态, 局部变量(声明在方法中的变量), 参数,执行方法的返回值
此处的 className 是类名, 可以是 java 内建类 eg: String, init, ArrayLiat, etc; 也可以是自定义类1
2
3
4className objName = new className(); //实例化一个对象, 并赋值给 objName 变量
eg: String gogo = new String( "I am a string" ); //实例一个字符型对象(传入参数), 赋值给 gogo 的变量
HelloWorld hello = new HelloWorld();
className[] objName = new className[length];构造函数
创建实例对象是通过 new 一个构造函数实现的- 若没定义构造函数, 编译器会默认为每个类添加一个空的构造函数
- 定义一个构造函数, 该构造函数名与类名保持一致
- 可以重载构造函数, 相同的构造函数名, 相同的返回类型, 不同的参数(类型或个数)
基本类型变量存储在栈中,
引用型变量名存储在栈中, 赋值内容存储在堆中, 变量名指向堆中的内容
类存储在代码区
类中的方法存储在代码区, 只有在执行时才分配内存, 执行结束后内存收回
同一类的每个对象共享该类的方法当编译器看到一个整数时, 会把它当做 int 型
java 的所有函数都是属于某个类的方法, 所以 main 函数也需要有个外壳类, 这个类有可能仅是为了main 函数而建立, 仅为了能够执行 main 函数
类的成员变量, 未赋值的成员变量, 均有初始值, int 类型为0, string 类型为 null, boolean 为 false, float 类型为 0.0
方法里的变量则不会有默认初始值final 指示常量, 只可被赋值一次, 常量一般用大写字母表示
字符串不可以修改, 赋值出现时拥有自己的内存, 如不可以把” hello”进行修改, 如果想修改变量对应字符串中的内容, 那就只能是获取该变量对应的字符串内容, 对其进行拼接, 再赋值给变量, 相当于将变量的引用指向了另外一个字符串对象;
数组, 数字型数字默认初始值为0; boolean 型数组默认初始值为 false; object 型数组默认初始值为 null;
数组一旦创建, 个数是不能改变的for each loop
for(type ele : arr){ele 是数组元素的值, 而不是指向数组值的索引
}
所以 for each 是不可以给数组赋值数组的拷贝
- 仅是变量的拷贝, 二者均指向同一内存区域, 即同一个数组对象;
int[] arr = new int[3];
int[] copyArr = arr; - 拷贝数组并创建新的对象
int[] copiedNewArr = Arrays.copyOf(arr, arr.length);
- 仅是变量的拷贝, 二者均指向同一内存区域, 即同一个数组对象;
数组初始化
arrAnonymous = new int[] {1, 2, 3, 4};
int[] arr = {1, 2, 3, 4};main( String[] args )方法中的参数, 是用来接收命令行中的参数
构造器
- 与类同名
- 重载
- 无返回值
- 使用 new 调用
- 若类中未定义构造器, 编译器默认添加一个空的构造器
- 可以传任意个数的参数
当类需要返回一个可变对象的引用时, 对这个对象进行克隆, 防止在该类对象的引用中, 改变
哈希值 代表独一无二的对象, 并且指向对象所在的位置
静态方法
public static void method() {}
以下条件可以设置为静态方法- 与对象状态无关
- 只用访问类的静态域
一个方法可以访问该方法所属类的所有对象的私有数据
参数传递, 都是值传递,
基本类型的实参, 是将实参复制一份出来, 再赋值给形参, 在函数内部进行的任何操作都不会影响到实参的值
对象类型的实参, 是将引用复制一份出来, 再赋值给形参, 在函数内部对实参的操作, 都是同一个对象, 会影响到对象的值. 但是如果是在函数中对参数引用的操作, 则不影响实参的值this
在一个构造器中可以使用 this() 调用该类中的另外一个构造器
class Employee{public Employee(double s) { String nextId = "hello"; this.(nextId, s);// 调用下面构造器, 并传入参数 } public Employ(String n, double s) { }
}
编译器在编译时不检查目录结构, 源文件开头有包语句, 但不在该包的目录下亦可通过编译, 但在 java 虚拟机中无法运行, 因为虚拟机找不到类文件
类的路径必须与包名匹配子类(派生类/孩子类) extends 超类(父类/基类)
子类比超类的功能更加丰富