课后作业——2022.09.17(2)(static关键字)
1.基本特征
静态(Static)的意义:即使没有创建对象,也能使用属性和调用方法
静态的内存是固定的,相对来说省资源;
新建一个实例,就要新开辟一个内存,耗费资源
static内部只能出现static变量和其他static方法
static表示“静态”的意思,可以用来修饰成员变量和成员方法。
static的主要作用在于创建独立于具体对象的域变量或者方法。
2.静态变量
在类加载的时候就加载到方法区,而且在方法区会被赋予有默认值
静态变量是先于实例化对象出现的,在创建对象前就可以使用了,故习惯上用类名来调用
静态变量只能定义在类(就是最外层的{})中,不能定义在任何代码块中
非静态变量必须在实例化(new)之后才能分配内存,才可调用
3.静态方法
在类加载的时候就加载到方法区,但在方法区只存储不执行,当其被调用的时候到栈内存中执行
静态方法属于类所有,先于对象存在,类实例化前即可使用
静态方法可以直接调用同类中的静态成员,但不能直接调用非静态成员。非静态方法可以直接访问类中的任何成员
静态方法效率上要比实例化高。但缺点是不自动进行销毁,而实例化的则可以做销毁
静态方法可以通过【类名.方法名】直接调用。普通方法需要创建一个实例,也就是new一个对象,然后通过 【对象名.方法名】的方式来调用
静态方法中还不能使用this等关键字
因为this代表的是对象的引用,它引用的是类的当前实例。而静态方法(加载到jvm的方法区)中没有实例变量(加载到jvm的堆中)
变量 定义位置 初始化值 生命周期 作用范围 内存位置 静态变量
也称类变量
类中方法外以static关键字声明 有默认的初始化的值 第一次访问时创建,在程序结束时销毁 整个类中有效 静态存储区 实例变量
也称成员变量
类中方法外 有默认的初始化的值 对象的存在而存在,随着对象的消失而消失 整个类中有效 堆内存 局部变量 方法内 不赋值不能用 方法的调用而存在,方法调用完毕而消失 所在方法有用 栈内存
静态方法可以重载。可以被继承,但不可以被重写
重载(Overload)
如果同一个类中包含了两个或两个以上方法名相同、方法参数的个数、顺序或类型不同的方法,则称为方法的重载,也可称该方法被重载了。重写(Override)
重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!
重写方法不能抛出新的检查异常或者比被重写方法申明更加宽泛的异常。
4.静态类
静态类只能包含静态成员,否则会抛出编译错误;然而非静态类既可以包含非静态成员也可以包含静态成员
5.static方法
以下是static方法和实例方法的区别:
● 生命周期(Lifecycle):
静态方法(Static Method)与静态成员变量一样,属于类本身,在类装载的时候被装载到内存(Memory),不自动进行销毁,会一直存在于内存中,直到JVM关闭。
非静态方法(Non-Static Method)又叫实例化方法,属于实例对象,实例化后才会分配内存,必须通过类的实例来引用。不会常驻内存,当实例对象被JVM 回收之后,也跟着消失。
● 在内存中存储位置
静态方法和静态变量创建后始终使用同一块内存,是连续的。
非静态方法会存在于内存的多个地方,是离散的。
● 效率
静态方法的使用效率比非静态方法的效率高。
● 线程安全
静态方法是共享代码段,静态变量是共享数据段。既然是“共享”就有并发(Concurrence)的问题。
非静态方法是针对确定的一个对象的,所以不会存在线程安全的问题。
● 使用范围
静态方法:
⒈ 有静态属性的类,一般会定义静态方法。
⒉ 没有属性的类,一般会定义静态方法。
⒊ 如果一个方法与他所在类的实例对象无关,那么它就应该是静态的。静态方法可以被继承但是不能被覆盖。
● 总计
如果静态方法在系统中定义太多,会占用大量的资源,最后造成内存溢出,所以静态方法不能滥用。如果从线程安全、性能、兼容性上来看,选用实例化方法为宜。
一般来说, 在程序里面,一些使用频率高的方法就用static 方法、使用频率低的则用实例方法。
注意:
- 静态方法中可以直接调用同类中的静态成员,但不能直接调用非静态成员。
- 如果希望在静态方法中调用非静态变量,可以通过创建类的对象,然后通过对象来访问非静态变量。
- 在普通成员方法中,则可以直接访问同类的非静态变量和静态变量。
- 静态方法中不能直接调用非静态方法,需要通过对象来访问非静态方法。
6.去掉static报错原因
1.java中 静态方法不可以直接调用非静态方法和成员,也不能使用this关键字(这就是这个问题的原因,用静态的main方法调用了非静态的的求平方数方法)。
原因解释:类中静态的方法或者属性,本质上来讲并不是该类的成员,在java虚拟机装在类的时候,这些静态的东西已经有了对象,
它只是在这个类中”寄居”,不需要通过类的构造器(构造函数)类实现实例化;
而非静态的属性或者方法,在类的装载是并没有存在,需在执行了该类的构造函数后才可依赖该类的实例对象存在。
所以在静态方法中调用非静态方法时,编译器会报错(Cannot make a static reference to the non-static method func() from the type A)。
总结:
1)java中不能将方法体内的局部变量声明为static
2)main()函数是静态的,没有返回值,形参为数组。
3)非静态成员的可以随便调用静态成员
7.去掉static报错例子
import java.util.Random; import java.util.Scanner; public class one { public static void main(String[] args) { Random ran = new Random(System.currentTimeMillis());//以当前时间为种子 Scanner input = new Scanner(System.in); System.out.print("Enter the number of randomnumbers:");//从键盘输入要产生随机数的个数 int in = input.nextInt(); int j=0;//引入j用来输出换行符 produce(in, j); } public static void produce(int in,int j) { Random ran = new Random(System.currentTimeMillis());//以当前时间为种子 for(int i = 0 ; i < in ; i++) { System.out.print(ran.nextInt()+"\t");//利用for循环输出所产生的随机数 j+=1; if(j==6){ System.out.println(); j=0; } } } }
若删掉生成随机数的方法中的static关键字
则报错