Java基础 & 基本数据类型 & String类

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除外),
基本类型字节位数对应包装类
boolean1Boolean
char2Character
byte1Byte
short2Short
int4Integer
long8Long
float4Float
double8Double
  • WarpperClassInstance.SIZE表示对应基本类型的二进制存储位数;
  • WarpperClassInstance.BYTES表示对应基本类型的字节存储位数;
  • WarpperClassInstance.MIN_VALUE/MAX表示对应基本类型的最小取值;
  • boolean类型采用16位Unicode编码;
 
  1. // 巨型整数值后加L,强制使用long(int)类型
  2. // Java中整型变量默认为int
  1. int bigValue = 999999999999L;
  1. // 二进制整数以0b或者0B开头
  2. int binaryValue = 0B01101001;
  3. // 八进制整数以0b开头
  4. int ocValue = 013;
  5. // 十六进制整数以0x或者0X开头, a~f不区分大小写
  6. int hexValue = 0XAF;
  7. // Java中浮点数变量默认为double类型,使用float变量,必须在数值后加f或F
  8. float a = 5.12F
  9. // 浮点数还可用科学计数法表示,5.12e2 = 5.12*10-4

包装类(Wrapper Class)

Object类提供包装类封装基本数据类型,使得基本数据类型“对象化”;所有包装类都使用final修饰,无法继承和重写
自动装箱(Auto Boxing)基本数据类型变量—>包装类变量,通过直接赋值/new WrapperClass(primitive)

自动拆箱(Auto Unboxing):包装类变量—>基本数据类型变量WrapperInstance.xxxValue()

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

包装类实现基本数据类型与字符串转换:
字符串—>基本数据类型: 包装类提供的Xxx.parseXxx()方法/WrapperClass提供的Xxx(String str)重载构造器

基本数据类型—>字符串:String类提供的重载String.valueOf()方,Boolean类型也可转换为String变量"true"/"false"

基本数据类型与包装类

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


Java String类/字符串

String的不可变性/线程安全

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

String对象内存分配

字符串常量池:位于常量池中,由String类私有维护,池中元素都是String对象,每个String对象的字面值是唯一的,由GC回收;
String常量对象创建场合:当String对象第一次常量赋值和调用String对象调用intern()方法时,常量池中创建对应String常量对象;
  1. String str1 = "abc";
  2. String str2 = "abc";
  3. String str3 = str1;
  4. String str4 = new String("abcd");
  5. String str5 = new String("abc");
String对象创建,分为直接常量赋值与new运算符创建;
直接字符串常量赋值
创建对象时,在编译阶段,编译器先去字符串常量池检查是否有String常量对象拥有字面值"abc",
  • 存在/str2:在栈中创建引用,指向常量池中的Strng常量对象(字面值为"abc");
  • 不存在/str1:在常量池中创建匿名Strng对象(字面值为"abc")在栈中创建引用,指向String常量对象;
使用new运算符创建
创建对象时,程序先去字符串常量池检查是否有String对象拥有字面值"abc",
  • 存在/str5:在栈中创建对象引用,在堆区为实例分配内存,但是字符数组value字段保存常量对象(常量池中)的value字段的引用;
  • 不存在/str4:在栈中创建对象引用,在堆区为实例分配内存,在常量池中创建String常量对象,字符数组value字段保存常量对象(常量池中)的value字段的引用;

String类的intern()方法

  1. String str6 = new String("abc");
  2. String a = str6.intern();
  3. String str7 = "xyz";
  4. String b = str7.intern();
str.intern()首先检查常量池中的String常量对象字面值是否有与str.value相等的,若有直接返回对应String常量对象的引用,否则在常量池中创建字面值为str.value的String常量对象并返回引用;

String判等

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

String:空串与null

空串是长度为0的字符串,判断方式如下:
  1. if(str.length() == 0)
  2. if(str.equals(""))
null表示String对象为空,用if(str == null)判断;

String、StringBuilder类与StringBuffer类辨析

String类对象不可变,线程安全【异】
StringBuilder与StringBuffer都继承AbstractStringBuilder类(类中定义char[] value),字面值均可变【同】
StringBuffer中主要方法用synchronized加了同步锁,因此线程安全【异】
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处于多少层循环之内
  1. outer: // 外层循环,outer作为标识符
  2. for(int i=0; i<5; i++) {
  3. for(int j=0; j<3; j++) {
  4. if(j == 1)
  5. //break outer; // 跳出outer所标识的外层循环
  6. //continue outer // 直接结束outer所标识的外层循环的当次循环下的剩余语句,重新开始下一次循环
  7. }
  8. }
if/else/for/while/do语句必须使用大括号{},即使只有一行代码,杜绝以下形式:
  1. if (condition) statements
使用If...else if...else表达逻辑时,不允许超过3层,否则使用状态设计模式实现;
缩进强制采用4个空格,禁止使用tab字符;
如果使用tab缩进,必须设置1个tab为4个空格,在eclipse中勾选“insert spaces for tabs”;


Java数组

- Java数组定义及遍历

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

- Java数组拷贝

数组引用拷贝:数组名赋值,两个数组变量将引用同一个数组;
完整数组拷贝:通过Arrays.copyOf,System.arrayCopy()实现
 

Java控制台输入输出

控制台输入通过java.util.Scanner类实现;
  • String nextLine()    // 读取输入的一行内容,包含空白字符(tab/space)
  • String next()    // 读取输入的第一个单词,过滤空白字符(tab/space)
  • int nextInt() / double nextDouble    // 读取并转换输入的整数/浮点数,非法输入会抛出异常
System.out.println(Object x),自动调用x的toString()方法;
System.out.printf()用于格式化输出数据,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中;
包名统一使用小写单数形式;

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

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





posted on 2017-03-28 22:13  yzwall  阅读(632)  评论(0编辑  收藏  举报

导航