java基础:入职华为前的重启

前言

以前我学java都是看看菜鸟教程就算了 那时候急功近利 而且因为用的少 每次学完都无一例外会忘记得一干二净 但是明年去华为肯定是需要使用java了 所以现在重新认真学习和使用java 下面是一些基础知识 比较浅显

因为每个小的知识点 我都是会在自己的示例代码里写很多注释 所以就不拓展来讲了


函数参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package basics.parameters;



/*
* 看了书本才知道 原来java的先可以分为:
* 1.基本数据类型
* 2.引用变量 引用变量就是相当于指针了
* 基本数据类型作为函数参数传入是无法被修改的 引用变量作为函数参数传入可以
*
* 除此之外 根据可是否可以被修改 也可以分为两种类型:
* 1.immutable不可修改 比如int跟string
* 2.mutable可修改 比如 StringBuilder
* 两种,不可修改就是当这个类型的参数传入函数中之后 函数中的任何操作都对这个参数不产生实质上的作用*/

public class immutable {

public static void main(String[] args) {
StringBuilder str = new StringBuilder("old");
change(str, str);
System.out.println(str);

String string = new String("lala");
changeStr(string);
System.out.println("after changestr " + string);

int num = 100;
changeInt(num);
System.out.println("after changeInt " + num);
}

/*测试修改StringBuilder的函数
*
* StringBuilder传进来本身是引用变量 是可以被修改的 穿进去之后又因为他本身是mutable的 所以被修改成功*/
public static void change(StringBuilder str0, StringBuilder str1) {
str0.append("append0");
str1.append("append1");

str0 = new StringBuilder("new string builder");
str0.append("new append");
System.out.println("inside func " + str0);
}

/*测试修改string的函数
*
* String传进来的引用变量 所以一开始是可以被修改的 但是因为String是immutable的 所以即使引用变量穿进去之后最后也是修改失败*/
public static void changeStr(String str) {
// string类型的参数 修改效果都是修改了参数的局部变量
str = "change str ";
System.out.println("str inside func " + str);
}

/*测试修改int类型的函数
*
* int这里是作为基本数据类型传进去的 所以本身就不可以被修改 无论是传进去之后是mutable还是immutable的*/
public static void changeInt(int num) {
// int类型的参数 修改效果都是修改了参数的局部变量
num = 10;
System.out.println("inside func" + num);
}
}

输出
微信图片_20181203142538.png-20.1kB


静态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package basics.staticBlock;


/*
* 我们静态static变量都是被共享的 在类初始化的时候执行 具有很高的优先级 想想被其他共享 肯定是需要最早进行执行或者初始化的
*
* static{...}这样的就是静态代码块 也是跟静态变量一样*/

class Parent {
/*所有的静态代码块的优先级都是很高的 在类初始化执行*/
static {
System.out.println("这是父类的静态代码块");
}
public Parent() {
System.out.println("这是父类的构造函数");
}
}

class Son extends Parent {
/*所有的静态代码块的优先级都是很高的 在类初始化执行*/
static {
System.out.println("这是子类的静态代码块");
}
public Son() {
System.out.println("这是子类的构造函数");
}


/*静态方法中不能使用可以被修改的对象 否则会出现线程安全问题*/
public static void TestStaticFunc() {
System.out.println("这是静态方法");
}
}

public class staticBlock {
public static void main(String[] args) {
new Son();
/*静态代码块因为是共享的 所以只被执行一次 在上面那条语句中已经被执行了 所以下面的new语句中不会被执行了*/
new Son();
Son.TestStaticFunc();
}
}

输出
微信图片_20181203142854.png-14.6kB


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package basics.staticBlock;

public class StaticCode {
static String prior = "done";

/*根据输出结果来看 static无论是静态变量还是静态代码块(除了静态方法)
* 都是按照先后顺序来执行的 比如下面的静态变量先进行初始化 再执行下面的静态代码块*/
static String last = f() ? g() : prior;

public static boolean f() {
System.out.println("这是f函数");
return true;
}

public static String g() {
System.out.println("这是g函数");
return "lala";
}

static {
System.out.println("这是静态代码块");
System.out.println(last);
g();
}
public static void main(String[] args) {

}
}

输出
微信图片_20181203143006.png-10.3kB


重载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package basics.overload;

/*方法的重载只允许参数不一样 其他:
* 1.访问控制符
* 2.方法名称
* 都必须一模一样
*
*
*
* 总而言之 重载就是参数不一样而已 只能是参数不一样!!!!!!!*/

public class OverloadMethods {
public void overloadTest() {
System.out.println("这是测试函数");
}
public void overloadTest(int num) {
System.out.println("这是重载的函数内部 传进来的参数为" + num);
}
public static void main(String[] args) {
OverloadMethods overloadMethods = new OverloadMethods();
overloadMethods.overloadTest();
overloadMethods.overloadTest(12);
}
}

输出
微信图片_20181203143326.png-12.3kB


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package basics.overload;


/*
* 方法重载的注意要点已经写在OverloadMethods这个类里面 这里记录一下重载方法匹配的优先级
*
*
* 匹配优先级:
* 1.精确匹配
* 2.如果是基本数据类型 自动转化为更大表示范围的基本类型
* 3.通过自动拆箱与撞线
* 4.同过子类向上转向继承路线一次匹配 就是子类优先的意思
* 5.通过可变参数匹配 可变参数匹配时最低等级的
*
*
* 要注意子类的方法也是可以重载父类的方法的*/

public class Priority {
public void OverloadMethod(int num) {
System.out.println("参数为int的方法");
}
public void OverloadMethod(Integer num) {
System.out.println("参数为Integer的方法");
}
public static void main(String[] args) {
Priority priority = new Priority();
priority.OverloadMethod(7);
}
}

输出
微信图片_20181203143405.png-7.7kB


覆写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package basics.override;

class Father {
protected void DoSomething() {
System.out.println("这是父类函数");
}
}

/*子类覆写的四大要求:
* 1. 子类方法中的访问权限不得小于父类中的
* 2. 子类方法的返回类型必须可以向上转型为父类的返回类型
* 3. 子类方法的异常类型必须可以向上转型为父类的异常类型
* 4. 子类方法的方法签名 参数类型以及个数必须完全一样*/

/*覆写只可以针对:
* 1. 非静态
* 2. 非final
* 3. 非构造方法
*
* 其实不可以覆写静态方法很容易理解 因为静态方法是属于类的 如果子类覆写了父类的静态方法 那么久存在两个名称相同的静态方法 两个都可以能被调用*/

public class Son extends Father {
@Override
public void DoSomething() {
System.out.println("这是子类覆写的函数");
}
public static void main(String[] args) {
Father father = new Son();
father.DoSomething();
/*像下面这样向下转型是不可以的*/
// Son son = new Father();
}
}

输出
微信图片_20181203145213.png-7.7kB


泛型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package basics.template;

class Meat {
@Override
public String toString() {
return "Meat";
}
}
class Soup {
@Override
public String toString() {
return "Soup";
}
}

/*使用泛型的好处:
* 1. 避免使用重载写多种方法
* 2. 类型擦除 避免强制转换带来的风险
*
*
* 什么是类型擦除:
* 所有的泛型参数都相当于转换为Object类型 进去是什么 出来就是什么 避免了类型强制转换带来的风险*/


/*任何在尖括号中的指代一种未知类型 即使放String在尖括号里面 这时候的String也不再是jav.lang.String不一样了*/

public class Stove {
/*尖括号必须位于:
1.类名之后 或者
2.方法返回类型之前*/
public static <T> void heat(T food) {
System.out.println(food + " is done");
}

public static void main(String[] args) {
Meat meat = new Meat();
Soup soup = new Soup();
Stove.heat(meat);
Stove.heat(soup);
}
}

输出
微信图片_20181203143644.png-9.8kB


包装数据类型的缓存

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package basics.boxing;


/*除了float和double之外 其他包装数据类型都会使用缓存 六个包装类直接赋值的时候 就是调用对应包装类的静态工厂valueOf*/
/* public static Integer valueOf(int i) {
如果存在缓存区间里面 就用缓存的
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
如果没有就重新创建一个新的
return new Integer(i);
}*/
public class cache {
public static void main(String[] args) {
/*直接重新创建一个对象 分配内存空间*/
Integer integer = new Integer(11);
System.out.println("新创建的Integer类型" + integer);

/*先查询缓存区是否存在这个值 如果存在就是用缓存中的实例 如果没有就重新new一个*/
Integer integer1 = Integer.valueOf(11);
System.out.println("新建的Integer类型" + integer1);
}
}

输出
微信图片_20181203143821.png-10.1kB