/*
静态:static
用法是一个修饰符 用于修饰成员(成员变量 成员函数)
当成员被静态修饰后就多了一种调用方式除了可以被对象调用外还可以直接被类名调用 类名.静态成员
特有数据随对象存储在堆内存中
方法去(共享区 /数据区)
statict特点
1静态随着类的加载而加载
也就是说静态会随着类的消失而消失说明它的生命周期最长
2优先于对象存在
明确一点:静态是先存在的对象是后存在的
3被所有对象所共享
4可以直接被类名所调研
实例变量和类变量的区别
1存放位置
类变量随着类的加载而存在于方法去中
实例变量随着对象的建立而存在于堆内存中
2生命周期
类变量生命周期最长随着类的消失而消失
实例变量生命周期随着对象的消失而消失
静态的使用注意事项:
1静态方法只能访问静态成员
非静态方法可以访问非静态成员及静态成员
2静态方法中不可以定义this super关键字
因为静态优先于对象存在所以静态方法中不可以出现this
3主函数是静态的
静态有利有弊
利:对对象共享数据进行单独空间的存储,节省空间没必要每一个对象都存储一份
可以直接被类名调用
弊端:生命周期过长,访问出现局限性(静态虽好只能访问静态)
*/
class Person
{
Stringname;//成员变量(实例变量)
staticString country="CN";//静态的成员变量(类变量)
publicstatic void show()
{
System.out.println(name+"::::"+country);
this.haha();
}
public void haha()
{
}
}
class static
{
publicstatic void main(String[] args)
{
//Personp=new Person();
//p.name="zhang";
//p.show();
//System.out.println("p.country");
//System.out.println("Person.country");
Person.show();
}
}
/*
什么时候使用静态?
要从两方面下手:
因为静态修士的内容有成员变量和函数
什么时候定义静态变量(类变量)呢?
当对象中出现共享数据时,该数据被静态所修饰
对象中的特有数据要定义成非静态存在于堆内存中
什么时候定义静态函数?
当功能内部没有访问到非静态数据(对象的特有数据)
那么该功能可以定义成静态的
*/
/*
class Person
{
Stringname;
publicvoid show()
{
System.out.println(name+"haha");
}
}
class static1
{
publicstatic void main(String[] args)
{
// Person p=new Person();
// p.show();
Person.show();
//System.out.println("HelloWorld!");
}
}
*/
class static1
{
publicstatic void main(String[] args)
{
int[]arr={3,4,1,8};
//int[]arr1={};
intmax=getmax(arr);
System.out.println("max="+max);
}
publicstatic int getmax(int[] arr)
{
intmax=0;
for(intx=1;x<arr.length ;x++ )
{
if(arr[x]>arr[max])
{
max=x;
}
}
returnarr[max];
}
}
class Test
{
publicstatic int getmax(int[] arr)
{
intmax=0;
for(intx=1;x<arr.length ;x++ )
{
if(arr[x]>arr[max])
{
max=x;
}
}
returnarr[max];
}
}
/*
静态代码块
格式:
static
{
静态代码块中的执行语句
}
特点:随着类的加载而执行,只执行一次,并优先于主函数
用于给类进行初始化的
*/
class Staticcode
{
intnum =9;
Staticcode();
{
System.out.println("b");
}
static
{
System.out.println("a"+num);//无法访问非静态
}
{
System.out.println("c"+this.num);//构造代码块
}
Staticcode(intx);
{
System.out.println("d");
}
publicstatic void show()
{
System.out.println("showrun");
}
}
class Staticcodedemo
{
static
{
//System.out.println("b");
}
publicstatic void main(String[] args)
{
new Staticcode(4);//a c d
//newStaticcode();
//newStaticcode();
//System.out.println("over");
//Staticcode.show();//类名调用静态
Staticcodes=null;
s=newStaticcode();
}
static
{
//System.out.println("c");
}
}
/*
静态的应用
每个应用程序中都有共性的功能,可以将这些功能进行抽取独立封装 以便复用
虽然可以通过建立Arraytool的对象使用这些工具方法,对数组进行操作
发现了问题
1对象是用于封装数据的,可是Arraytool对象并未封装特有数据。
2操作数组的每一个方法都没有到Arraytool对象中的特有数据
这时就考虑,让程序更严谨,是不需要对象的
可以将Arraytool中的方法都定义成static的。直接通过类名调用即可
将方法都静态后可以方便于使用 但是该类还是可以被其他程序建立对象的
为了更严谨强制让该类对象不能建立对象
可以通过对构造函数私有化完成
接下来,将Arraytool.class发送给其他人,其他人只要将该文件设置到classpath路径下,就可以使用该工具类
但是很遗憾 该类中到底定义了多少个方法,对方不清楚,因为该类并没有使用说明书
开始制作程序的说明书。Java的说明书通过文档注释来完成
*/
/**
这是一个可以对数组进行操作的工具类,该类中提供了获取最值 、排序等功能
@author 张三
@version v1.1
*/
public class Arraytool
{
/**
空参数构造函数
*/
privateArraytool(){}
/**
获取一个整形数组中的最大值
@paramarr 接受一个int 类型的数组
@return会返回一个该数组中的最大值
*/
publicstatic int getmax(int[] arr)
{
intmax=0;
for(int x=1;x<arr.length ;x++ )
{
if(arr[x]>arr[max])
{
max=x;
}
}
returnarr[max];
}
/**
获取一个整形数组中的最小值
@paramarr 接受一个int 类型的数组
@return会返回一个该数组中的最小值
*/
publicstatic int getmin(int[] arr)
{
intmin=0;
for(int x=1;x<arr.length ;x++ )
{
if(arr[x]<arr[min])
{
min=x;
}
}
returnarr[min];
}
/**
给int数组进行选择排序
@paramarr 接受一个int 类型的数组
*/
publicstatic void selectsort(int[] arr)
{
for(int x=0;x<arr.length ;x++ )
{
for(int y=x+1;y<arr.length-1 ;y++ )
{
if(arr[x]>arr[y])
{
swap(arr,x,y);
}
}
}
}
/**
给int数组进行冒泡排序
@paramarr 接受一个int 类型的数组
*/
publicstatic void bubblesort(int[] arr)
{
for(int x=0;x<arr.length-1 ;x++ )
{
for(int y=0;y<arr.length ;y++ )
{
if(arr[y]>arr[y+1])
{
swap(arr,y,y+1);
}
}
}
}
/**
给数组中的元素进行位置的置换
@paramarr 接受一个int 类型的数组
@parama 要置换的位置
@paramb 要置换的位置
*/
privatestatic void swap(int[] arr,int a ,int b)
{
inttemp=arr[a];
arr[a]=arr[b];
arr[b]=temp;
}
/**
用于打印数组中的元素,打印形式:[element1,element2,....]
*/
publicstatic void printarray(int[] arr)
{
System.out.print("[");
for(int x=0;x<arr.length ; x++)
{
if(x!=arr.length-1)
System.out.print(arr[x]+",");
else
System.out.print(arr[x]+"]");
}
}
}
/*
一个类中默认会有一个空参数的构造函数
这个默认的构造喊啊输的权限和所属类一致
如果类没有被public修饰,那么默认的构造函数,也没有public修饰
默认构造函数的权限是随着类的变化而变化的
*/
/*
设计模式:
Java中23中设计模式
单例设计模式:解决一个类在内存中只存在一个对象
想要保证对象唯一
1 为了避免其他程序过多建立该类对象。先禁止其他程序建立该类对象
2还为了让其他程序可以访问到该类对象 只好在本类中自定义一个对象
3为了方便其他程序对自定义对象的访问 可以对外提供一些访问方式
这三部怎么用代码体现?
1将构造函数私有化
2在类中创建一个本类对象
3提供一个方法可以获取到该对象
对于事物该怎么描述还怎么描述
当需要将该事物的对象保证在内存中唯一时就将以上的三步加上即可
*/
class Single
{
privateint num;
publicvoid setNum(int num)
{
this.num=num;
}
publicint getNum()
{
returnnum;
}
privateSingle(){}
privatestatic Single s=new Single();
publicstatic Single getinstance()
{
returns;
}
}
class Singledemo
{
publicstatic void main(String[] args)
{
Singles1=Single.getinstance();
Singles2=Single.getinstance();
s1.setNum(23);
System.out.println(s2.getNum());
/* Single s1=new Single();
Singles2=new Single();
s1.setNum(30);
System.out.println(s2.getNum());
*/
//Students1=Student.getStudent();
//Students2=Student.getStudent();
}
}
/*class Student
{
privateint age;
privatestatic Student s=new Student();
privateStudent(){};
publicstatic Student getStudent()
{
returns;
}
publicvoid setAge(int age)
{
this.age=age;
}
publicint getAge(int age)
{
returnage;
}
}*/
/*
这个是先初始化
称为饿汉式
Single 类一进内存 就已经创建好了对象
开发一般用饿汉式
*/
/*
class Single
{
privatestatic Single s=new Single();
privateSingle(){}
publicstatic Single getinstance()
{
returns;
}
}
*/
//对象的方法被调用时 才初始化 也叫作对象的延时加载 成为:懒汉式
//Single类进内存 对象还没有存在 只有调用instance方法时才建立对象
class Single//面试
{
privatestatic Single s=null;
privateSingle(){}
publicstatic Single getinstance()
{
if(s==null)
{
s=newSingle();
}
returns;
}
}
class Singledemo2
{
publicstatic void main(String[] args)
{
Singles1=Single.getinstance();//调用方法时才在内存中建立对象延时加载
System.out.println("HelloWorld!");
}
}
小例程
/*
需求:获取一段程序运行的时间
原理:获取程序开始和结束的时间并相减即可
获取时间:System.currentTimeMillis();
当代码完成优化后就可以解决这类问题
这种方式模板方法设计模式
什么是模板方法?
在定义功能时,功能的一部分是确定的但是有一部分是不确定的而确定的部分在使用不确定的部分
那么这时就将不确定的部分暴露出去由该类的子类去完成。
*/
abstract class Gettime
{
publicfinal void gettime()//final强制不能复写只能获取时间(功能确定)避免覆盖
{
longstart=System.currentTimeMillis();
runcode();//(不确定功能 暴露出去 由子类完成)
longend=System.currentTimeMillis();
System.out.println("毫秒:"+(end-start));
}
publicabstract void runcode();
}
class Subtime extends Gettime
{
publicvoid runcode()//复写
{
for(int x=0;x<4000 ;x++ )
{
System.out.print(x);
}
}
}
class Templatedemo
{
publicstatic void main(String[] args)
{
//Gettimegt=new Gettime();
Subtimegt=new Subtime();
gt.gettime();
//System.out.println("HelloWorld!");
}
}