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

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
分享到:
评论

相关推荐

    单例模式(讲解单例模式)

    6.单例模式6.单例模式6.单例模式6.单例模式6.单例模式6.单例模式6.单例模式6.单例模式6.单例模式式6.单例模式

    单例模式详解.pdf

    1、掌握单例模式的应用场景。 2、掌握 IDEA 环境下的多线程调试方式。 3、掌握保证线程安全的单例模式策略。 4、掌握反射暴力攻击单例解决方案及原理分析。...5、序列化破坏单例的原理及...6、掌握常见的单例模式写法。

    Qt qml Singleton 单例模式

    此示例展示了Qml 的单例模式(类似全局对象,只生成一次实例,可全局使用) surfsky.cnblogs.com

    java-单例模式几种写法

    自己总结的6中单例模式的写法,也有测试类,可以试验下,自己稍微修改一下后,验证安全性,纯粹为学习,建议可提

    java设计模式,单例模式学习示例源码,创建单例,配置文件读取

    java设计模式,单例模式学习示例源码,创建单例,配置文件读取

    【JavaScript源代码】JS实现单例模式的6种方案汇总.docx

     今天在复习设计模式中的-创建型模式,发现JS实现单例模式的方案有很多种,稍加总结了一下,列出了如下的6种方式与大家分享 大体上将内容分为了ES5(Function)与ES6(Class)实现两种部分 单例模式就是在系统中...

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

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

    这可能是最全的单例模式了

    设计模式之——单例模式单例的几种实现1. 懒汉单例模式2. synchronized 修饰的懒汉单例模式3. 双重检查锁定的单例模式4. 静态内部类实现单例模式5. 饿汉实现单例模式6. 饿汉变种实现单例模式7. 枚举实现单例模式...

    01 设计模式之单例模式.pdf

    2021年全面详细介绍6种方式实现单例模式,Java语言实现。

    单例模式.zip(c#设计模式)

    本压缩包含有两个demo,分别对应&lt;设计模式&gt;第2版,刘伟这本书,单例模式这一章课后习题6、7,如果问题请留言一起探讨,谢谢!

    Java面试 java设计模式整理 单例、工厂、策略等 面试使用,学习使用

    java的设计模式大体上分为三大类: 2 设计模式遵循的原则有6个: 2 1. 工厂模式(Factory Method) 2 2. 抽象工厂模式(Abstract Factory) 3 3. 单例模式(Singleton) 4 4.建造者模式(Builder) 4 5. 原型模式...

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

    1.1.1 摘要 ...单例模式(Singleton)是几个创建模式中最对立的一个,它的主要特点不是根据用户程序调用生成一个新的实例,而是控制某个类型的实例唯一性,通过上图我们知道它包含的角色只有一个,

    Java 经典设计模式讲解以及项目实战

    Java 经典设计模式讲解以及项目实战 设计模式简介:主要介绍各种设计模式的概念和运用场景等 设计模式综合运用:主要是笔者在实际工作中运用到的一些设计模式综合运用事例的提炼 Spring设计模式简介:主要是讲述...

    angular 服务的单例模式(依赖注入模式下)详解

    单例模式就不要说了,懂点设计模式的都懂得,真有不明白的自行百度。 (解释下angular的命名,angular就是angular2+,angular1叫angularjs,至于angular2,3,4,5,6只是angular的版本,通称angular,希望小伙伴...

    深入浅出java设计模式(高清中文PDF)

    文件类型为PDF文件,此文档对20多种java设计模式进行了详细讲解,在中文讲解的过程中还附有代码示例给学习者进行参考,使学习者通过实践更容易理解设计模式的原理。 本文档目录: 1.工厂模式 2.单例模式 3.建造...

    Java:单例模式的七种写法

    第一种(懒汉,线程不安全): 1 public class Singleton { 2 private static Singleton instance; 3 private Singleton ... 6 instance = new Singleton(); 7 } 8 return instance;

    设计模式源代码--工厂模式与单例

    设计模式源代码--工厂模式与单例。 代码是本人在学习设计模式时,所写的例子。 适合设计模式的初学者看。

    java设计模式

    22.4.1 Java世界中的观察者模式 22.4.2 项目中真实观察者模式 22.4.3 订阅发布模型 22.5 最佳实践 第23章 门面模式 23.1 我要投递信件 23.2 门面模式的定义 23.3 门面模式的应用 23.3.1 门面模式的优点 23.3.2 门面...

Global site tag (gtag.js) - Google Analytics