[关闭]
@lemonguge 2017-09-13T14:50:58.000000Z 字数 7829 阅读 394

Java基础部分(一)

JAVA


一切都是对象

  1. java有两种类型:引用数据类型和8种基本数据类型。
    • 引用数据类型在64位平台上占8个字节;在32位平台上占4个字节,因为持有的是对象在堆内存中的首地址,这需要根据平台来确定。
  2. java的关键字都是小写的,可以通过class关键字创建新的类型。
  3. 类中有字段和方法,又名成员变量和成员函数。
  4. Java中的属性,通常可以理解为gettersetter方法。其中具有一对gettersetter方法被称为类的可读写属性,如果只拥有getter方法则称为可读属性,只拥有setter方法称为可写属性。

    1. public class Person {
    2. // 三个字段
    3. private String name;
    4. private int age;
    5. private String sex;
    6. // 四个方法
    7. // Person类中拥有一个可读写的age属性
    8. public int getAge() {
    9. return age;
    10. }
    11. public void setAge(int age) {
    12. this.age = age;
    13. }
    14. // 可读属性name
    15. public String getName() {
    16. return name;
    17. }
    18. // 可写属性sex
    19. public void setSex(String sex) {
    20. this.sex = sex;
    21. }
    22. }
  5. 通过new关键字在堆内存中创建一个新的实例时,基本数据类型如果作为该实例的成员变量时,会有默认的初始化值,而引用变量的初始化值默认为null

1.基本数据类型

基本数据类型 大小 默认值
boolean - false
char 16bits '\u0000'即null
byte 8bits (byte)0
short 16bits (short)0
int 32bits 0
long 64bits 0l
float 32bits 0.0f
double 64bits 0.0d

byte的范围从-128到127。0111-1111为7F即对应十进制的127

2.方法

  1. 方法包括:名称、参数列表、返回值和方法体。
  2. import是用了告诉编译器想要的类,用来简化书写。
  3. 返回值是void时,在方法的结尾处会有隐式的return ;来退出方法,当然也可以自己写。

    1. //return语句之后不能有语句,否则不能通过编译。
    2. public static void show(){
    3. System.out.println("show");
    4. return;//退出方法
    5. }
  4. main()方法的参数String[] args用于存储命令行参数,多个参数以空格分开。

    1. public class args {
    2. public static void main(String[] args) {
    3. for (String str : args)
    4. System.out.println(str);
    5. }
    6. }
    7. //在命令行中输入java args haha xixi hehe可以看到输出结果。

3.编码风格

  • 类名首字母大写,驼峰风格。
  • 包名都小写,通常反过来使用自己的域名,例cn.jiehong.util。
  • 方法、字段以及对象的引用变量,第一个字母小写,也为驼峰风格。
  • 变量命名:$ 、字母、_开头都行,后面的可以是数字、字母、下划线。
  • 常量一般都是大写。

操作符

  • 操作符接收一个或多个参数,并生成一个新值。
  • 有些操作符可能会改变操作数自身的值,被称为副作用。
  • 几乎所有的操作符都可以操作基本类型,其中===!=可以操作所有的对象。

  • String类支持++=,其中将+称为连接符。

  1. public static void oper() {
  2. int x = 1, y = 2;
  3. System.out.println(x + y + "xy");// 3xy
  4. System.out.println("xy" + x + y);// xy12
  5. }

当编译器观察到一个String后面紧跟一个"+",而这个"+"的后面又紧跟着一个非String类型的元素,就会尝试将这个非String类型的元素转换为String。

  • 基本类型存储了实际的值,并非指向对象的引用;对一个对象进行操作时,我们真正操作的是对对象的引用,引用持有的是对象在堆内存中的首地址。
  1. class Tank {
  2. int level;
  3. }
  4. public class Person {
  5. public static void main(String[] args) {
  6. Tank t1 = new Tank();
  7. Tank t2 = new Tank();
  8. t1.level = 9;
  9. t2.level = 47;
  10. System.out.println("1: t1.level: " + t1.level + ", t2.level: " + t2.level);
  11. t1 = t2;// 将t2持有的引用赋给了t1,t1的引用被覆盖。此时它们指向相同的对象,而不再被t1引用的对象会由垃圾回收器自动清理。
  12. System.out.println("2: t1.level: " + t1.level + ", t2.level: " + t2.level);
  13. t1.level = 27;
  14. System.out.println("3: t1.level: " + t1.level + ", t2.level: " + t2.level);
  15. }
  16. } /* Output:
  17. 1: t1.level: 9, t2.level: 47
  18. 2: t1.level: 47, t2.level: 47
  19. 3: t1.level: 27, t2.level: 27
  20. *///:~

算术操作符

操作符:加号+、减号-、除号/、乘号*以及取模操作符%

  1. public static void mathOper() {
  2. // 涉及负号的取模运算,结果的负号只参考被模数
  3. System.out.println(-5 % 2); // -5为被模数,输出-1
  4. System.out.println(5 % -2); // 1
  5. // 使用47作为随机数生成器的种子,如果没有传值,java会将当前时间作为随机数生成器的种子。
  6. // 种子用于随机数生成器的初始值,随机数生成器对于特定的种子值总是产生相同的随机数序列。
  7. Random rand = new Random(47);
  8. int i, j, k;
  9. // 由于在创建Random对象时提供了种子,就可以在每一次执行程序时都生成相同的随机数。
  10. // 其实也就是不断地从随机数序列中获取值。
  11. j = rand.nextInt(100) + 1;// 从1到100的值。
  12. System.out.println("j : " + j);// j : 59
  13. k = rand.nextInt(100) + 1;
  14. System.out.println("k : " + k);// k : 56
  15. // 整数的算术操作
  16. i = j + k;
  17. System.out.println("j + k : " + i);// j + k : 115
  18. i = j - k;
  19. System.out.println("j - k : " + i);// j - k : 3
  20. i = k / j;
  21. System.out.println("k / j : " + i);// k / j : 0
  22. i = k * j;
  23. System.out.println("k * j : " + i);// k * j : 3304
  24. i = k % j;
  25. System.out.println("k % j : " + i);// k % j : 56
  26. i = j % k;
  27. System.out.println("j % k : " + i);// j % k : 3
  28. // 非整数的算术操作
  29. float u, v, w; // Applies to doubles, too
  30. v = rand.nextFloat();
  31. System.out.println("v : " + v);// v : 0.5309454
  32. w = rand.nextFloat();
  33. System.out.println("w : " + w);// w : 0.0534122
  34. u = v + w;
  35. System.out.println("v + w : " + u);// v + w : 0.5843576
  36. u = v - w;
  37. System.out.println("v - w : " + u);// v - w : 0.47753322
  38. u = v * w;
  39. System.out.println("v * w : " + u);// v * w : 0.028358962
  40. u = v / w;
  41. System.out.println("u = v / w : " + u);// u = v / w : 9.940527
  42. }

赋值运算符

赋值运算符包括:=+=-=*=/=%=

  1. public static void assignOper() {
  2. // 4为int,编译器会自动对4进行检查,4在short的范围内,会自动转换为short,否则会报错
  3. short s = 4;
  4. long l = 200; // 编译器能正确识别类型,可以省略L
  5. // ! byte b = 129; // 编译报错,129大于127(0111-1111)超出了范围。
  6. byte b = (byte) 129;//1000-0001,首位为1,即负数,正数取反加一为该正数对应的负数,所以先减一再取反为0111-1111即-127
  7. b = (byte) 383;//0001-0111-1111,会自动截取低8位,0111-1111即127
  8. //short+int首先向上转为int,后赋值给short需要手动向下转型,否则出现精度丢失的报错
  9. // ! s = s + 1; // 此处编译错误,先算术运算后赋值运算[两次运算]
  10. s += 1;// 会自动将int类型强制转换为short[一次运算]
  11. System.out.println("s : " + s);// 5
  12. int big = Integer.MAX_VALUE;
  13. System.out.println("big = " + big);// big = 2147483647
  14. int bigger = big * 4;// 将big左移两位,1100减1为1011,取反为0100即4
  15. //编译器也不会报错,运行时也不会出现异常,但是结果溢出。要注意!
  16. System.out.println("bigger = " + bigger);// bigger = -4
  17. }

自动递增和递减

  • 自动递增++和自动递减--属于java的快捷运算。
  • 这两个操作符各有两种使用方式,通常称为“前缀式”和“后缀式”。
  • 前缀与后缀分别是相对与变量或表达式的前面还是后面。
  • 后缀式运算结合赋值运算比较特殊,其运算特点:右边运算结束才会赋值给左边,当进行右边运算时,后缀式所操作的变量或者表达式会首先将自己的值进行预存到临时记录值temp中,在右边运算结束时,才会将该临时记录值temp赋值给左边。
  1. public static void autoInc() {
  2. int i = 3;
  3. // 在i++运行结束后才进行赋值运算,i会它的值预存到temp
  4. // i自增后为4,然后将temp赋值给i即i=3
  5. i = i++;
  6. System.out.println("i=" + i);// 输出i=3
  7. // 等价与i=i+1,其实是将i中的值进行预存temp,只是没有用到该temp的值。
  8. i++;
  9. System.out.println("i=" + i);// 输出i=4
  10. }

关系操作符

  • 关系操作符又名比较运算符,运算完的结果一定为boolean(布尔)类型。
  • 关系操作符包括:小于<、大于>、小于或等于<=、大于或等于>=、等于==以及不等于!=
  • 等于==和不等于!=适用于所有的基本数据类型,其他四种比较符不适用与boolean类型。
  • 关系操作符==!=也适用于所有对象,比较的是对象的引用,即对象在堆内存中的首地址是否相等。equals()默认行为是比较引用,与==一样,但是可以通过覆盖该方法达到比较对象的内容(自定义的类一般为成员变量)。

逻辑操作符

  • 逻辑运算符“与”&&、“或”||、“非”!根据参数的逻辑关系生成一个布尔值(truefalse)。
  • 在使用逻辑操作符式,会遇到短路的现象,这种现象将获得潜在的性能提升。
    • &&:当左边为false时,右边不参与运算的。
    • ||:当左边为true时,右边不参与运算的。

按位操作符

  • 按位操作符用来操作整数基本数据类型(int)中的单个“比特”(bit),即二进制位。会对两个参数中对应的位执行布尔代数运算,并最终生成一个结果。
    • 1代表true,0代表false
  • &、或|、异或^和非~
    • &|的效果等同于&&||,按位的“与”和“或”运算不会出现短路,无论左边的运算结果是什么,右边都参与运算。
    • ^异或操作符的运算规律:
      1. 两边结果如果相同,输出是false;两边结果如果不同,输出是true
      2. 任意一个数val和一个数key进行两次异或运算,结果还是val(即val^key^key=val)。
    • ~也称为取反操作符,可以通过正数取反加一为该正数对应的负数来快速计算。
  1. public static void main(String[] args) {
  2. // 对两个整数变量的值进行互换 (不需要第三方变量)
  3. int a = 3, b = 5;
  4. System.out.println("a=" + a + ",b=" + b);//a=3,b=5
  5. a = a ^ b; // a = 3 ^ 5;
  6. b = a ^ b; // b = (3 ^ 5) ^ 5; b = 3;
  7. a = a ^ b; // a = (3 ^ 5) ^ 3; a = 5;
  8. System.out.println("a=" + a + ",b=" + b);//a=5,b=3
  9. // 对一个整数的最后一个字节,高四位和低四位进行换位。
  10. int num = 61;// 0011-1101
  11. int n1 = num & 15;// 15[1111]低四位
  12. int n2 = num & (15 << 4);// 高四位
  13. int n = n1 << 4 | n2 >>> 4;
  14. System.out.println("n=" + n);// n=211,即1101-0011
  15. }

移位操作符

  • 移位操作符操作的运算对象也是二进制的“位”,只用来处理整数类型。
  • 移位操作符包括:左移位<<、“有符号”右移位>>、“无符号”右移位>>>
    • “有符号”的右移>>使用“符号扩展”:若符号为正,则在高位插入0;若符号为负,则在高位插入1。而>>>使用“零扩展”:无论正负,都在高位插入0
    • 对一个数val进行左移<<n,输出val*2^n
    • 对一个正数val进行右移,输出val/(2^n)(取余)。
  1. public static void moveOper() {
  2. // 就像十进制的234,左移两位[23*10*10],得到23400
  3. System.out.println(3 << 2);// 3左移两位。即3*2^2=12
  4. // 就像十进制的234,右移两位[234/(10*10)],得到2
  5. System.out.println(3 >> 2);// 3/4=0
  6. }
  1. 如果对charbyte或者short类型的数值进行移位处理,那么在移位进行之前,它们会被转换为int类型,并且得到的结果也是一个int类型的值。
  2. 若对一个long类型的数值进行处理,最后得到的结果也是long
  3. “移位”可与“等号”(<<=>>=>>>=)组合使用,此时,操作符左边的值会移动由右边的值指定的位数,再将得到的结果赋给左边的变量。其中如果对级别比int低的类型进行<<=>>=>>>=,由于会先被转换为int类型,在进行移位操作,之后被截断,赋值给原来的类型,见下面shortMove()方法。
  1. public static void shortMove() {
  2. short s = -1;
  3. // 1111-1111-1111-1111-1111-1111-1111-1111
  4. System.out.println(formatBinaryString(Integer.toBinaryString(s)));
  5. s >>>= 10;
  6. System.out.println(s);// 输出还是-1,取低16位
  7. // 1111-1111-1111-1111-1111-1111-1111-1111
  8. System.out.println(formatBinaryString(Integer.toBinaryString(s)));
  9. s = -1;
  10. // 11-1111-1111-1111-1111-1111
  11. System.out.println(formatBinaryString(Integer.toBinaryString(s >>> 10)));
  12. }
  13. public static void intMove() {
  14. int i = -1;
  15. // 1111-1111-1111-1111-1111-1111-1111-1111
  16. System.out.println(formatBinaryString(Integer.toBinaryString(i)));
  17. i >>>= 10;
  18. System.out.println(i);// 4194303,即0011-1111-1111-1111-1111-1111
  19. // 11-1111-1111-1111-1111-1111
  20. System.out.println(formatBinaryString(Integer.toBinaryString(i)));
  21. i = -1;
  22. // 11-1111-1111-1111-1111-1111
  23. System.out.println(formatBinaryString(Integer.toBinaryString(i >>> 10)));
  24. }
  25. /**
  26. * 将二进制字符串格式化,便于查看
  27. *
  28. * @author JieHong 2015年5月26日
  29. */
  30. public static String formatBinaryString(String binaryString) {
  31. int length = binaryString.length();
  32. int size = 0;
  33. if (length == 0)
  34. return "";
  35. size = length + length / 4;
  36. if (length % 4 == 0) {
  37. size--;
  38. }
  39. char[] strChar = new char[size];
  40. char[] binChar = binaryString.toCharArray();
  41. for (int i = length, k = size - 1, temp = 1; i > 0; i--, temp++, k--) {
  42. strChar[k] = binChar[i - 1];
  43. if (temp % 4 == 0) {
  44. if (temp < length - 1)
  45. strChar[--k] = '-';
  46. }
  47. }
  48. return String.valueOf(strChar);
  49. }

三元操作符

  • 三元操作符也称为条件操作符,它比较特别,因为它有三个操作数。
  • 表达式采用的形式:boolean-exp ? value0 : value1,比普通的if-else更简练,但是容易产生可读写极差的代码。

类型转换操作符

  • 将希望得到的数据类型置于圆括号内,放在要进行类型转换的值的左边。
  • 截尾和舍入:将结果赋值给较小类型的,要使用类型转换,可能会发生截尾;如果要进行舍入,可以使用Math.round()方法。
  • 提升:对基本数据类型执行算术运算或按位运算,只要类型比int小(即charbyte或者short),那么在运算之前,这些值会自动转换为int
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注