计算机编码
中文Windows操作系统中,ANSI 编码代表 GBK 编码;如果一个文本文件是UTF-8编码的,那么在cmd.exe命令行窗口(DOS窗口)中不能正确显示文件中的内容,所以在进行命令行解析的时候,应将要编译执行的代码的编码字符集设置为 ANSI,否则编译都过不了;通俗一点,存储在底层的字节流data(OS利用GBK_encoding转换得到的)用software打开的时候,software设置的coding模式也应是GBK decoding,才能正确显示原来被转化成字节流的文件内容(在unicode系列编码和GBK系列编码中,同一个中文的字符对应的编码不同)。
字符s(visual content)—>>>—字节流(GBKstream/UTF-8stream)
【visual content】—by developsoftware—>>【GBKstream to store data】(ANSI, default)—opened by DOS(default)—from stored GBKstream(ANSI)—>>(【visual content: .java】?middle process)—???by javac(general —unicode way) —>>【.class—unicodestream to store】;
if DOS窗口(OS提供的接口软件?) 指定了 javac Test.java(源文件visual content) 用 UTF-8编解码格式 去识别源文件内容(/映射),即 javac Test.java -encoding utf-8
,相应地也就决定了用来编写.java文件内容的开发软件也应设定成UTF-8编解码格式,才能进行共享content的阅读;
【visual content】—by IDE environment(software, including --javac command function-- : javac Test.java -encoding utf-8)–>>【unicodestream to store data???】; due to java is general—unicode to data in/out
运算符
【位运算符】
各二进制码按补码各位取反;
【取模 %】
符号:取模的结果的符号 >> 与被模数的符号相同;
应用:开发中,经常使用%
来判断能否被除尽的情况;
【自*】
- ++、+=、-=、*=、/= 操作符不会改变本身变量的数据类型;
use自增, due to 不会改变本身变量的数据类型
//自增1
short s1 = 10;
//s1 = s1 + 1; //编译失败 1--default int > short
//s1 = (short)(s1 + 1); //正确的
s1++; //自增1 equals s1 += 1;
System.out.println(s1);
byte a1 =127;
a1++; //consider the binary data stored in IS
System.out.println("a1 = " + a1);
//自增赋值
short s2 = 10;
//s2 = s2 + 2; //fail
s2 += 2; //不会改变s2本身的数据类型
//(s2++)++; //fail
//s2++++; //fail
// n = ++(n++); // illegal
// n = (n++)++;
// n = ++(++n);
// n = (++n)++;
System.out.println(s2);
//自除
int s3 = 6;
s3 *= 0.2; //1 自动截断
System.out.println(s3);
【逻辑与& 短路与&&】
相同点1:& 与 && 的运算结果相同;
相同点2:当符号左边是true结果时,二者都会执行符号右边的运算;
不同点:当符号左边是false结果时,&继续执行符号右边的运算,&&不再执行符号右边的运算;
- 开发中,推荐使用 &&;
【练习】
//练习:交换两个变量的值
int num1 = 10;
int num2 = 20;
System.out.println("num1 = " + num1 + ",num2 = " + num2);
//方式一:定义临时变量的方式
//推荐的方式
int temp = num1;
num1 = num2;
num2 = temp;
//方式二:好处:不用定义临时变量
//弊端:① 相加操作可能超出存储范围 ② 局限性:只能适用于数值类型
//num1 = num1 + num2;
//num2 = num1 - num2;
//num1 = num1 - num2;
//方式三:使用位运算符
//局限性:只能适用于数值类型
//num1 = num1 ^ num2;
//num2 = num1 ^ num2;
//num1 = num1 ^ num2;
System.out.println("num1 = " + num1 + ",num2 = " + num2);
【三元运算符】
- 格式:
类型 (布尔表达式) ? 表达式1 : 表达式2;
; - 要求表达式1、2 是一致的数据类型(可以自动类型提升) ;
//三元运算符对表达式1、2的要求
int a = 12;
char b = 'A';
int max1 = (a > b)? a : b;
//char max1 = (m > n)? m : n; //int-->char 不能自动转
System.out.println(max1);
String p = "a is bigger";
String q = "b is bigger";
String max2 = (a > b)? p : q;
System.out.println(max2);
String c = "123";
String d = "12";
String m = "c is longer";
String n = "d is longer";
String max3 = (c.length() > d.length())? m : n;
System.out.println(max3);
- 三元运算符可以嵌套使用;
- 如果if-else结构可以改成三元运算符方式,优先选择三元运算符 >> 简洁、执行效率高;
【连接符 + 】
String str0 = "abc" + 2 * 3; // abc6
String str1 = "abc" + 2 * 3 + 4; // abc64
String str2 = "abc" + 3 / (double)2 + 4; //abc1.54
String str3 = 3 + 7 + "bank"; //10bank
String str4 = "bank" + 3 + 7; //bank37
loop
【break & continue】
- break 光标即刻移动到指定循环块外的下一行(if 存在上层循环 ---- 到上层循环的第三小块—> xx;xx;xxx)
本来是 ---- by指定循环块对应的终止条件来跳转
- continue 光标即刻移动到指定循环块内的 for语句的下一行—(先执行指定循环的第三小块)
本来是 ---- by指定循环块内循环体的最后一行来跳转
数组
【说在前面】
- Java中的确是有一些超语言的东西,比如两个String对象可以用 + 进行连接,但我们却无法自己写一个类,在其中重载加法运算符;
- Java对数组的操作是指令级的:
数组经Java特殊处理过 >>专门为数组这种引用数据类型定义了取得长度的指令;
数组的length即不是method,也不是field;
【继承于Object类】
- 在Java中,数组是一个典型的特殊类:
没有类文件,它在运行时产生维护;
它有从Object中继承下来的10个方法,但没有重写;
- 应用:如数组可以使用clone() 方法来复制数组:
clone() 方法的返回值是 Object 类型,要使用强制类型转换为适当的类型;
类
【.toString()
:String】
- 静态/非静态:
// 注意Arrays只是数组的一个拓展工具类
System.out.println(Arrays.toString(arr)); //静态方法举例:Arrays重载了Object的toString方法
System.out.println(arr.toString()); //方法举例:数组类型的父类 >>Object类的toString方法
>>
[20, 20, 20]
[I@15db9742
【xxx.equals(xxx)
:boolean】
String str = "12345";
System.out.println(str.equals(arr)); // 字符串对象.equals(数组对象)可以的 由于多态性
>>
false
- String类的方法equals(Object obj)的形参类型为其父类 >> Object类
【Xxx.valueOf(yy)
:Xxx】
- 应用:
Xxx为String类时:输出实体信息yy成字符串形式;
Xxx为包装类时:装箱 >> 使用目标包装类的名去Xxx.valueOf
<< 该方法返回类型为Xxx
;
(可回溯到利用构造器进行装箱)
// ZGAccount zg3 = null;
// System.out.println(zg3.toString()); // 空指针异常
//null根本不能去"." --修改/重写空参方法toString()的内容也无用
ZGAccount zg3 = null;
System.out.println(String.valueOf(zg3)); // 输出null
//valueOf更健壮 --将null作为参数传入
>>
null
---------------------------------------------------------------------------
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
} // String类中的valueOf源码
---------------------------------------------------------------------------
public static Integer valueOf(String s) throws NumberFormatException {
return Integer.valueOf(parseInt(s, 10));
} // Integer类中的静态方法valueOf(String)源码 -----装箱1:String>>int>>Integer
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
} // Integer类中的静态方法valueOf(int)源码 -----装箱2:int>>Integer
...
【练习】:输出实体信息成字符串
- 使用String的静态方法
String.valueOf(xxx):String
:
// ZGAccount zg3 = null;
// System.out.println(zg3.toString()); // 空指针异常
//null根本不能去"." --修改/重写空参方法toString()的内容也无用
ZGAccount zg3 = null;
System.out.println(String.valueOf(zg3)); // 输出null
//valueOf更健壮 --将null作为参数传入
>>
null
---------------------------------------------------------------------------
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
} // String类中的valueOf源码
- 使用包装类的方法
xx.toString():String
- 使用包装类的静态方法
Xxx.toString(xx):String
:
Float flo1 = new Float(1.23);
System.out.println(String.valueOf(flo1));
//没有String.toString(); 只有String.valueOf(Object/int,double,float,char,char[]..):String;
System.out.println(flo1.toString());
//any class has a method extending from Object --toString(), some override some not
System.out.println(Float.toString(flo1));
//有Float.toString(float):String; 也有Float.valueOf(String/float):Float;
System.out.println(Double.toString(12));
>>
1.23
1.23
1.23
12.0
---------------------------------------------------------------------------
public String toString() {
return Float.toString(value);
} // Float类中的xx.toString()源码
---------------------------------------------------------------------------
public static String toString(float f) {
return FloatingDecimal.toJavaFormatString(f);
} // Float类中的静态方法toString(float)源码
public static String toString(int i) {
if (i == Integer.MIN_VALUE)
return "-2147483648";
int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
char[] buf = new char[size];
getChars(i, size, buf);
return new String(buf, true);
} // Integer类中的静态方法toString(int)源码
---------------------------------------------------------------------------
public static Float valueOf(float f) {
return new Float(f);
} // Float类中的静态方法valueOf(float)源码 -----装箱2:float>>Float
public static Float valueOf(String s) throws NumberFormatException {
return new Float(parseFloat(s));
} // Float类中的静态方法valueOf(String)源码 -----装箱1:String>>float>>Float
【匿名对象的使用】
- 使用情形:
类中的方法仅被对象调用一次时
匿名对象作实参传递时
【运行入口】
- 当一个源文件含有多个类时:
源文件名 >> 与 public类名 一致
源文件名 >> eclipse软件默认的内存加载入口 >> 通常public类中含main()方法
非public类也可以存在main() >> 可作为入口(使用IDE编译时需设置),也可作为普通static方法被调用来使用
接口
- 接口中为什么不可以定义变量?
接口提供的统一的抽象;
你认为是要变化的东西,就放在你自己的实现中,不能放在接口中去,接口只是对一类事物的属性和行为更高层次的抽象。对修改关闭,对扩展(不同的实现 implements)开放,接口是对开闭原则的一种体现。
自动拆箱与装箱
【拆箱】
左边为基础类型时;
两边数据value类型涉及到需要强制类型转换(大->小)时,error;
if not可利用基础类型的自动类型提升
;
【装箱】
右边为基础类型时;
两边数据value必须匹配(相同)时,才可直接装箱;
if not可by(int)
等进行基础类型强转;
Float flo1 = new Float(1.23);
1.先默认转化成基础类型,然后可以考虑是否有默认自动类型提升 !!!!!!!!!!!!!!!!!!!!!!!!
float flo10 = flo1; //1.同 directly拆箱
double dou10 = flo1; //2.不同 拆箱->自动类型提升
double dou = 10; //directly自动类型提升
//int int10 = (int)flo1;
//先默认强制转换(int),但此时flo1仍是个Double类对象,不能使用(int)来转换
System.out.println("flo1's value is 1.23 and flo10 is "+ flo10);
System.out.println("flo1's value is 1.23 and dou10 is "+ dou10);
2.先默认转化成类Integer,but类->类之间的转换没有直接的 !!!!!!!!!!!!!!!!!!!!!!!!!
Integer int1 = (int)10.2; //先默认转化成类
Integer int2 = Integer.parseInt("123"); //two steps: String->int->Integer
//Float flo2 = Integer.parseInt("123"); //类型不匹配
//Double dou1 = 10; //error:涉及到类之间的转换 10先默认转化成Integer
Double dou1 = (double)10; //先强制10->10.0 系统再默认装箱到Double
Double dou2 = Double.parseDouble("123.5");
//Integer int1 = Integer.parseInt("123.5"); //java.lang.NumberFormatException
System.out.println(int1);
System.out.println(int2);
System.out.println(dou1);
System.out.println(dou2);
方法Xxx.parseXxx("yyy"):xxx
的使用
- 包装类(除了Character类)的静态方法;
- 将字符串格式的数据"yyy"转成基本数据类型;
- 可以利用自动装箱 >> 包装类的引用变量来接收;
//case1
Float flo1 = Float.parseFloat("123.5"); // String->float-(同类型)->Float
System.out.println("flo1 is "+ flo1);
steps (步骤罗列)
float flo11 = Float.parseFloat("123.5");
Float flo12 = flo11;
System.out.println("flo12 is "+ flo12);
//case2
Integer int2 = (int)Float.parseFloat("123.5"); //String->float-(大->小强转)->int->Integer
System.out.println("int2 is "+ int2);
steps
float flo2 = Float.parseFloat("123.5"); //1
int int21 = (int)flo2; //2
Integer int22 = int21; //3
System.out.println("int22 is "+ int22);
//case3
Float flo3 = (float)Integer.parseInt("123"); //String->int-(小->大强转)>float->Float
System.out.println("flo3 is "+ flo3);
steps
int int3 = Integer.parseInt("123"); //1
float flo31 = int3; //float flo31 = (float)int3; 2
Float flo32 = flo31; //3
System.out.println("flo32 is "+ flo32);