Java发展

  • 1991年4月,James Gosling博士领导启动绿色计划,开发出Oak语言;
  • 1995年5月23日,Oak语言改名为Java,发布Java1.0版,第一次提出"write once, run anywhere"口号;
  • 2006年12月11日,Sun公司用Java SE,Java EE和Java ME分别替代J2SE,J2EE和J2ME;
  • 2009年4月20日,Oracle公司正式收购Sun公司;

OpenJDK是Oracle JDK的一种开源版本,OpenJDK7与Oracle JDK7大致相同,是一种精简版的JDK;


Java环境变量配置相关

  • Path/PATH环境变量:变量值是一系列路径,Win系统依次在路径中查找命令,找到则该命令可执行;
  • 使用JDK1.5之前的版本,才需要设置CLASSPATH环境变量;
  • Win操作系统不区分大小写,故设置Path与PATH无区别;

Linux系统区分大小写, 只需设置 PATH环境变量即可;


Java基本数据类型

Java是强类型语言,强类型包含两方面含义:

  • 所有变量必须先声明,后使用;
  • 指定类型的变量只能接受符合其类型的值;

Java中共有8种基本类型(primitive type),分别有对应的包装类(wrapper class);

基本类型存储在栈中,因此存取速度要快于在堆中的包装类对象;

Java基本类型中不存在无符号类型,字段长度和取值范围固定,基本类型的取值范围以 常量形式定义在对应的包装类中(Boolean除外),

基本类型

字节位数

对应包装类

boolean

1

Boolean

char

2

Character

byte

1

Byte

short

2

Short

int

4

Integer

long

8

Long

float

4

Float

double

8

Double

  • WarpperClassInstance.SIZE表示对应基本类型的二进制存储位数;
  • WarpperClassInstance.BYTES表示对应基本类型的字节存储位数;
  • WarpperClassInstance.MIN_VALUE/MAX表示对应基本类型的最小取值;
  • boolean类型采用16位Unicode编码;

// 巨型整数值后加L,强制使用long(int)类型// Java中整型变量默认为intint bigValue = 999999999999L; 
   // 二进制整数以0b或者0B开头int binaryValue = 0B01101001;// 八进制整数以0b开头int ocValue = 013;// 十六进制整数以0x或者0X开头, a~f不区分大小写int hexValue = 0XAF;// Java中浮点数变量默认为double类型,使用float变量,必须在数值后加f或Ffloat a = 5.12F// 浮点数还可用科学计数法表示,5.12e2 = 5.12*10-4

包装类(Wrapper Class)

所有包装类都使用final修饰,无法继承和重写;

基本数据类型变量—>包装类变量,通过 直接赋值/ new WrapperClass ( primitive )

protobuf pythton和java性能差距 java和pathon_c/c++

WrapperInstance.xxxValue() ;

protobuf pythton和java性能差距 java和pathon_数据库_02

自动装箱与自动拆箱实现基本数据类型与包装类对象之间的转换;

包装类实现基本数据类型与字符串转换:

Xxx.parseXxx()方法/WrapperClass提供的Xxx(String str)重载构造器

protobuf pythton和java性能差距 java和pathon_Java_03

String.valueOf()方,Boolean类型也可转换为String变量"true"/"false"

protobuf pythton和java性能差距 java和pathon_包装类_04

基本数据类型与包装类

  • 所有相同包装类对象进行判等操作时,强制使用equals()方法判等;
  • 局部变量使用基本数据类型;
  • long/Long类型初始赋值时,必须使用大写的L,小写容易与1混淆;

Java String类/字符串

String的不可变性/线程安全

protobuf pythton和java性能差距 java和pathon_包装类_05

protobuf pythton和java性能差距 java和pathon_java_06

  • String类字符串值使用final类型的字符数组存储,因此一旦赋值不可改变;
  • 构造方法中使用Array.copyof方法赋值,并开辟内存空间;
  • String类使用final修饰符,表示String类不可继承;
  • String类提供的所有方法中,有返回String的一律新建一个String对象,防止对原String对象进行修改;

String对象内存分配

字符串常量池:位于常量池中,由String类私有维护,池中元素都是String对象,每个String对象的字面值是 唯一的,由GC回收;

String常量对象创建场合:当String对象第一次常量赋值和调用String对象调用intern()方法时,常量池中创建对应String常量对象;

String str1 = "abc";String str2 = "abc";String str3 = str1;String str4 = new String("abcd");String str5 = new String("abc");

String对象创建,分为直接常量赋值与new运算符创建;

直接字符串常量赋值

常量 对象拥有字面值"abc",

  • 存在/str2:在栈中创建引用,指向常量池中的Strng常量对象(字面值为"abc");
  • 不存在/str1:在常量池中创建匿名Strng对象(字面值为"abc"),在栈中创建引用,指向String常量对象;

使用new运算符创建

先去字符串常量池检查是否有String对象拥有字面值"abc",

  • 存在/str5:在栈中创建对象引用,在堆区为实例分配内存,但是字符数组value字段保存常量对象(常量池中)的value字段的引用;
  • 不存在/str4:在栈中创建对象引用,在堆区为实例分配内存,在常量池中创建String常量对象,字符数组value字段保存常量对象(常量池中)的value字段的引用;

String类的intern()方法

String str6 = new String("abc");String a = str6.intern();String str7 = "xyz";String b = str7.intern();

str.intern()首先检查常量池中的String常量对象字面值是否有与str.value相等的,若有直接返回对应String常量对象的引用,否则在常量池中创建字面值为str.value的 String常量对象并返回引用;

String判等

  • String类判等可用equals方法和等号运算符:
  • equals()方法检测两个字符串变量/常量是否相等;
  • “==”运算符判断两个String对象的引用地址是否相同,即判断引用变量是否指向同一个对象;

protobuf pythton和java性能差距 java和pathon_数据库_07

 

String:空串与null

if(str.length() == 0)if(str.equals(""))

null表示String对象为空,用if(str == null)判断;

String、StringBuilder类与StringBuffer类辨析

【异】

StringBuilder与 StringBuffer都继承AbstractStringBuilder类(类中定义char[] value),字面值均可变【同】;

线程安全 【异】 ;

StringBuilder方法没有加同步锁,因此线程不安全 ,但在非多线程场景下,效率高于StringBuilder 【异】 ;

【异】 :

  • 使用String类:适用于字符串不频繁变化的场景,比如常量生命,少量变量运算;
  • 使用StringBuilder类:适用于单线程环境下字符串频繁变化的场景;
  • 使用StringBuffer类:适用于多线程环境下字符串频繁变化的场景;

★ String对象"+/+="本质

  • 在进行连接操作(“+”和 “+=”)时,String每次返回一个新的String实例,而StringBuffer/StringBuilder的append()直接返回this
  • String类“+”和 “+=”操作符是Java中唯一重载的两个操作符。这两个操作符都是编译器默认引入了StringBuilder类,最后都调用toString方法返回String对象,StringBuilder临时对象被GC回收,因此效率极为低下;


Java流程控制

  • break默认结束所在的循环,在break后紧跟一个标签(该标签在所在循环的外层循环之前定义),直接结束外层循环:
  • continue默认跳过所在循环的剩余语句,重新开始所在循环的下一次循环,也可紧跟标签,见代码段;
  • return语句与break和continue不同,return直接结束方法,不论return处于多少层循环之内;

outer: // 外层循环,outer作为标识符for(int i=0; i<5; i++) { for(int j=0; j<3; j++) { if(j == 1) //break outer; // 跳出outer所标识的外层循环 //continue outer // 直接结束outer所标识的外层循环的当次循环下的剩余语句,重新开始下一次循环 }}

if/else/for/while/do语句必须使用大括号{},即使只有一行代码,杜绝以下形式:

if (condition) statements

使用If...else if...else表达逻辑时,不允许超过3层,否则使用 状态设计模式实现;

缩进强制采用4个空格,禁止使用tab字符;

如果使用tab缩进,必须设置1个tab为4个空格,在eclipse中勾选“insert spaces for tabs”;

Java数组

- Java数组定义及遍历

Java数组定义时通过new运算符分配内存空间,数组大小可为变量;

protobuf pythton和java性能差距 java和pathon_包装类_08

  • 数组初始化时,数字数组所有元素均初始化为0,boolean数组的元素会初始化为false,对象数组的元素初始化为null;
  • foreach遍历访问数组时,foreach中的循环变量实际为临时变量,遍历时系统将数组元素依次赋给这个临时变量。
  • foreach循环不能改变数组元素的值;
  • 除Map外,各类集合通过iterator()方法(实现了Iterable<T>接口)构造一个迭代器从而实现集合遍历;
  • Java数组是引用类型,指向堆中创建的真实对象,与数组元素分开存放(类似于C指针,不过C中数组名时数组起始元素地址),故必须先初始化后使用;
  • Java"二维数组"实质是一维数组,因为其数组元素是指向一维数组的引用(类似于C中指针的指针);

- Java数组拷贝

数组引用拷贝:数组名赋值,两个数组变量将引用同一个数组;

完整数组拷贝:通过Arrays.copyOf,System.arrayCopy()实现

protobuf pythton和java性能差距 java和pathon_java_09

 


Java控制台输入输出

控制台输入通过java.util.Scanner类实现;

  • String nextLine()    // 读取输入的一行内容,包含空白字符(tab/space)
  • String next()    // 读取输入的第一个单词,过滤空白字符(tab/space)
  • int nextInt() / double nextDouble    // 读取并转换输入的整数/浮点数,非法输入会抛出异常

System.out.println(Object x),自动调用x的toString()方法;

double与float格式化输出均使用%f(与C不同)


Java注释规约/javadoc

  • 类/类属性/类方法的注释必须使用Javadoc规范,使用/** */注释,不得使用//注释,类中必须添加作者信息;
  • 所有抽象方法/接口中的方法必须使用Javadoc规范,说明返回值,参数,异常说明和方法功能;
  • Javadoc注释标记;
  • 方法内部单行注释时,在被注释语句上方另起一行,使用//注释;
  • 方法内部多行注释时,使用/* */注释,与代码对齐;

javadoc只能对public和protected成员进行文档注释,

javadoc可以通过HTML标签实现对文本内容格式化;

javadoc标签:

@see:允许用户链接其他类的文档;

@version:

@author:作者;

@since:指定代码最早使用的版本

@param:

@return:

@throws:

@Deprecated:指出有些特性已经过时,建议用户不再使用;


package, import

package/包机制

Java引入package/包机制,提供了类的多层命名空间/解决类的命名冲突,类文件管理等问题;

package语句负责将类加入指定package中,否则默认加入default package中;

包名统一使用小写单数形式;

package 中的公有类;

  • 当两个package中有重名类需要同时使用时,在每个类名之前加上完整的package名以避免冲突;
  • import static负责导入static方法;

与C++相比,package/包机制类比于namespace命名空间,import语句类比于using指令;