Java系列10—this、static、final和访问控制修饰符

this、static、final和修饰符

一、this的使用

(1)this使用概述

/**
 * 关于java语言中的this关键字:
 * 	1、this 是一个关键字,翻译为:这个
 * 	2、是一个引用,保存在堆内存中对象的内部,指的是对象自身
 * 	3、创建100个java对象,每一个对象都有一个this,也就是有100个不同的this
 * 	4、this可以出现在实例方法中,this指向当前正在执行这个动作的对象
 * 	5、this多数情况下可以不写
 * 	6、this不能使用在带有static的方法中
 * **/
public class Customer {
	
	String name;   // 实例变量
	public Customer() {
		
	}
	
	public static void main(String[] args) {
		
	}
	
	// 不带有static关键字的方法
	// 比如顾客的购物行为
	// 每一个顾客购物的结果不同
	// 所以购物行为属于对象级别的行为
	// 由于每一个对象在执行购物这个动作的最终结果不同,所以购物这个动作必须有对象参与
	
	// 重点:没有static关键字的方法被称为实例方法
	// 重点:没有static关键字的变量称为实例变量
	// 注意:当一个行为/动作执行的过程当中是需要对象参与的,name这个方法一定要定义为实例方法,不要带static
	
	// 以下方法定义为实例方法,因为每个顾客在真正购物时候,最终的结果都是不同的
	public void shopping() {
		
		// 由于name是一个实例变量,所以这个name访问的时候一定访问的是当前对象的实例变量
		// System.out.println(name+"在购物");
		System.out.println(this.name+"在购物");
	}
	
	
	// static方法不需要对象,直接使用类名调用,所以执行过程中没有对象
	public static void doSome() {
		// 执行过程中没有当前对象,因为带有static的方法是通过类名.方法名访问的
		// 或者说这个上下文中没有当前对象,自然也不存在this
		// doSome方法调用不是对象去调用,是一个类名去调用
		// name是一个实例变量,以下代码没有实例,所以会编译报错
		// System.out.println(name);
	}
	
	public static void doOther() {
		// 想访问时,需要先创建对象
		Customer c = new Customer();
		// 这里访问的name不再是当前调用的实例的name,而是c实例的name
		System.out.println(c.name);
	}
	
}

this内存图分配:

this内存图

(2)this在哪里使用

/*
 * this可以使用在哪里?
 * 	1、可以使用在实例方法当中,代表当前对象
 * 	2、可以使用在构造方法中,通过当前的构造方法调用其他的构造方法
 *重点【记忆】:this()只能放在有效代码的第一行
 * */
public class Date {
	private int year;
	private int month;
	private int day;
	
	// 无参构造器
	/* 需求:当调用时,默认日期为1970,1,1
	 * */
	public Date() {
		
		/*
		this.year = 1970;
		this.month = 1;
		this.day = 1;
		*/
		// 函数可以通过调用下边的构造方法
		// 前提是不能创建新的对象,以下代码代表创建新的对象
		// new Date(1960,1,1);
		
		// 需要采用这种方法进行调用,调用构造方法的另一种方式

		this(1970,1,1);
		
		
	}
	// 有参构造器
	public Date(int year, int month, int day) {
		
		this.year = year;
		this.month = month;
		this.day = day;
	}
	
	public int getYear() {
		return year;
	}
	
	public void setYear(int year) {
		this.year = year;
	}
	public int getMonth() {
		return month;
	}
	public void setMonth(int month) {
		this.month = month;
	}
	public int getDay() {
		return day;
	}
	public void setDay(int day) {
		this.day = day;
	}
	
	public void print() {
		System.out.println(this.year+"年"+this.month+"月"+this.day+"日");
	}
	
}

(3)案例练习

public class Test {
	public static void main(String[] args) {
			
		// 完整方法和省略方法分别调用method1和method2
		Test.method1();	
		method1();
		Test t = new Test();
		t.method2();
		t.method1();
	}
	
	public static void method1() {
		System.out.println("method1 调用");
		
		// 完整方法调用
		Test.doSome();
		// 省略方法调用
		doSome();
		// 完整方法调用
		Test t = new Test();
		t.doOther();
		// 完整访问i
		System.out.println("完整的i:"+t.i);
	}
	
	public void method2() {
		System.out.println("method2 调用");
		Test.doSome();
		doSome();
		
		this.doOther();
		doOther();
		
		System.out.println("完整的i:"+this.i+"缩写的:"+i);
	}
	
	int i;
	public static void doSome() {
		System.out.println("do some!");
	}
	
	public void doOther() {
		System.out.println("do Other!");
	}
}

二、static的使用

(1)static用法概述

带有static时候表示静态的,不管是方法还是变量都上升为类级别的,跟具体的对象无关。

/*
 *  什么时候成员变量声明为实例变量呢?
 *  	所有对象都有这个属性,但是这个属性随着对象的变化而变化
 * 
 *  什么时候成员变量声明为静态变量呢?
 *  	所有对象都有这个属性,但是这个属性不随着对象的变化而变化
 *  
 *  静态变量在类加载的时候,存储在方法区内存中
 *  
 *  所有静态的数据,都可以用“类名.”或“引用.”的方式访问
 *  采用“引用.”访问时,及时引用为null,也不会出现空指针异常
 *  
 *  
 *  关于java的static关键字:
 *  1、static的英语为静态的
 *  2、static修饰的方法是静态方法,访问使用"类名."方法名的方式访问
 *  3、static修饰的变量是静态变量
 *  4、所有static修饰的都为静态的,都可以使用“类名.”的方式调用
 *  5、static修饰的元素都是类级别的特征,跟具体的对象无关。
 * */
public class Chinese {
	
	// 身份证号【每一个对象身份证号不同】
	int id;
	
	// 姓名【每一个对象姓名不同】
	String name;
	
	// 国籍【每一个对象由于都是chinese实例化的,所以每一个中国人的国籍都是中国】
	// 无论通过Chinese类实例化多少对象,这些对象国籍都是“中国”
	// 带static代表静态变量,内存在方法区内存中
	static String Country = "中国";
	

	public Chinese(int id, String name) {
		this.id = id;
		this.name = name;
	}
	
	public static void doSome() {
		System.out.println("Chinese doSome");
	}
}

public class Chinese2 {
	public static void doSome() {
		System.out.println("Chinese2 doSome");
	}
}
public class ChinestTest {

	public static void main(String[] args) {
		
		Chinese zhangsan = new Chinese(1,"zhangsan");
		System.out.println("身份证号:"+zhangsan.id+",姓名:"+zhangsan.name+",国籍:"+Chinese.Country);
		
		Chinese lisi = new Chinese(2,"lisi");
		System.out.println("身份证号:"+lisi.id+",姓名:"+lisi.name+",国籍:"+Chinese.Country);
		
		Chinese2 wangwu = new Chinese2();
		wangwu = null;
		wangwu.doSome();
	
	}
}

(2)方法什么时候定义为静态的?

/*
 * 方法什么时候定义为静态的?
 * 	方法描述的是动作,当所有对象执行这个动作的时候,最终产生的影响是一样的,
 * 	那么这个动作已经不再属于一个对象动作了,可以将这个动作提升为类级别的动作,模板级别的动作。
 * 
 * 
 *   静态方法无法直接访问实例变量和实例方法
 * 
 * 大多数方法都定义为实例方法,一般一个行为或者一个动作在发生的时候,都需要对象的参与
 * 	但是也有例外,例如:大多数“工具类”中的方法都是静态的,因为工具类中的方法不需要实例,直接用“类名
 *.”的方式调用
 * 
 * */


public class StaticTest {
	
	// 实例变量
	int i =10;
	
	// 实例方法
	public void doSome() {
		
	}
	
	public static void main(String[] args) {
		System.out.println(MathUtil.sumInt(10, 20));
	}
	
}

工具类示例:

public class MathUtil {

	public static int sumInt(int a, int b) {
		// TODO Auto-generated method stub
		return a+b;
	}
}

(3)静态代码快和实例代码块

  1. 静态代码块

    /*
     * 可以使用static关键字定义"静态代码块"
     * 1、语法格式
     * 	static{
     * 		java语句	
     * 	}
     * 
     * 2、静态代码快在类加载的时候执行,并且只执行一次
     * 
     * 3、静态代码块在一个类中可以编写多个,并且遵循自上而下的顺序依次执行
     * 
     * 4、静态代码块的作用:
     *  	- 和具体的需求有关,例如项目中在类加载的时刻,或者时机执行代码完成日志的记录。
     *  	- 那么这段记录日志的代码可以放在静态代码块中,完成日志记录
     *  	— 静态代码块是java为程序员准备的一个特殊的时刻,这个特殊的时刻被称为:类加载时刻
     * */
    
    public class StaticTest01 {
    
    	static {
    		System.out.println("static1");
    	}
    	static {
    		System.out.println("static2");
    	}
    	public static void main(String[] args) {
    		
    	}
    }
    
    
  2. 实例代码块

    /*
     * 	实例代码块
     * 		1、实例代码块也可以编写多个,也是遵循自上而下的顺序执行
     * 		2、实例代码块在构造方法执行之前执行,构造方法执行一次,实例代码执行一次
     * 		3、实例代码块也是java语言为程序员准备的一个特殊时刻,这个特殊时刻被称为:对象初始化时机。
     * 
     * */
    	
    public class Test {
    	public Test(){
    		System.out.println("Test类构造函数");
    	}
    	{
    		System.out.println("1");
    	}
    	{
    		System.out.println("2");
    	}
    	public static void main(String[] args) {
    		System.out.println("main begin");
    		Test t = new Test();
    		Test t1 = new Test();
    	}
    }
    
    

三、final关键字

/**
 * 	关于java语言中的final关键字
 * 		1、final是一个关键字,表示最终的,不可变的
 * 		2、final修饰的类无法被继承
 * 		3、final修饰的方法无法被覆盖
 * 		4、final修饰的变量一旦赋值之后不可重新赋值
 * 		5、final修饰的实例变量:必须手动赋值,不能使用系统的默认值
 * 			final int age = 20;
 * 			
 * 		6、final修饰的引用:
 * 			final User user = new User(30);user=null;  // 报错
 * 			一旦指向某个对象之后,不能再指向其他对象,那么被指向的对象无法被垃圾回收机制回收
 * 			final User user = new User(30);user.id = 50;   // 正确
 * 			虽然指向某个对象之后不能指向其他对象,但是所指向的对象内部的内存是可以修改的
 * 		7、final修饰的实例变量一般都要和static连用,被称为常量:
 * 			常量定义的语法格式是:public static final 类型 常量名 = 值;
 * 			Java语法规范要求所有的常量的名字全部大写,每个单词之间使用下划线链接
 * 			常量示例:public static final String GUO_JI = "中国";	
 * 
 * */
public class FinalTest01 {
	public static void main(String[] args) {
		
		final int  i = 10;
//		  i = 20;  // 编译报错,无法为final修饰的变量赋值
		System.out.println(i);
		
		final int m;
		m = 20;   // 编译通过,不能二次赋值
		System.out.println(m);
	}
}	

四、访问控制修饰符

package com.bjpower.javase.test005;

/**
 *  访问控制修饰符
 *  1、访问控制修饰符来控制元素的访问范围
 *  2、访问控制修饰符包括:
 *  	public			公开的,在任何位置都可以访问
 *  	protected		同包,子类中可以访问
 *  	缺省(无修饰符)	同包可以访问
 *  	private			只能在本类中访问
 *  3、访问控制修饰符可以修饰类、变量、方法。。。
 *  4、当某个数据只希望子类使用:protected进行修饰
 *  5、修饰符范围:
 *  	private < 缺省 < protected < public
 *  6、类只能定义public或者缺省
 * 
 * */
public class Test01 {
	
	public static void main(String[] args) {
		
	}
}

package com.bjpower.javase.test005;

public class User {
	
	// 受保护的
	protected int i = 20;
	
	// 缺省的
	int j = 20;
}

猜你喜欢

转载自blog.csdn.net/qq_42486675/article/details/106511029