2022/9/16 java课后作业感悟
1、关于java中的static静态关键字
①静态变量
静态变量可以用于引用所有对象的公共属性(对于每个对象不是唯一的)。如:员工公司名称,学生所在的大学名称。
Java静态属性被共享给所有对象,同于c++;
②静态方法
静态方法属于类,而不属于类的对象。
可以直接调用静态方法,而无需创建类的实例。
静态方法可以访问静态数据成员,并可以更改静态数据成员的值。
package demo1; class stdu{ int id; String name; static String school="无"; public static void change(String n) { school=n; } public void printf() { System.out.println(this.id + " " + this.name+ " " + school); } public stdu(int id, String name) { super(); this.id = id; this.name = name; } public static void main(String[] args) { stdu s1=new stdu(2021,"王王"); stdu s2=new stdu(2022,"李李"); s1.printf(); s2.printf(); stdu.change("石家庄");//调用静态方法更改两人的学校名,使用类名调用就行 s1.printf(); s2.printf(); } }
运行结果为
可见静态方法的调用只需要用类名调用就行,并且静态变量是所有对象共有的。
静态方法也有两个限制:
- 静态方法不能直接使用非静态数据成员或调用非静态方法。
this
和super
两个关键字不能在静态上下文中使用。(super()用于调用父类的构造方法)
③静态代码块
静态代码块的特点如下:
- 静态代码块类似于一个方法,但它不可以存在于任何方法体中。
- 静态代码块可以置于类中的任何地方,类中可以有多个静态初始化块。
- Java 虚拟机在加载类时执行静态代码块,所以很多时候会将一些只需要进行一次的初始化操作都放在 static 代码块中进行。
- 如果类中包含多个静态代码块,则 Java 虚拟机将按它们在类中出现的顺序依次执行它们,每个静态代码块只会被执行一次。
- 静态代码块与静态方法一样,不能直接访问类的实例变量和实例方法,而需要通过类的实例对象来访问。
- 随着类的加载而执行,而且只执行一次
静态代码块:静态代码块在类被加载的时候就运行了,而且只运行一次,并且优先于各种代码块以及构造函数。如果一个类中有多个静态代码块,会按照书写顺序依次执行。后面在比较的时候会通过具体实例来证明。
静态代码块写法;
static{ }
非静态代码块(构造代码块):执行的时候如果有静态初始化块,先执行静态初始化块再执行非静态初始化块,在每个对象生成时都会被执行一次,它可以初始化类的实例变量。非静态初始化块会在构造函数执行时,在构造函数主体代码执行之前被运行。
非静态代码块写法:
{
}
下面为静态代码块与非静态代码块的一个实例:
public class StaticCode { public static int count = 0; { count++; System.out.println("非静态代码块 count=" + count); } static { count++; System.out.println("静态代码块1 count=" + count); } static { count++; System.out.println("静态代码块2 count=" + count); } public static void main(String[] args) { System.out.println("*************** StaticCode1 执行 ***************"); StaticCode sct1 = new StaticCode(); System.out.println("*************** StaticCode2 执行 ***************"); StaticCode sct2 = new StaticCode(); } }
执行结果如下:
这里我发现代码块的作用和构造函数很类似,那么既然已经有了构造函数,为什么还要设计代码块?
原因如下:构造代码块和构造函数的作用类似,都能对对象进行初始化,并且只要创建一个对象,构造代码块都会执行一次。但是反过来,构造函数则不一定每个对象建立时都执行(多个构造函数情况下,建立对象时传入的参数不同则初始化使用对应的构造函数)。利用每次创建对象的时候都会提前调用一次构造代码块特性,我们可以做诸如统计创建对象的次数等功能。
2、静态导入
在 JDK 1.5 之后增加了一种静态导入的语法,用于导入指定类的某个静态成员变量、方法或全部的静态成员变量、方法。如果一个类中的方法全部是使用 static 声明的静态方法,则在导入时就可以直接使用 import static 的方式导入。
/*使用静态导入*/ import static java.lang.System.*; import static java.lang.Math.*; public class stdu { public static void main(String[] args) { // out是java.lang.System类的静态成员变量,代表标准输出 // PI是java.lang.Math类的静态成员变量,表示π常量 out.println(PI); // 直接调用Math类的sqrt静态方法,返回256的正平方根 out.println(sqrt(256)); } } /*使用非静态导入*/ import java.lang.Math; import java.lang.System; public class stdu { public static void main(String[] args) { // out是java.lang.System类的静态成员变量,代表标准输出 // PI是java.lang.Math类的静态成员变量,表示π常量 System.out.println(Math.PI); // 直接调用Math类的sqrt静态方法,返回256的正平方根 System.out.println(Math.sqrt(256)); } }
3、有时去掉子方法里的static报错的原因
public class stdu { public static void main(String[] args) { int result; for (int x = 1; x <= 10; x++) { result = square(x); /*这里的square()进行了报错*/ // Math库中也提供了求平方数的方法 // result=(int)Math.pow(x,2); System.out.println("The square of " + x + " is " + result + "\n"); } } // 自定义求平方数的静态方法 public static int square(int y) { //去掉这里的static后会提示一些错误 return y * y; } }
这里的错误是由于square()是一个非静态的方法,不可这样直接进行调用,可以通过定义一个对象后再通过对象来进行调用。
下面是修改后的:
public class stdu { public static void main(String[] args) { int result; stdu s=new stdu(); //定义一个实例化对象 for (int x = 1; x <= 10; x++) { result = s.square(x); //使用对象来进行函数的调用 // Math库中也提供了求平方数的方法 // result=(int)Math.pow(x,2); System.out.println("The square of " + x + " is " + result + "\n"); } } // 自定义求平方数的静态方法 public int square(int y) { return y * y; } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通