java之6天 static代码块,单例模式

1 篇文章 0 订阅
1 篇文章 0 订阅
static(静态) 关键字

//用于修饰成员(成员变量和成员函数)

//被static修饰后的特点
  1.随着类的加载而加载,消失而消失(说明生命周期随着类)
  2.优先于对象存在
  3.被所有对象共享
  4.可以直接被类名调用
  5.静态变量定义多了,就会消耗更多的内存 


//实例变量 和 类变量(静态变量)的区别
  1.存放位置
     类变量随着类的加载而存在方法区中
     实例变量随着对象的建立存在与堆内存中
  2.生命周期
    类变量的生命周期最长:  随着类的消失而消失
    实例变量生命周期随着对象的消失而消失
  

//使用注意
  1.静态方法只能访问静态成员(方法和变量)
    非静态可以访问静态也可以访问非静态

  2.静态方法中不可以写 this,super 关键字
      因为静态优先于对象存在,所以静态方法中不可以出现this.

  3.主函数是静态的.

//静态有利有弊
  利: 对对象共享数据进行单独空间的存储,节省空间,没有必要每个对象中都存储一份.
      可以直接被类名调用.

  弊端:生命周期过长
       访问出现局限性(静态虽好,只能访问静态)



static 的使用 为了节约内存的使用  (如果多个对象拥有同样的属性)

class Person{
  String name;  //成员变量,实例变量
  static String country="CN";  //静态的成员变量,类变量
  public void show(){
   System.out.println(name+":::"+country);
  }

}

/**
主函数: 是一个的特殊的函数,作为程序的入口,可以被JVM调用

主函数的定义: 
public: 代表着该函数访问权限是最大的.
static: 代表着主函数随着类的加载 就已经存在了.
void:   主函数没有具体的返回值.
main: 不是关键字,但是是一个特殊的单词,可以JVM识别
String[] args: 函数的类型,参数类型是一个数组,该数组中的元素是一个字符串,字符串类型的数组.
主函数是固定格式的:JVM识别.
args:arguments : 就只有这个变量名可以 修改

JVM再调用主函数时, 传入的是new String[0];
*/

public static void main(String[] args){


}
//重载
public static void main(int x){}

//重载
public static void main(String[] args,int x){ }


DOS 中 给 main传递 参数
c:\> javac MainDemo.java

c:\> java MainDemo haha hehe heihei xixi wuwu   

//还一种 给main传递参数

class MainDemo{

     public static void main(String[] args){
        
      String [] arr={"hah","hehe","heihei","xixi","wuwu","hiahia"};
     
         MainTest.main(arr);
     }
}

class MainTest{

   public static void main(String[] args){
     for(int x=0;x<args.length;x++)
       System.out.println(args[x]);

   }

}



//什么时候使用静态??
要从两方面下手 
因为静态修饰的内容有成员变量和函数

//什么时候定义静态的变量(类变量)呢?
  当对象中出现共享数据时, 该数据被静态所修饰 存在方法区中.
   对象中的特有数据要定义成非静态存在于堆内存中

//什么时候定义静态的函数呢?
  当功能内部没有访问到非静态数据(对象的特有数据)
   那么该功能可以定义成静态的.

//静态的应用
  //对象是用来封装数据的,如果某个方法没有使用到 对象中的特有数据,就可以定义成static的 

//为了是某个类不然用户建立对象, 可以见构造函数私有化 .


/**
一个类中默认会有一个空参数的构造函数
这个默认的构造函数的权限恶化所属类一致.

1.如果类的被public 修饰,那么默认的构造函数,也带有public 修饰符

2.如果类没有被public修饰,那么默认的构造函数,也没有public修饰.

默认的构造函数的权限是随着类的变化而变化的
*/


帮助文档的制作

/使用  javadoc 来创建java类的说明书 
c:\> javadoc -d c:\javadoc  -author -version  MyTools.java

在c:\javadoc 中 创建 MyTools工具类的 说明书 

//注意 :  要生成说明书的类必须 是public 修饰


/**
 * 自定义 数组的 和 进制转换 工具类
 * @author Bin
 * @version V1.1
 */
public class MyTools {
	 
	private MyTools() {
	}

	/**
	 * 获取最大值 采用 元素值表示
	 * 
	 * @param arr
	 *            接受一个int 类型的数组
	 * @return 返回该数组中的最大值
	 */
	public static int getArrMax(int[] arr) {

		int max = arr[0];
		for (int x = 0; x < arr.length; x++) {
			if (arr[x] > max)
				max = arr[x];
		}
		return max;
	}

	/**
	 * 获取数组的最小值
	 * 
	 * @param arr
	 * @return
	 */
	public static int getArrMin(int[] arr) {

		int max = 0;
		for (int x = 0; x < arr.length; x++) {
			if (arr[x] < arr[max])
				max = x;
		}
		return arr[max];
	}

	/**
	 * 选择排序
	 * 
	 * @param arr
	 */
	public static void selSort(int[] arr) {

		for (int x = 0; x < arr.length; x++) {

			for (int y = x; y < arr.length; y++) {
				if (arr[x] < arr[y]) {
					int temp = arr[x];
					arr[x] = arr[y];
					arr[y] = temp;
				}

			}
		}
	}

	/**
	 * 冒泡排序
	 * 
	 * @param arr
	 */
	public static void bubbleSort(int[] arr) {

		for (int x = 0; x < arr.length - 1; x++) {
			// -x:让每一次比较的元素减少,-1 :不让下标越界
			for (int y = 0; y < arr.length - 1 - x; y++) {
				if (arr[y] > arr[y + 1]) {
					swarp(arr, y, y + 1);
				}
			}
		}

	}

	/**
	 * 交换数组中的两个位置
	 * 
	 * @param arr
	 *            接受一个int类型的数组
	 * @param a
	 *            要换的位置1
	 * @param b
	 *            要换的位置2
	 */
	private static void swarp(int arr[], int a, int b) {
		/*
		 * //方法一: int temp=arr[a]; arr[a]=arr[b]; arr[b]=temp;
		 */

		// 方法二
		arr[a] = arr[a] ^ arr[b];
		arr[b] = arr[a] ^ arr[b];
		arr[a] = arr[a] ^ arr[b];
	}

	/**
	 * 获取key 第一次出现的位置 -1 表示数组中不存在
	 * 
	 * @param arr
	 * @param key
	 * @return
	 */
	public static int getIndex(int[] arr, int key) {
		for (int x = 0; x < arr.length; x++) {
			if (arr[x] == key)
				return x;
		}
		return -1;// 没有找到

	}

	/**
	 * 折半查找 必须保证数据中的元素是有序的 折半查找方式1,提高效率,但是必须要保证该数组是有序的数组
	 * 
	 * @param arr
	 * @param key
	 * @return
	 */
	public static int halfSearch(int[] arr, int key) {
		int min = 0;
		int max = arr.length - 1;
		int mid = (max + min) / 2;

		while (arr[mid] != key) {
			if (key > arr[mid])
				min = mid + 1;
			else if (key < arr[mid])
				max = mid - 1;

			if (min > max)
				return -1;
			mid = (max + min) / 2;
		}
		return mid;
	}

	/**
	 * 折半查找 2 折半查找方式可以用于插入 数据
	 */
	public static int halfSearch_2(int[] arr, int key) {
		int min = 0, max = arr.length, mid;

		while (min <= max) {
			mid = (min + max) >> 1;
			if (key > arr[mid])
				min = mid + 1;
			else if (key < arr[mid])
				max = mid - 1;
			else
				return mid;
		}
		return -1;

	}

	/**
	 * 各种进制的转换
	 * 
	 * @param num
	 * @param base
	 *            与上的基数
	 * @param offset
	 *            偏移量
	 * @return
	 */
	private static String trans(int num, int base, int offset) {
		char[] chs = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',
				'B', 'C', 'D', 'E', 'F' };
		if (num == 0)
			return "0";
		StringBuffer sb = new StringBuffer();
		while (num != 0) {
			int temp = num & base;
			sb.append(chs[temp]);
			num = num >>> offset;
		}
		return sb.reverse().toString();
	}

	/**
	 * 十进制 -->二进制
	 * 
	 * @param num
	 * @return
	 */
	public static String toBinary(int num) {
		return trans(num, 1, 1);
	}

	/**
	 * 十进制 -->八进制
	 * 
	 * @param num
	 *            十进制数
	 * @return
	 */
	public static String toEight(int num) {
		return trans(num, 7, 3);
	}

	/**
	 * 十进制 -->十六进制
	 * 
	 * @param num
	 * @return
	 */
	public static String toHex(int num) {
		return trans(num, 15, 4);
	}

}




静态代码快

//格式
static{


}
//特点 
//随着类的加载而执行,只执行一次,用于给类进行初始化的.

class StaticCode{
   static{
     System.out.println("a");
   }

   public static void  show(){
    System.out.println("show run");
  }
}

//例子
class StaticCodeDemo{

     static {
      System.out.println("b");
    }

   public static void main(String[] args){
    
     new  StaticCode();
     new  StaticCode();
     System.out.println("over");  
  }
  
   static {
     System.out.println("c");
    }


}

//输出 为  b c  a  over 


//例子2


class StaticCode{
   int num=0;
  //构造代码块
   {
      System.out.println("e"+this.num);
   }
   //构造方法
    StaticCode(){}
  //构造方法
    StaticCode(int x){
      this.num=9
     System.out.println(this.num);
    }
   //静态代码块 
   static{
      System.out.println("a");
   }

}

class StaticCodeDemo{

     static {
      System.out.println("b");
    }

   public static void main(String[] args){
    
      StaticCode s=null;//    
  }
  
   static {
     System.out.println("c");
    }


}
//只会输出   bc

class StaticCodeDemo{

     static {
      System.out.println("b");
    }

   public static void main(String[] args){
    
       StaticCode  s=new StaticCode();
  }
  
   static {
     System.out.println("c");
    }


}


//输出  b c a  e0 9


//静态代码 和 构造代码块的区别

静态代码: 只有 程序应用到类的数据的时候 ,即 只要类被加载到内存中个 静态代码就会被执行 
构造代码快:主要是在 创建对象的时候  首先被调用 优先于构造函数.



练习


class Fu{
	static{  //静态代码块    只要该类被JVM 加载到内存 就会运行这个 里面的内容 
		System.out.println("fu static run");
	}
	{  //构造代码块  在所有 构造函数前都会运行 ,除非不用构造函数 
		System.out.println("fu gouzao run");
	}
  Fu(){
	  System.out.println("fu run");
  }
  Fu(int x){  //如果不调用该类中的这个构造方法 就不会被运行
	  System.out.println("fu run"+x);
  }
}
class Zi extends Fu{
	static{
		System.out.println("zi static run");
		
	}
	{
		System.out.println("zi gouzao run");
	}
	Zi(){
		//super(); 默认都有  这行
		System.out.println("zi run");
	}
	Zi(int x){
		//super(); 默认都有  这行
		System.out.println("zi run"+x);
	}
	
}
public class day7_T1 {
	public static void main(String[] args) {
			Zi z=new Zi(4);
			
			/*
			fu static run
			zi static run
			fu gouzao run
			fu run
			zi gouzao run
			zi run4
			*/
	}
}



this 和super 的使用

class Person{
	String name;  //默认为0  
	
	 //Perseon(){} 显示写出 默认构造函数 
	
	Person(String name){  //发现 我们没有写 那个默认的构造函数 
		this.name=name;
		System.out.println("fu run"+this.name);
	}
}

class Student extends Person{
	
	Student(){
		super("xx");  //如果没有写父类默认构造函数 ,只能调用 其他构造函数
		System.out.println("zi run");
	}
	
	Student(String name){
		this();  //调用子类自己的  默认构造函数 由于 上面的构造函数 中调用 super("xx") 所以这句话可以了
		//super();  // 发现 写了this()后 这句报错了, 因为  super 要在第一行 
		//this();  //发现 先写 super后 在写 this() 也不行    因为  构造函数中 只能调用一次 父类构造方法 ,而且 super要放在第一行 ,所以这两个不能同时出现
		System.out.println("zi run" +this.name); //如果不调用父类的构造函数 我们就拿不到这个值了.
	}
	
}

public class day7_T2 {
	public static void main(String[] args) {
		Student stu=new Student("aa");
	}

}



//对象的初始化过程

class Person{
 private String name="haha";
 pirvate int age;
 
 Person(){}
 
 Person(String name,int age){
  this.name=name;
  this.age=age;
 }

 {
   this.name="xixi";
   this.age="10";
  }
 

 public static void main(String [] args){

  Person p=new Person(); 

/***这句话做了什么事情

1. 因为 new 用到了Persion.class 所以会先找到Person.class 文件并加载到内存中

2.执行该类中的static  代码快,  如果有的话,给Person.class类进行初始化 

3.在栈内存中 分配存储空间 个p,在堆内存中开辟空间,分配内存地址.

4.然后再在堆内存中建立对象,特有的属性, 并进行默认的初始化

5.然后对属性进行 显示初始化 

6.然后对对象进行构造代码快初始化 

7.对对象进行对应构造函数初始化 

8.将内存地址值复制给栈内存中的变量  p

 */

}
}



对象调用成员的过程

package com.itheima.day6;

public class Person {

	private static String country = "cn";

	private String name;
	private int age;
	
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	private void speak(){
		System.out.println(this.name+"...."+this.age);
	}

	public static void showCountry(){
		System.out.println("country="+country);
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		Person p = new Person("xixi",10);
		p.setName("lisi");  //运行有  栈内存的变量会被释放
		
		Person p1 = new Person("xixi",10);
		p1.setName("hah");
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}

}





单例设计模式 GOF (Gang of Four)四人帮

java23种设计模式
//设计模式:解决某一类问题最行之有效的方法

//单例设计模式: 解决一个类在内存中只存在一个对象.

/**
1.为了避免其他程序过多的创建该类对象,先禁止其他程序建立该类对象

2.为了让其他程序可以访问到该类对象,只好 在本类中,自定义一个对象 给其他程序使用,自己控制要创建的对象个数

3.为了方便其他程序使用自定义的该类对象, 可以对外提供一些访问方式

//程序代码的实现

1.将构造函数苏私有化

2. 在类中创建一个本类的对象

3.提供 一个方法可以获取到该对象.

4.该类的一些属性 该怎么样描述的还是 同样的要描述

*/

//类被加载 就初始化了

//称为  :饿汉式  (立即加载) 这个安全点 
class Single{


  private int age;
  private void  setAge(int age){
     this.age=age;
  }
  pirvate int getAge(){
     return  this.age;
  }

  private Single(){}   //私有化后 其他程序就不能创建对象了

  private static Single s=new Single();  //由于 getInstance 中只能使用static 的成员 ,所以只能是  static的了. 由于不能被外界访问 所以只能是 private

 public static Single getInstance(){   //由于 不能创建对象  所有只能是 static  ,由于要被外界访问  所以采用 public 修饰
   return s;
 }

}

class SingleDemo{

  public static void main(String [] args){
     Single s1=Single.getInstance();
      s1.setAge(13);
    Single s2=Single.getInstance();

    System.out.println(s2.getAge);  //13

      
 
  }
}




//单例的第二种方式


//称为 ; 懒汉式  (延迟加载) 效率低
class Single{


  private int age;
  private void  setAge(int age){
     this.age=age;
  }
  pirvate int getAge(){
     return  this.age;
  }

  private Single(){}   //私有化后 其他程序就不能创建对象了

  private static Single s=null;  //由于 getInstance 中只能使用static 的成员 ,所以只能是  static的了. 由于不能被外界访问 所以只能是 private

//注意两个 地方 synchronized 不是同时出现的
 public static /*synchronized*/ Single getInstance(){   //由于 不能创建对象  所有只能是 static  ,由于要被外界访问  所以采用 public 修饰
     if(s==null){
              
           synchronized(Single.class){
              if(s==null)
                s=new Single();
           }
      }
     return s;
 }

}

class SingleDemo{

  public static void main(String [] args){
     Single s1=Single.getInstance();
      s1.setAge(13);
    Single s2=Single.getInstance();

    System.out.println(s2.getAge);  //13

      
 
  }
}

// 只有调用 getInstance 方法后 才被延迟加载.
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值