Java Development kit Java开发工具包
Java Runtime Enviroment Java 运行时环境
Java Virtual Machine Java虚拟机
关系:
JDK > JRE > JVM
JVM是一种规范
虚拟计算机(一种软件)
依照规范,针对不同场景,jvm可以有不同的具体实现
一般使用SUN,现被oracle公司收购
java程序编译运行机制:
*.java --> *.class --> JVM for platforms
路径:
bin: binary缩写
JAVA_HOME
path: 执行dos命令,系统会在path指定的路径中寻找该命令对应的可执行文件
文本编辑器;
UltraEdit
EditPlus
notepad++
集成开发环境:
Eclipse
NetBeans
public class Welcome{
public static void main(String[] args){
System.out.println("Hello Wrold!");
}
}
Dos 下编译运行:
>javac Welcome.java # 编译成字节码文件Welcome.class
>java Welcome # 在java虚拟机上运行
notes:
大小写敏感;
main方法为程序入口;某块化编程类似python
public class 只能有一个,且与文件名一致,在同个文件中还可以定义无public 开头的class
注释:
// - 单行注释
/* xxx */ - 多行注释,或在行内注释
javadoc.. (Eclipse快捷键:ALT+SHIFT+J)
命名;
标识符必须以字母A-Za-z,下划线_,美元符$开头;
java内部采用Unicode字符集,universal通用字符集(所有语言字符)!!2个字节,2^32即65535个字符
字符集:
ISO8859-1 西欧字符集(1个字节),向下兼容ASCII
BIG5 台湾的大五码,表示繁体汉字
GB2312 大陆使用最早、最广的简体中文字符(2字节)
GBK GB2312的扩展,可以表示繁体中文
GB18030 GBK的扩展,可以表示汉字,维吾尔文,藏文
Unicode 国际通用字符集
utf-8 (西欧一个字节,汉2个字节)
UTF-8是Unicode的其中一个使用方式。 UTF是 Unicode Tranformation Format,即把Unicode转做某种格式的意思。
UTF-8便于不同的计算机之间使用网络传输不同语言和编码的文字,使得双字节的Unicode能够在现存的处理单字节的系统上正确传输。
UTF-8使用可变长度字节来储存 Unicode字符,例如ASCII字母继续使用1字节储存,重音文字、希腊字母或西里尔字母等使用2字节来储存,而常用的汉字就要使用3字节。
UTF-8(8-bit Unicode Transformation Format)是一种针对Unicode的可变长度字符编码,又称万国码。
由Ken Thompson于1992年创建。现在已经标准化为RFC 3629。
UTF-8用1到6个字节编码UNICODE字符。用在网页上可以同一页面显示中文简体繁体及其它语言(如英文,日文,韩文)。
数据类型
基本数据类型
数值型
整数类型 byte,short,int,long
浮点类型 float,double
字符型 char
布尔型 boolean
引用数据类型
类 class
接口 interface
数组 int[], ...
整数类型:
byte 1字节 -128 - 127 (非128,因0占用一个)
short 2字节 -2^15 - 2^15-1 65536/2
int 4字节 -2^31 - 2^31-1 约21亿
long 8字节 -2^63 - 2^63-1
进制:
十进制 1
八进制 01
十六进制 0x1
可通过Integer.toxx()相互转换;
自动转型,数据没有超过类型表示范围时可以相互转换
java语言的整数常数默认为int型,声明long型常量时,若超出int范围则
应在后加L,以表示该常量为long型,可以超过2^31-1:
long a = 2500000000L;
long a = 2500000000; // 错误超出范围
BigInteger 大整数类
浮点型:
float 4字节 范围:3.4*10^38
double 8字节 范围:1*10^103
浮点数常量默认为double;
3.14 double
3.14F float
314e-2 double 科学计数法
浮点数存在舍入误差;
BigDecimal类,可进行精确的计算
字符型char:
java中的char为2个字节,即一个字符占有两个字节(java内部Unicode表示)
char c1 = '中'; // 2个byte; Unicode 2byte 0-65535
char c2 = 'a'; //字符,可以是汉字,因为是Unicode编码
char c3 = 65; // 用整数赋值,其对应字符为相应的ASCII码表示的字符
转义字符,',\t, \n, ...
char c4 = (char)1; //强制转型
字符用单引号'中'
字符串String 用双引号"中国"
布尔类型boolean:
boolean 1bit 1位 两个值 true, false
自动类型转换
- 容量小的类型可以自动转换为容量大的数据类型(容量为该类型表示的数的范围)
没有精度损失:
byte -> short -> int -> long
int -> double
char -> int
float -> double
可能有精度损失:
long -> double
long -> float
int -> float
- 可以将整型常量(默认int)直接赋值给byte,short,char等类型变量
而不需要强制类型转换,只要不超过其表数的范围
强制类型转换
- 有可能发生截断(多数情况下,无意义)
- int i2 = 100;
char c3 = (char)i2;
类型提升问题(二元运算符中,+-*/%)
- 向容量大的提升
- 或强制转型
溢出问题
- 强制转型提升(先转型提升再计算)
举例:一个人70年心跳多少次
long times = 70L*60*24*365*70;
long times = (long)70*60*24*365*70;
二进制整数,下划线分隔符
int a = 0b000000000000000000000000000000011; // 3, 32位,4字节
int a = 0b0000_0000_0000_0000_0000_0000_0000_0011;
int b = 1_2312_3131;
int b = 1123123131;
Java是一种强类型语言,每个变量都必须声明其类型
变量名,变量类型,作用域
变量声明:
type varName [=value]
int a = 1;
int a;
a = 1;
int x,y,z;
局部变量:方法或语句块内部定义的变量;需要赋值才能使用;
实例变量/成员变量:类中的属性;
public class test{
int t; // 实例变量,成员变量
public static void main(String[] args){
int t; //局部变量
final int F = 3.14; //常量final
final int MAX_SPEED = 120;
}
}
常量 final(最终变量)
只能初始化一次(然后不能改变);
一般大写;
命名规则:
- 变量、方法名
首字母小写和驼峰原则
举例:run(), runRun(),
age, ageNew, monthSalary
- 常量final
大写字母和下划线:MAX_SPEED
- 类名
首字母大写和驼峰原则:Man, SuperMany;
- 算术运算符 ..
- 赋值运算符 ..
- 关系运算符 .., instancOf()
- 布尔逻辑运算符 .., 短路方式:(逻辑与和逻辑或,从左至右计算,如果确定值则不会再计算下去)
- 位运算符(主要用于权限管理,或游戏类开发中)
~ -- 取反 & -- 与
| -- 或 ^ -- 异或
<< -- 左移 (左移一位相当于乘2)
>> -- 右移 (右移一位相当于除2取商)
boolean b1 = true & false;
- 扩展运算符
a += b
- 字符串连接符 +
- 三目运算符
x?y:z; // x为true,返回y,否则z
str = a>b ? "abc" : "cba";
- 选择结构
双选择:
if(){
xxx;
}else{
xxx;
}
多选择:
if(e==6){
xxx;
}else if(e==5){
xxx;
}else if(e==4){
xxx;
}else{
xxx;
}
等值判断时可以用switch代替if..else:
swith(e){ // e 为int,或者自动给可以转为int的类型(byte,char,short),枚举
case 6: // e 也可为字符串,1.7jdk
//todo
break;
case 5:
//todo
break;
default:
//todo
}
- 循环结构
while(){}
do{}while // 基本不用
for(){} //while的特殊情况
for循环语句,遍历用的非常多
Application Interface
package?(有点类似于命名空间的概念,python的模块)
- 为了解决类之间的重名问题
- 为了便于管理类:合适的类位于合适的包)
- 包名惯用规则:域名倒着写+模块名
cn.bjsxt.test
注意:
- 写项目时都要定义包,方便管理,不要使用默认包
- 在包内写各种相关类
- com.gao和com.gao.car,这两个包没有包含关系,是两个完全独立的包。
只是逻辑上看起来后者是前者的一部分。
常用包:
java.lang
包含java语言核心类,如String、Math、Integer、System、Thred
提供常用功能,不需要import;
java.awt
包含了构成抽象窗口工具集(abstract window toolkits)的多个类;
这些类用来构建和管理应用程序的图形用户界面(gui)
java.net
包含执行与网络相关的操作的类;
java.io
包含能提供多种输入输出功能的类;
java.util
包含一些实用工具类,如定义系统特性、使用与日期日历相关的函数;
使用javadoc生成api文档
- 文档注释/**
*/
- 快捷键alt+shift+j
自定义模板codeStyle:
Window-->Preferences-->Java-->Code Style --> Code Templates --> Comments --> types --> Edit
栈:存放局部变量(注意引用类型);自动分配连续空间,后进先出
堆:放置new出的对象,方法区等;
方法区
类信息[属性,方法](代码)(通过class loader加载)
static变量和方法
常量池(如字符串常量)
等等
垃圾回收机制
垃圾回收负责回收所有“不可达”对象的内存空间
构造该类的实例;
通过new触发调用;
不能有return;
构造方法名为类名;
默认构造器;
默认初始化:数值型0
方法的重载
一个类中可以定义有相同名字,但参数不同的多个方法
调用时,会根据不同的参数列表调用相应的方法
两同三不同
同一个类,同一个方法名
参数列表不同(类型、个数,顺序)
不构成重载:
1. 只有返回值不同
int a(Stirng str){};
void a(String i){};
调用:a(); //无法判断调用哪个方法
2. 只有形参名称不同
构造方法也可以重载!!
在类中声明的成员变量为静态变量
或者叫做:类属性,类变量
(类的实例不能直接访问,可以通过成员函数访问)
(静态方法中不能访问非静态变量/成员)
***见内存分析
作用:使得各对象可以共享同同一份代码;
普通方法中,表示当前调用对象;
构造方法中,表示正要创建的对象;
在static方法中,不能用this;
public class Student{
String name;
int id;
public Student(String name, int id){
this.name = name; //this.name为成员变量
}
// 构造方法重载
public Student(String name){
this(name); // this()调用另外一个构造方法
}
}
方法中的隐式参数this,不需要写出来
类比于python方法中self,但要显示写出来
方法中隐式参数this,super
更好的建模;
通过extends标识,以进行代码复用;
extends,子类是父类的扩展;
java中类只有单一继承(一个直接父类);简化分析关系
(构成一个继承树)
多继承通过java中接口实现;
如果定义一个类时,没有调用extends,
则其父类是:java.lang.Object(根类,老祖宗)
不同叫法:超类、父类、基类、子类、派生类
方法的重写override;
具有相同的方法名称、参数列表和返回类型
快捷键:ctrl+t 查看类型层次结构
Object类是所有java类的根基;
public class Object{
public String toString() {
return getClass().getName() + "@" +Integer.toHexString(hashCode());
}
}
// It is recommended that all subclasses override this method.
直接父类对象的引用;
**可以通过super来访问父类中被子类覆盖的方法或属性;
方法中的隐式参数;
普通方法中:可以随便调用;
构造方法中:首行
一般java默认调用,也可以显示调用;
隐藏对象内部的复杂性,只对外公开简单的接口;
高内聚,低耦合
(什么叫运营??复杂的留给自己,简单留给他人)
高内聚:类的内部操作细节自己完成,不允许外部干涉
低耦合:仅暴露少量的方法给外部使用
使用访问控制符,实现封装:
远亲不如近邻
|标记 | 同一个类 | 同一个包 | 子类 | 所有类 |
|---------|:---------:|:--------:|:------:|--------:|
|private | * | | | |
|default | * | * | | |
|protected| * | * | * | |
|public | * | * | * | * |
tips:
- 类的属性处理:
1. 一般使用private. (除非其属性确定会让子类继承)
2. 提供相应的get/set方法来访问相关属性.
这些方法通常是public,从而提供对属性的读取操作。
(boolean变量的get方法是用is开头,在eclipse中可以通过添加source自动完成)
- 一些只用于本类的辅助性方法method可用private
- 希望其他类调用的方法用public
用来实现动态联编,程序的最终状态只有在执行过程中才被决定;
而非在编译期间就决定了。
提高系统的灵活性和扩展性,也可以解决代码复用问题;
如何实现多态?
引用变量的两种类型:
- 编译时类型(模糊一点,一般为父类),由声明事的类型决定
- 运行时类型(具体是哪个子类就是哪个子类),由实际对应的对象类型决定
**多态存在的3个必要条件:
- 要有继承
- 要有方法重写
- 父类引用指向子类对象;
父类引用指向子类对象;
Animal a1 = new Cat();
Cat c = new Cat;
Animal a1 = c;
Cat c = (Cat)a1; // 强制转型转换可行,其本来就是cat
本来面目!!
if(c.instancof Cat){
//todo
}
编译器,运行时jvm
## Importtant Notes:
运行时时,this指向谁,调用谁方法
*方法中有两个隐式参数method(this, super, xx)
**继承中new出的对象,内存结构为new xx类型指定的内存(包括其父类直至Object)
***在多态中,父类可以引用子类对象,但实际上运行时,当前对象还是子类对象,该调用什么调用什么
抽象类为所有子类提供了一个通用的模板,子类可以在这个模板基础上进行扩展;
public abstract class Animal{ //抽象类
public abstract void methods(); //抽象方法
public void method(){}; //同时可以定义普通方法或属性
}
包含抽象方法的类为抽象类;
抽象类可以被抽象子类继承;
其继承子类为非抽象类时,必须实现抽象类中声明的方法;
**抽象类不能实例化,不能用new来实例化抽象类;
**抽象类只能用来继承;
将方法的设计和实现分离;
只有抽象,规范,没有具体实现;
public interface newInterface {
//接口中只包含:常量,抽象方法;
String MAX_GREAD = "BOSS";
public static final String MAX_GREAD = "BOSS";
// 上述是等价的,public static final默认添加
int MAX_SPEED = 120;
public void test01(); // public 默认添加
public int test02(int a, int b)
}
设计和实现分离;
谁负责设计接口;谁负责实现;便于分工合作!协作!
public class myClass implements newInterface {
public void test01(){
String str = newInterface.MAX_GREAD;
}
public int test02(int a, int b){
return a+b;
}
}
如何描述飞机,导弹,子弹,篮球,石头的关系?
多继承通过java中接口实现,即:
一个类可以实现多个接口,实现多继承关系
遵循多项规范
比如,人作为不同的身份,需要同时遵循相应的行为准则
class myClass implements interface1, interface2{
}
接口不能被new实例化,但可以作为类型,具有多态特性;
接口支持多继承;
多态的应用!
抽象类;
接口应用更多;
在c语言中,可以用指向函数的指针来实现;
在python中,函数可以作为参数,因此也可以像c语言这样实现;
同时,python中也有面向对象的特性,用多态实现;
回调函数通俗的解释:
普通函数:你所写的函数调用系统函数,你只管调用,不管实现。
回调函数:系统调用你所写的函数,你只管实现,不管调用。
多态!!!
匿名内部类:定义和调用同时进行;
非静态内部类:类似成员变量,从属于外部类的实例化对象
静态内部类:类似类的静态成员,从属于类;
静态非静态static:从属不同而已!!
相同数据类型(任意类型)元素的有序集合;
数组也是对象,数组元素相当于成员变量,只是没有名,可通过索引访问;
数组长度确定;
数组声明后,为引用数据类型,自动继承自Object类;
数组声明:(在堆里开辟空间)
int[] iArray;
iArray = new int[n]; //(在堆里开辟存储空间)
String[] sArray;
//自定义类型
myClass[] cArray;
操作对象即操作对象的引用!!(除基本数据类型外)
见内存分析!!
数组声明;int[] a; myClass[] c;
数组创建:a = new int[n]; c = new myClass[n]
数组初始化:
a[0] = 1;
c[0] = new myClass(xx);
a = {1,2,3};
c = {
new myClass(x1),
new myClass(x2)
}; //静态初始化
方式:
1. 默认初始化。数组元素相当于对象的成员变量。
数值0,布尔false,char '\u0000'
2. 动态初始化
3. 静态初始化
数据为基本的引用数据类型;
大部分容器的内部实现为数组;
内部有由字符数组private final char[] value;实现,修饰符private表示数组外部不可见,final表示char地址不可变
数组的典型应用;线性表的顺序实现;
"abc"是String的一个实例对象;
equals 比较内容;
字符串对象
字符串常量 内存存储有差别!!
内存分析!!
可变字符序列;
StringBuilder(线程不安全,效率高);
StringBuilder(线程安全,效率低);
return this; 可以构成方法链,链式调用;
看源码,分析源码;内部有char[] value;字符数组实现!!(无private修饰可见,无final修饰可变)
通过数组扩容实现:
扩容具体通过将原数组copy到一个新的容量更大的数组来实现;
老数组通过垃圾回收机制回收;
***大多数容器类的底层实现通过Object[] elem;来实现!!
**部分通过链表实现??
***c语言c++语言中的容器,各种语言中的容器
**其实际上可以通过构建指针数组(地址数组)来实现!!!
多维数组:数组的数组;
int[][] a = {
{1,2},
{3,4,0,9},
{5,6,7},
};
int[][] a = new int[3][];
a[0] = new int[2];
a[1] = new int[4];
a[2] = new int[3];
a[0][0] = 1;
a[0][1] = 2;
a[1][0] = 3;
...
a[2][2] = 7;
二维数组内存分析;
提供各种关于数组操作的API,如复制,排序,搜索等;
Comment: