- static修饰符
- main函数关键字解释
- 封装工具
- 静态方法如何使用
- 静态代码块
- 对象初始化过程
static修饰符
/*
static:一个修饰符,用于修饰成员
当成员被static修饰以后,就多了一个调用方式,除了被对象.成员变量调用以外,还可以类名.静态成员变量 调用
用途:减少堆内存的使用,因为每一个对象的建立都会用同一个变量,堆内存会被浪费,所以使用静态变量,建立在方法区,每次建立对象去访问即可
static特点
1.随着类的加载二加载,随着类的消失而消失,也就是说他的生命周期最长
2.优先于所有对象
3.被所有对象都共享
4.可以直接被类名所调用
实例变量和类变量区别
1.存放位置
实例变量随着对象的建立产生在堆内存中,
而类变量随着类的加载二产生在方法区中
2.生命周期
实例变量随着对象的产生而产生
类变量随着类的加载而加载
静态成员使用事项
1.静态方法只能调用静态成员,非静态方法可以调用静态和非晶态成员
2.因为静态变量优先于对象存在,所以静态方法中不可以出现this,super关键字
什么时候使用静态方法:
当函数内部没有涉及到实例变量时
*/
class PersonDemo
{
public static void main(String[] args)
{
Person a=new Person();
a.name="wx";
a.speak();
System.out.println(Person.country);
}
}
class Person
{
static String country="ZN";//静态的成员变量,类变量
String name;//成员变量,也叫实例变量
public void speak()
{
System.out.println(country+"..."+name);
}
}
主函数的理解
/*
主函数
public表示访问权限最大
static表示随着类的加载主函数就加载了
void代表无返回值
main不是关键字,但是时一个特殊的单词,可以被jvm所识别
(String[] arr)代表一个字符串类型的数组参数
主函数的格式时固定的
jvm在调用主函数时,传入的时new String[0]
*/
class Demo
{
public static void main(String[] args) //arguments
{
//System.out.println(args.length+" "+args[0]);//会把编译时后面自己输入的字符串作为函数参数
String[] arr={"aha","sa","gf","gf"};
Demo2.main(arr);//主函数的传参
}
}
class Demo2
{
public static void main(String[] args)
{
for(int i=0;i<args.length;i++)
System.out.println(args[i]);
}
}
制作封装工具
/**
这是一个操作整形数组的工具类ArrTool
包含获取最大最小值,冒泡排序,以及打印输出
javadoc -d myhelp -author -version ArrTool.java
@author 莱茵河
@version 1.1
*/
public class ArrTool//用Javadoc制作文档时必须要是public的类名权限,下面的方法也只会提取public权限的方法
{
/**
取得一个整型数组中的最大值
@param arr[] 获取一个整型数组
@return 会返回最大值max
*/
public static int getMax(int arr[])
{
int max=-999;
for(int i=0;i<arr.length;i++)
{
if(arr[i]>max)
max=arr[i];
}
return max;
}
/**
取得一个整型数组中的最小值
@param arr[] 获取一个整型数组
@return 最小值min
*/
public static int getMin(int arr[])
{
int min=999;
for(int i=0;i<arr.length;i++)
{
if(arr[i]<min)
min=arr[i];
}
return min;
}
/**
取得一个整型数组进行冒泡排序
@param arr[] 获取一个整型数组
*/
public static void arrSort(int arr[])//定义了静态之后,同目录下的其他Java文件可以直接类名.成员方法!进行调用
{
for(int i=0;i<arr.length-1;i++)
{
for(int j=0;j<arr.length-1;j++)
if(arr[j]>arr[j+1])
{
arr[j]=arr[j]^arr[j+1];
arr[j+1]=arr[j]^arr[j+1];
arr[j]=arr[j]^arr[j+1];
}
}
}
/**
对一个整型数组进行打印输出
@param arr[] 获取一个整型数组
*/
public static void printArr(int arr[])
{
System.out.println("[");
for(int i=0;i<arr.length;i++)
{
if(i<arr.length-1)
System.out.println(arr[i]+",");
else
System.out.println("]");
}
}
}
静态方法的调用
class Usestatic
{
public static void main(String[] args)
{
int arr[]={1,52,19,45,742,65,-5};
int max=ArrTool.getMax(arr);
int min=ArrTool.getMin(arr);//直接调用,这就是封装,静态
System.out.println("max="+max+" min="+min);
ArrTool.printArr(arr);
ArrTool.arrSort(arr);
ArrTool.printArr(arr);
}
}
静态代码块的先后执行
/**
静态代码块
static
{
}
随着类的建立而运行,且只运行一次
*/
class StaticDemo
{
StaticDemo()
{
System.out.println("a");
}
static
{
System.out.println("b");
}
{
System.out.println("c");
}
StaticDemo(int x)
{
System.out.println("d");
}
static
{
System.out.println("e");
}
}
class run
{
public static void main(String[] args)
{
//new StaticDemo(4);//结果是b e a d
//说明:
//a没有打印,因为并没有创建对象,所以构造函数并不会被执行,它只会在对象创立的时候执行
//bea说明静态代码块优先于代码块执行
//ad说明代码块优先于方法执行
//StaticDemo a=new StaticDemo();//beca 说明构造函数依旧排在代码块之后执行
new StaticDemo(4);new StaticDemo(4);//becdcd 因为静态代码块只会在第一次类的建立时执行,所以第二次不输出be了
}
}
对象初始化的过程
class PersonDemo
{
public static void main(String[] args)
{
Person a=new Person("zhangsan",20);
a.speak();
}
}
class Person
{
private String name;
private int num=6;
private static String country="ZN";
Person(String name,int num)
{
this.name=name;
this.num=num;
}
{
System.out.println("name="+name+" num="+num);
}
public void speak()
{
System.out.println("name="+name+" num="+num);
}
}
/**
Person a=new Person("zhangsan",20);这一句话干了什么??
1.因为new用到了Person.class,所以jvm会先把Person.class加载到内存中
2.先后执行类中的静态代码块和代码块(如果有的话),进行初始化
3.在堆内存中开辟空间,分配内存地址
4.在堆内存中建立对象特有的属性,并进行初始化
5.对属性进行显示初始化
6.对对象构造代码块初始化
7.对对象进行与之对应的构造函数初始化
8.将内存地址付给栈中的a变量
*/