面向对象-static关键字

本文深入浅出地介绍了Java中static关键字的基本概念、特点及其应用场景,包括如何使用static关键字来优化代码,减少内存开销,以及如何正确使用静态方法和静态变量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

static关键字的引入:


/*
	定义一个人类
	
	姓名和年龄都是变化的,这个我能接收,因为每个人的姓名和年龄是不同的。
	但是,我们现在选取的几个人都是中国人,他们的国籍是一样的。
	一样的国籍,我每次创建对象,在堆内存都要开辟这样的空间,
	我就觉得有点浪费了。怎么办呢? 
		针对多个对象有共同的这样的成员变量值的时候,
		Java就提高了一个关键字来修饰:static。
*/
class Person {
	//姓名
	String name;
	//年龄
	int age;
	//国籍
	//String country;
	static String country;
	
	public Person(){}
	
	public Person(String name,int age) {
		this.name = name;
		this.age = age;
	}
	
	public Person(String name,int age,String country) {
		this.name = name;
		this.age = age;
		this.country = country;
	}
	
	public void show() {
		System.out.println("姓名:"+name+",年龄:"+age+",国籍:"+country);
	}
}

class PersonDemo {
	public static void main(String[] args) {
		//创建对象1
		Person p1 = new Person("邓丽君",16,"中国");
		p1.show();
		
		//创建对象2
		//Person p2 = new Person("杨幂",22,"中国");
		//p2.show();
		Person p2 = new Person("杨幂",22);
		p2.show();
		
		//创建对象3
		//Person p3 = new Person("刘亦菲",20,"中国");
		//p3.show();
		Person p3 = new Person("刘亦菲",20);
		p3.show();
		
		//------------------------------------------
		//这些对象共享同一个静态修饰的成员
		p3.country = "美国";
		p3.show();//..."美国"
		p1.show();//..."美国"
		p2.show();//..."美国"
		
	}
}

static关键字的特点:


/*
	static的特点:(它可以修饰成员变量,还可以修饰成员方法)
		A:随着类的加载而加载
			回想main方法。
		B:优先于对象存在
		C:被类的所有对象共享
			举例:咱们班级的学生应该共用同一个班级编号。
			其实这个特点也是在告诉我们什么时候使用静态?
				如果某个成员变量是被所有对象共享的,那么它就应该定义为静态的。
			举例:
				饮水机(用静态修饰)
				水杯(不能用静态修饰)
		D:可以通过类名调用
			其实它本身也可以通过对象名调用。
			推荐使用类名调用。
			
			静态修饰的内容一般我们称其为:与类相关的,类成员
*/
class Student {
	//非静态变量
	int num = 10;
	
	//静态变量
	static int num2 = 20;
}

class StudentDemo {
	public static void main(String[] args) {//main方法为什么是静态的,因为是被虚拟机调用的,不用创建对象
		Student s = new Student();
		System.out.println(s.num);       //10
		
		System.out.println(Student.num2);//20,类名调用
		System.out.println(s.num2);      //20,也可以被对象名调用
	}
}

static的内存图解:静态的内容在方法区的静态区


static关键字注意事项:


/*
	static关键字注意事项
		A:在静态方法中是没有this关键字的
			如何理解呢?
				静态是随着类的加载而加载,this是随着对象的创建而存在。
				静态比对象先存在。
		B:静态方法只能访问静态的成员变量和静态的成员方法
				静态方法:
					成员变量:只能访问静态变量
					成员方法:只能访问静态成员方法
				非静态方法:
					成员变量:可以是静态的,也可以是非静态的
					成员方法:可是是静态的成员方法,也可以是非静态的成员方法。
			简单记:
				静态只能访问静态。
*/


静态方法只能访问静态的成员变量和静态的成员方法:



在静态方法中是没有this关键字的:


静态变量和成员变量的区别

A:所属不同

    静态变量:属于类,类变量

    成员变量:属于对象,对象变量,实例变量

B:内存位置不同

    静态变量:方法区的静态区

    成员变量:堆内存

C:生命周期不同

    静态变量:静态变量是随着类的加载而加载,随着类的消失而消失

    成员变量:成员变量是随着对象的创建而存在,随着对象的消失而消失

D:调用不同

    静态变量:可以通过对象名调用,也可以通过类名调用

    成员变量:只能通过对象名调用

--------------------------------------------------------------------------------------------------

main方法的格式详细解释:


/*
	main方法的格式讲解:
		public static void main(String[] args) {...}
		
		public:公共的,访问权限是最大的。由于main方法是被jvm调用,所以权限要够大。
		static:静态的,不需要创建对象,通过类名就可以。方便jvm的调用。
		void:因为我们曾经说过,方法的返回值是返回给调用者,而main方法是被jvm调用。你返回内容给jvm没有意义。
		main:是一个常见的方法入口。我见过的语言都是以main作为入口。
		String[] args:这是一个字符串数组。值去哪里了?
			这个东西到底有什么用啊?怎么给值啊?
				这个东西早期是为了接收键盘录入的数据的,现在不用了。
				格式是:
					java MainDemo hello world java
				JDK5后用 Scanner s = new Scanner(System.in); 
*/
class MainDemo {
	public static void main(String[] args) {
		//System.out.println(args);        //[Ljava.lang.String;@175078b
		//System.out.println(args.length); //0
		//System.out.println(args[0]);     //ArrayIndexOutOfBoundsException 数组越界
		
		//接收数据后
		System.out.println(args); 
		System.out.println(args.length); 
		//System.out.println(args[0]); 
		for(int x=0; x<args.length; x++) {
			System.out.println(args[x]);
		}
		
		Scan
	}
}

工具类中使用静态:


/*
	我想要对数组进行操作
	
	在同一个文件夹下,类定义在两个文件中和定义在一个文件中其实一样的。
*/
class ArrayDemo {
	public static void main(String[] args) {
		//定义数组
		int[] arr = {28,55,37,46,19};
		
		//需求:遍历数组
		/*
		for(int x=0; x<arr.length; x++) {
			if(x == arr.length-1) {
				System.out.println(arr[x]);
			}else {
				System.out.print(arr[x]+", ");
			}
		}
		*/
		
		//如果我有多个数组都要进行遍历,那么,代码的重复度就很高
		//如何改进呢?用方法改进
		//调用
		//静态方法
		//printArray(arr);
		
		//非静态方法
		//ArrayDemo ad = new ArrayDemo();
		//ad.printArray(arr);
		
		//测试类的作用:创建其他类的对象,调用其他类的功能。
		//而我们现在的操作是跟数组相关的,所以,你应该把这些操作定义到数组操作类中
		//定义一个数组的操作类
		//有了数组操作类之后的调用
		//ArrayTool at = new ArrayTool();
		//at.printArray(arr);
		
		//方法改进为静态后,就可以直接通过类名调用
		ArrayTool.printArray(arr);
	}
	
	/*
	public static void printArray(int[] arr) {
		for(int x=0; x<arr.length; x++) {
			if(x == arr.length-1) {
				System.out.println(arr[x]);
			}else {
				System.out.print(arr[x]+", ");
			}
		}
	}
	*/
	
	//假设该方法不是静态的
	/*
	public void printArray(int[] arr) {
		for(int x=0; x<arr.length; x++) {
			if(x == arr.length-1) {
				System.out.println(arr[x]);
			}else {
				System.out.print(arr[x]+", ");
			}
		}
	}
	*/
}


class ArrayTool {
	
	//把构造方法私有,外界就不能在创建对象了
	private ArrayTool(){}

	public static void printArray(int[] arr) {
		for(int x=0; x<arr.length; x++) {
			if(x == arr.length-1) {
				System.out.println(arr[x]);
			}else {
				System.out.print(arr[x]+", ");
			}
		}
	}
	
}

工具类的完善:


/*
	我想要对数组进行操作
	
	如何制作一个说明书呢?
		A:写一个工具类
		B:对这个类加入文档注释
			怎么加呢?
			加些什么东西呢?
		C:用工具解析文档注释
			javadoc工具
		D:格式
			javadoc -d 目录 -author -version ArrayTool.java
			
			目录:就可以写一个文件夹的路径
			
	制作帮助文档出错:
		找不到可以文档化的公共或受保护的类:告诉我们类的权限不够
*/
class ArrayDemo {
	public static void main(String[] args) {
		//定义数组
		int[] arr = {28,55,37,46,19};
		
		//遍历
		ArrayTool.printArray(arr);

		//获取最值
		int max = ArrayTool.getMax(arr);
		System.out.println("max:"+max);
		
		//获取55的索引值
		int index = ArrayTool.getIndex(arr,55);
		System.out.println("index:"+index);
	}
}


/**
* 这是针对数组进行操作的工具类
* @author ZHOU_VIP
* @version V.10
*/
public class ArrayTool {
	
	//把构造方法私有,外界就不能在创建对象了
	/**
	* 这是私有构造
	*/
	private ArrayTool(){}

	/**
	* 这是遍历数组的方法,遍历后的格式是:[元素1, 元素2, 元素3, ...]
	* @param arr 这是要被遍历的数组
	*/
	public static void printArray(int[] arr) {
		System.out.print("[");
		for(int x=0; x<arr.length; x++) {
			if(x == arr.length-1) {
				System.out.println(arr[x]+"]");
			}else {
				System.out.print(arr[x]+", ");
			}
		}
	}
	
	/**
	* 这是获取数组中最大值的方法
	* @param  arr 这是要获取最大值的数组
	* @return 返回数组中的最大值
	*/
	public static int getMax(int[] arr) {
		int max = arr[0];
		
		for(int x=1; x<arr.length; x++) {
			if(arr[x] > max) {
				max = arr[x];
			}
		}
		
		return max;
	}
	
	/**
	* 获取指定元素在数组中第一次出现的索引,如果元素不存在,就返回-1
	* @param arr 被查找的数组 
	* @param value 要查找的元素
	* @return 返回元素在数组中的索引,如果不存在,返回-1
	*/
	public static int getIndex(int[] arr,int value) {
		int index = -1;
		
		for(int x=0; x<arr.length; x++) {
			if(arr[x] == value) {
				index = x;
				break;
			}
		}
		
		return index;
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZHOU_VIP

您的鼓励将是我创作最大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值