Java学习日志6

First Post:

Last Update:

Word Count:
2.4k

Read Time:
9 min

空指针异常

出现空指针异常的前提条件是:
“空引用”访问实例对象相关的数据时,都会出现空指针异常。

JVM中体现如下:

Image 12.png

参数传递

Java中关于方法调用时的参数传递实际上只有一个规则:
不管你是基本数据类型,还是引用数据类型,实际上在传递的时候都是将变量中保存的那个“值”复制一份,传过去

1
2
3
4
5
6
7
8
9
10
int i = 10;
int j = i; //i传递给j,实际上只是将i变量中保存的10传递给j了,
//j实际上是一块全新的内存空间。


User u = 0x1234;
User u2 = u; //u传递给u2,实际上是将0x1234这个值赋值给u2了,
//u和u2实际上是两个不同的局部变量,
//但是它们这两个变量指向堆内存中同一个java对象。

day09参数传递1.jpg

Image 1.png

构造方法

1.当一个类中没有提供任何构造方法,系统默认提供一个无参数的构造方法。这个无参数的构造方法叫做缺省构造器。

2.当一个类中手动的提供了构造方法,那么系统将不再提供无参数的构造方法。

3.无参数构造方法和有参数构造方法都可以调用。

1
2
Student x = new Student();
Student y = new Student(123);

4.构造方法支持方法重载。在一个类当中构造方法可以有多个,并且所有的构造方法名字都是一样的。(与类名一致)

代码示例:

Student.java:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* @author OliverChen
*/
public class Student {

int id;
String name;
boolean sex;
String address;
int age;

public Student()
{
System.out.println("无参数的构造方法执行了!");
}
public Student(int i)
{
System.out.println(i);
}
}

ConstructorTest.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
/**
* @author OliverChen
*/
public class ConstructorTest {
public static void main(String[] args) {
new Student();
//调用Student类的无参数构造方法

ConstructorTest.doSome();
doSome();
//调用普通方法

Student s1 = new Student();
System.out.println(s1);
//输出“引用”
//只要输出结果不是null,说明这个对象一定是创建完成了

Student s2 = new Student(100);
System.out.println(s2);
//这是调用另一个有参数的构造方法
}


public static void doSome()
{
System.out.println("Do some!!!!");
}
}

综上,构造方法是用来创建对象,并且同时给对象的属性赋值(注意:实例变量没有手动赋值时,系统会使用默认值)

封装

  • 封装的作用:
    1.保证内部结构的安全
    2.屏蔽复杂,暴露简单

  • 如何进行封装?
    第一步:属性私有化(使用private关键字进行修饰)
    第二步:对外提供简单的操作入口:1个属性对外提供两个set和get方法。外部程序只能通过set方法修改,只能通过get方法读取,可以在set方法中设立关卡来保证数据的安全性。

set和get方法都是实例方法,不能带static。

不带static的方法称为实例方法,实例方法的调用必须先new对象。

以下为代码示例:

Person.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
/**
* @author OliverChen
*/
public class Person {
private int age;
//private表示私有的,被这个关键字修饰之后,该数据只能在本类中访问。
//出了这个类,age就无法访问了。

public int getAge() {
return age;
}
//get方法
/*
格式要求:public 返回值类型 get+属性名首字母大写(无参){
return xxx;
}
*/

public boolean setAge(int nianLing) {
int nianLingMax = 150;
if(nianLing < 0 || nianLing > nianLingMax)
{
System.out.println("年龄不合法!");
return false;
}
age = nianLing;
return true;
}
//set方法
/*
格式要求:public 返回值类型 set+属性名首字母大写(有一个参数){
xxx = 参数;
}
*/

//对外提供简单的访问入口
//外部程序只能通过调用以上代码来完成访问
}

PersonTest.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
* @author OliverChen
*/
import java.util.Scanner;
public class PersonTest {
public static void main(String[] args) {
Person p1= new Person();
Scanner s = new Scanner(System.in);
//创建对象
//若仅有private int age;
//则此时person的age彻底在外部不能访问,未免有些过于安全了
//age不能访问,此程序意义不大
int i;
boolean found;
do{
i = s.nextInt();
found = p1.setAge(i);}
while(!found);
System.out.println(p1.getAge());
}
}

static关键字

1、static修饰的统一都是静态的,都是类相关的,不需要new对象。直接采用“类名.”访问。
2、当一个属性是类级别的属性,所有对象的这个属性的值是一样的,建议定义为静态变量。
3、static修饰的变量:静态变量(在类加载的时候执行)
4、static修饰的方法:静态方法

变量根据声明的位置进行划分:

  • 在方法体当中声明的变量叫做:局部变量
  • 在方法体外声明的变量叫做:成员变量

成员变量又可分为:

  • 实例变量
  • 静态变量
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
class VarTest{

// 以下实例的,都是对象相关的,访问时采用“引用.”的方式访问。需要先new对象。
// 实例相关的,必须先有对象,才能访问,可能会出现空指针异常。
// 成员变量中的实例变量
int i;

// 实例方法
public void m2(){
// 局部变量
int x = 200;
}


// 以下静态的,都是类相关的,访问时采用“类名.”的方式访问。不需要new对象。
// 不需要对象的参与即可访问。没有空指针异常的发生。
// 成员变量中的静态变量
static int k;

// 静态方法
public static void m1(){
// 局部变量
int m = 100;
}

}

什么时候变量声明为实例的,什么时候声明为静态的?
如果这个类型的所有对象的某个属性值都是一样的,不建议定义为实例变量,浪费内存空间。建议定义为类级别特征,定义为静态变量,在方法区中只保留一份,节省内存开销。

一个对象一份的是实例变量。
所有对象一份的是静态变量。

实例相关的都是需要new对象的。

代码示例:

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
public class StaticTest{
public static void main(String[] args){
// 访问中国人的国籍
// 静态变量应该使用类名.的方式访问
System.out.println(Chinese.country);

Chinese c1 = new Chinese("1231456456456456","张三");
System.out.println(c1.idCard);
System.out.println(c1.name);

Chinese c2 = new Chinese("7897897896748564","李四");
System.out.println(c2.idCard);
System.out.println(c2.name);

// idCard是实例变量,必须先new对象,通过“引用.” 访问
}
}

// 定义一个类:中国人
class Chinese{

// 身份证号
// 每一个人的身份证号不同,所以身份证号应该是实例变量,一个对象一份。
String idCard;

// 姓名
// 姓名也是一个人一个姓名,姓名也应该是实例变量。
String name;

// 国籍
// 加static的变量叫做静态变量
// 静态变量在类加载时初始化,不需要new对象,静态变量的空间就开出来了。
// 静态变量存储在方法区。
static String country = "中国";

// 无参数
public Chinese(){

}

// 有参数
public Chinese(String s1,String s2){
idCard = s1;
name = s2;
}
}

JVM体现:

016变量什么时候声明为静态变量.png

017变量什么时候声明为静态的2.png

静态代码块

1、使用static关键字可以定义:静态代码块

2、什么是静态代码块,语法是什么?
static {
java语句;
java语句;
}

3、static静态代码块在什么时候执行呢?
类加载时执行。并且只执行一次。
静态代码块有这样的特征/特点。

4、注意:静态代码块在类加载时执行,并且在main方法执行之前执行。

5、静态代码块一般是按照自上而下的顺序执行。

6、静态代码块有啥作用,有什么用?
第一:静态代码块不是那么常用。(不是每一个类当中都要写的东西。)
第二:静态代码块这种语法机制实际上是SUN公司给我们java程序员的一个特殊的时刻/时机。
这个时机叫做:类加载时机

具体的业务:
项目经理说了:大家注意了,所有我们编写的程序中,只要是类加载了,请记录一下类加载的日志信息(在哪年哪月哪日几时几分几秒,哪个类加载到JVM当中了)。
思考:这些记录日志的代码写到哪里呢?
写到静态代码块当中。

代码示例:

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
public class StaticTest{

// 静态代码块(特殊的时机:类加载时机。)
static {
System.out.println("A");
}

// 一个类当中可以编写多个静态代码块
static {
System.out.println("B");
}

// 入口
public static void main(String[] args){
System.out.println("Hello World!");
}

// 编写一个静态代码块
static{
System.out.println("C");
}
}

/*
A
B
C
Hello World!
*/

实例语句块

1、实例语句在类加载时并没有执行。
2、实例语句语法
{
java语句;
java语句;
java语句;
}

3、实例语句块在什么时候执行?
只要是构造方法执行,必然在构造方法执行之前,自动执行“实例语句块”中的代码。
实际上这也是SUN公司为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
public class InstanceCode{

//入口
public static void main(String[] args){
System.out.println("main begin");
new InstanceCode();
new InstanceCode();

new InstanceCode("abc");
new InstanceCode("xyz");
}


//实例语句块
{
System.out.println("实例语句块执行!");
}

// Constructor
public InstanceCode(){
System.out.println("无参数构造方法");
}

// Constructor
public InstanceCode(String name){
System.out.println("有参数的构造方法");
}

}