`
Luob.
  • 浏览: 1589884 次
  • 来自: 上海
社区版块
存档分类
最新评论

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

阅读更多
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 方法后 才被延迟加载.
14
2
分享到:
评论

相关推荐

    Java实现多种单例模式

    在Java编程中,单例模式是一种常用的软件设计模式,它保证一个类只有一个实例,并提供一个全局访问点。这种模式在需要频繁创建和销毁对象的场景中尤其有用,因为它可以节省系统资源并确保对象间的协调一致。以下是...

    设计模式-单例模式

    **设计模式——单例模式** 单例模式是一种广泛应用于软件设计中的创建型设计模式...总的来说,单例模式的应用旨在提高代码的可维护性和资源利用率,但也要注意避免滥用,以免造成设计复杂度增加和代码难以测试的问题。

    连接数据库单例模式

    综上所述,通过使用单例模式来管理数据库连接不仅能够有效地提高程序的性能,还能简化开发过程中的复杂度,使得代码更加简洁和易于维护。在实际项目开发中,根据具体需求灵活运用单例模式是十分必要的。

    单例模式的七种写法

    单例模式是软件设计模式中的一种经典模式,用于确保一个类只有一个实例,并提供一个全局访问点。这种模式在很多场景下都非常有用,比如控制数据库连接、管理缓存或者全局配置等。下面我们将详细探讨单例模式的七种...

    单例模式(Singleton)的6种实现

    它通过减少同步代码块的范围,只在instance为null时才同步,这样既解决了多线程问题,又提高了性能。 4. 静态内部类(Initialization on Demand Holder) 静态内部类实现单例模式的方式是利用了类的加载机制来保证...

    单例模式讲解案例

    在Java、C#、Python等面向对象编程语言中,实现单例模式有多种方法。以下是一些常见的实现方式: 1. 饿汉式(静态常量):这是最简单的单例实现方式,它在类加载时就完成了初始化,所以是线程安全的。 ```java ...

    单例模式的几种实现方式demo

    单例模式是软件设计模式中的一种,它的主要目的是确保一个类只有一个实例,并提供一个全局访问点。这种模式在很多场景下都非常有用,比如控制数据库连接、缓存管理、线程池等。下面我们将深入探讨单例模式的几种实现...

    单例模式应用DEMO SHOW

    单例模式是软件设计模式中的一种,它保证一个类只有一个实例,并提供全局访问点。这种模式在许多场景下非常有用,比如配置管理、线程池、数据库连接等,因为这些情况通常只需要一个对象来处理所有的请求,以节省系统...

    单例模式学习笔记

    在Java或其他面向对象语言中,单例模式的实现有多种方式。 1. 饿汉式(静态常量): 这是最简单的单例实现方式,它在类加载时就完成了初始化,所以类加载比较慢,但获取单例的速度快,且线程安全。 ```java ...

    几种单例模式

    单例模式是软件设计模式中的一种,它的主要目的是确保一个类只有一个实例,并提供一个全局访问点。这种模式在很多场景下都非常有用,比如控制服务的唯一性、避免资源浪费等。接下来,我们将深入探讨几种常见的单例...

    设计模式 之 “单例模式[Singleton Pattern]”

    **单例模式(Singleton Pattern)**是软件设计模式中的一种基础模式,它的核心思想是确保一个类只有一个实例,并提供一个全局访问点。这种模式在很多场景下非常有用,比如配置管理、线程池、数据库连接池等,这些都...

    单例模式与接口.rar

    在"demo6"这个示例文件中,可能包含了一个或多个类,演示了如何将单例模式与接口结合使用。你可以通过解压文件,查看代码来进一步学习和理解这两种概念在实际项目中的应用。通过实践,你将更深入地了解它们如何帮助...

    深入理解JavaScript系列(25):设计模式之单例模式详解

    单例模式是软件开发中一种非常重要的设计模式,它确保一个类只有一个实例,并提供一个全局访问点。在JavaScript这样的动态语言中,单例模式的实现方式很多样,而且可以非常灵活。下面,我们就来深入探讨单例模式在...

    设计模式 For iOS-02-单例模式

    总之,单例模式是iOS开发中常见的设计模式之一,它能够提供一种优雅的方式来管理和访问全局唯一的对象实例。无论是通过传统的非ARC方法,还是现代的ARC+GCD方式,实现单例模式都需要仔细考虑其线程安全性和生命周期...

    第五讲:单例模式

    单例模式是软件设计模式中的一种,它的主要目的是确保一个类只有一个实例,并提供一个全局访问点。这种模式在很多场景下都非常有用,比如控制数据库连接、日志系统或者配置管理等,因为这些都需要一个全局共享的对象...

    单例模式

    单例模式是软件设计模式中的一种,它的主要目的是确保一个类只有一个实例,并提供一个全局访问点。这种模式在很多场景下都非常有用,比如控制资源的共享、管理配置对象或者创建昂贵的对象时,以减少系统开销。 单例...

    java代码-考试内容1-单例模式

    在压缩包文件中,`main.java`很可能是实现单例模式的源代码,而`README.txt`可能是对代码的解释或使用说明。查看这两个文件的具体内容可以帮助我们更深入地理解这个单例模式的实现方式和应用场景。

    java视频 static关键字

    类级别的初始化代码可以放在`static`块中,确保在类加载时执行,且只执行一次。这常用于初始化`static`变量或执行一次性设置任务。 ```java public class MyClass { static int count; static { count = 100; ...

    c#单例模式(Singleton)的6种实现

    在C#中,实现单例模式有多种方式,下面将详细介绍6种常见的实现方法: 1. **线程不安全版本**: 这是最简单的实现,但不适用于多线程环境。代码中,`_instance` 变量在未初始化时返回 `null`,当访问 `Instance` ...

Global site tag (gtag.js) - Google Analytics