• Java 总结


    Java 总结

    第一部分:知识复习要点

    1. Java技术体系分成哪三大部分?JAVAEE(企业级计算)、JAVASE(桌面级计算)、JAVAME(移动计算)

    2. JDK中:

      • 用于编译Java源程序的命令是:javac 源程序名.java
      • 用于运行Java程序的命令是, java 程序名
      • 键盘标准输入流的对应的对象是:System.in 对象
      • 屏幕标准输出流对应的对象是:System.out对象
    3. PATH环境变量的作用?

      环境变量主要作用是找到程序的安装路径。我们用windows的命令行执行命令的时候,是需要到相应程序的安装路径下面去执行的。

    4. JAVA中各个基本数据类型的大小(即在内存中占用的字节数。如:int 大小是4个字节等... )

      image-20200620171107921

    5. 如何定义一个全局型的常量?

      //定义全局型的一个PI常量。
      public static final double PI=3.14159d;
      
    6. JAVA中汉字的范围(用于判别汉字):U4e00-U9fa5

    7. 定义一个类,用于表达:二维坐标平面上面的点。或定义一个类,用于表达:复数?或定义一个类,用于表达表达:圆?能写出代码。

    8. 能简述 static 数据成员 与非static 数据成员的区别、用法。

      静态变量和实例变量的区别如下:

      • 静态变量在内存中占用一份拷贝,运行时Java虚拟机只为静态变量分配一次内存,在加载类的过程中完成静态变量的内存空间分配。可以直接通过类名访问静态变量。

      • 对于实例变量,每创建一个实例,就会为实例变量分配一次内存。实例变量可以在内存中有多份拷贝,互不影响。

      静态方法:

      • 在静态方法里只能直接访问类中其他的静态成员(包括变量和方法),而不能直接访问类中的非静态成员。这是因为,对于非静态的方法和变量,需要先创建类的实例后才可使用。而非静态方法属于对象的具体实例,只有在类的对象创建时在对象的内存中才有这个方法的代码段。

      • 静态方法不能以任何方式引用this和super关键字。因为静态方法在使用前是不需要创建任何对象的,当静态方法被调用时,this所引用的对象根本就没有产生。

      • 子类只能继承、重载、隐藏父类的静态方法,子类不能重写父类的静态方法,也不能把父类不是静态的方法重写成静态的方法。

    9. 能简述:四种访问控制符(publuc 、protected、缺省、private)各自的含义。

      image-20200620173144780

    10. 能定义一个抽象类。能写出代码片断。

    11. 能定义一个接口。能写出代码片断。

    12. 外部类、内部类的概念及相应知识点。能据此知识点:阅读程序,写出运行结果。

    13. 类和对象的初始化顺序方面相应知识点(含:对象初始化块、类初始化块)。能据此知识点:阅读程序,写出运行结果。

      所有类的初始化块(父类的类的初始化块 --> 子类的类的初始化块) --->> 所有对象的初始化块-->构造器

    14. try-catch-finally语句的语句。

    15. throws子句与throw语句的含义与区别

      • throw语句是抛出一个异常。throws语句是方法可能抛出异常的声明。(用在声明方法时,表示该方法可能要抛出异常)

      • throws出现在方法函数头;而throw出现在函数体。

      • throws表示出现异常的一种可能性,并不一定会发生这些异常;throw则是抛出了异常,执行throw则一定抛出了某种异常。

    16. try-catch-finally语句中包含return语句时的处理。能据此知识点:阅读程序,写出运行结果。

    17. 根据你的理解:回答JAVA中的继承机制。

      继承机制主要具有双重作用:一是作为类的构造机制,二是作为类型的构造机制。

      作为类的构造机制,继承通过扩充、组合现有的类来构造新的类。扩充是指形成现有类的特例——派生类,组合是指抽取出若干现有类的共性形成新的抽象层次——基类。
      作为类型的构造机制,如果子类继承父类,则所有要求对象为父类类型的地方也可以接受子类类型的对象。也就是说父类对象出现的地方可以用子类对象替代。也就是里氏替换原则。

      • 子类拥有父类非private的属性,方法。
      • 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
      • 子类可以用自己的方式实现父类的方法(重定义)。
      • java的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如A类继承B类,B类继承C类,所以按照关系就是C类是B类的父类,B类是A类的父类,这
      • java继承区别于C++继承的一个特性。但接口允许多继承。
      • 提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系)。
    18. 理解JAVA中继承、方法重载、方法重写、方法隐藏的知识点,能据此知识点:阅读程序,写出运行结果。

      隐藏和覆盖的区别:

        被隐藏的属性,在子类被强制转换成父类后,访问的是父类中的属性

        被覆盖的方法,在子类被强制转换成父类后,调用的还是子类自身的方法

        因为覆盖是动态绑定,是受RTTI(run time type identification,运行时类型检查)约束的,隐藏不受RTTI约束,总结为RTTI只针对覆盖,不针对隐藏

      区别 覆盖 重载
      实现 子类对父类方法的重写 同一个类中建立多个同名方法
      参数 与父类同名同参 与别的方法同名不同参
      返回 子类与父类返回类型要一致
      权限 子类不能覆盖父类的private方法
      父类一个方法只能在子类覆盖一次 重载只要参数不同,可以多次
      覆盖是针对父类方法的重写 同类中的方法均可重载
      重写要求父类鼻子类抛出更少的异常

    第二部分:示例代码

    输出字符'啊'的UNICODE码值

    public static void main(String[] args) {
    	System.out.println("字符'啊'的UNICODE码值:"+(int)'啊');	
    }
    //21834
    

    对给定的年份如: int year=1986;输出是不是一个闰年。

    public static void main(String[] args) {
    	// TODO Auto-generated method stub
    	int year=1986;
    	boolean isLeap=false;
        isLeap  = (year % 400 == 0)||(year % 4 == 0 && year % 100 != 0);
        System.out.println("1986年="+isLeap);
    }
    

    给定四个字节b1,b2,b3,b4,拼接成一个int 整数值,其中:b1在最左边,b4在最右边,按b1b2b3b4次序拼接。

    byte b1 = (byte)(0xaa), b2 = (byte)(0xbb), b3 = (byte)(0xcc), b4 = (byte))0xdd;
    int i = b1 << 24 | (b2 << 16) & 0x00ff0000 | (b3 << 8) & 0x0000ff00 | b4 & 0x000000ff;
    

    定义一个类,表达:二维 坐标平面上的点:

    public class Point {
    	private int x,y;
    
    	public Point(int x, int y) {
    		this.x = x;
    		this.y = y;
    	}
    
        public Point(int x) {
            this(x,0);
        }
    
        public Point() {
            this(0);
        }
        //此处可添加其它所需要的方法
        //.......
    
        @Override
        public String toString() {
            // TODO Auto-generated method stub
            return "("+this.x+","+this.y+")";
        }
    
    }
    

    类与对象的初始化块、初始化次序相关知识点。

    自定义异常。

    public class KBException extends IOException{
        String str;
    	MyException1(String _str) {
    		this.str = _str;
    	}
    	public String toString() {
    		sout(str);
    	}
    }
    
    public class KBPress{
        public static int read() throws KBException{
            //throws是声明异常。
            int ch;
            try{
                ch = System.in.read();
                if(ch == 'A'){
                    throw new KBException ("A键已坏");
                }
            }
            catch(IOException e){
                throw new KBException(e.getMessage());
                //throw是抛出异常。
            }
            return ch;
        }
    }
    
    public class Client{
        public static String[] main(String[] args){
            int ch;
            try{
    	        while((ch = KBPress.read()) != -1){
        	        sout("" + ch);
        	    }
            }catch(KBException e){
                sout("" + e.getMessage());
            }
        }
    }
    

    try与return 语句 下列方法运行的结果是:

    int f(int x){
    	try {
    		if(x>0) throw new Exception("x>0");
    		return 1;
    	}catch(Exception e) {
    		return 2;
    	}finally {
    		return 3;
    	}
     
    }
     /*
    问:f(-1)时方法的返回值是多少?
    f(1)时方法的返回值又是多少?
    答:都是3
    */
    

    抽象类:设计一个类,能对任何 的几何图形求面积.

    //表达:任何几何图形--抽象概念  -->抽象类!
    public abstract class Graphix {
    	public abstract double area();  //抽象方法!方法体不需要写!(无法写出!) 
    }
    //定义一个通用的工具类:完成对任何几何图形求面积:
    public class Tools {
    	public static double calArea(Graphix g) {
    		return g.area();
    	}
    	/**
    	* @param args
    	*/
    	public static void main(String[] args) {
    		Circle c=new Circle();
    		Tools.calArea(c);
    		Square s=new Square();
    		Tools.calArea(s);
    
    	}
    
    }
    
    public class Circle extends Graphix{
    	@Override
    	public double area() {
    		System.out.println("按圆面积公式求。");
    		return 0;
    	}
    }
    public class Square extends Graphix{
    	@Override
    	public double area() {
    		System.out.println("按正方形面积公式求。");
    		return 0;
    	}
    }
    

    输出前n个质数。

    public class PrintPrimes {
    	public static boolean isPrime(int n)
    	{
    		for(int i=2;i*i<=n;i++)
    		{
    			if(n % i ==0 ) return false;
    		}
    		return true;
    	}
    	//输出前n个质数
    	public static void printPrimes(int n)
    	{
    		int cc=0;
    		for(int i=2;cc<n;i++)
    		{
    			if(isPrime(i))
    			{
    				System.out.print(" "+i);
    				cc++;
    			}
    		}
    	}
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		
           printPrimes(20);     
    	}
    }
    
    

    递归方式求前n个数的和,

    public static int sum(int n)
    {
    	return (n==1)?1:sum(n-1)+n;
    }
    

    递归方式把一个数n逆序输出。如:参数是1234,则返回4321

    public static int reverse(int n)
    {
    	return reverse(0,n);
    }
    private static int reverse(int m,int n)
    {
    	return n==0?m:reverse(m*10+n%10,n/10);
    }
    

    使用ArrayList类,完成:将一个十进制安徽,转成二进制。

    public static void conv(int n)
    {
    	ArrayList<Integer>  al=new ArrayList<Integer>();
    	do {
    		al.add(n%2);
    		n /= 2;
    	} while (n!=0);
    	for(int i=al.size()-1;i>=0;i--)
    	{
    		System.out.print(""+al.get(i));
    	}
    }
    

    使用HashMap类,完成:汉字串中每一个汉字出现的次数。

    public static void count(String s)
    {
    	if(s==null) return;
    	HashMap<Character, Integer> map=new HashMap<Character, Integer>();
    	for(int i=0;i<s.length();i++)
    	{
    		char c=s.charAt(i);
    		Integer freq=map.get(c);
    		map.put(c, (freq==null?1:freq+1));
    	}
    	System.out.println("统计结果:"+map);
    }
    

    字符串相等比较:

    public class TestStr {
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
            System.out.println("男".compareTo("女"));
            String s1="Hello";
            String s2="Hello";
            String s3=new String("Hello");
            String s4=new String("Hello");
            System.out.println("s1==s2?"+(s1==s2));
            System.out.println("s3==s4?"+(s3==s4));
            System.out.println("s1==s3?"+(s1==s3));
    
            System.out.println("s1.equals(s2)?"+s1.equals(s2));
            System.out.println("s3.equals(s4)?"+s3.equals(s4));
            System.out.println("s1.equals(s3)?"+s1.equals(s3));
            //结构分析初步!
            System.out.println("Abtest.txt".startsWith("Ab"));
            System.out.println("Abtest.txt".endsWith(".txt"));
    	}
    }
    

    将"aaaabbbbccccccdd";压缩成:"abcd"; 核心代码片断如下:

    String s="aaaabbbbccccccdd";
    System.out.println(s.replaceAll("(.)+\1", "$1"));
    

    字符串拆分:copy c:/a.txt d:/bb.txt

    String s="copy    c:/a.txt     d:/bb.txt";
    //起分隔作用的字符串是:空格串,即:\s+
    String[] ss=s.split("\s+");
    for(String e:ss)
    {
    	System.out.println(es);
    }
    

    对字符串中"ABD237&&9309jf898icdm4390"中数值求和。

    //方法一: 使用split()方法。
    //代码片断:
    String s="ABD237&&*9309jf898icdm4390";
    //这分隔作用的是:非数字,即:[^0-9]+
    String[] ss=s.split("[^0-9]+");
    int sum=0;
    for(String e:ss)
    {
    	if(e.trim().length()>0)
    	{
    		int v=Integer.parseInt(e);//将整数值的串,变成整数值。
    		sum += v;
    	}
    }
    System.out.println("sum="+sum);
    
    //方法二:使用Pattern类
    Pattern p=Pattern.compile("\d+");
    Matcher m=p.matcher("ABD237&&*9309jf898icdm4390");
    int sum=0;
    while(m.find())
    {
    	String e=m.group();	 
      	int cv=Integer.parseInt(e);
      	sum += e;
    }
    System.out.println("sum="+sum);
    
    //方法三:使用Scanner类,最方便 
    Scanner sc=new Scanner("ABD237&&*9309jf898icdm4390");
    //重要:分隔作用的是:非数字串,即: [^\d]+
    sc.useDelimiter("[^\d]+");
    int sum=0;
    while(sc.hasNextInt())
    {
    	sum += sc.nextInt();
    }
    System.out.println("sum="+sum);
    

    模板串。

    public class Ex2 {
    	public static String process(String tmp, String ds){
    		String res="";
    		HashMap<String, String> map=new HashMap<String, String>();
    		String[] r_ds=ds.split(",");
    		for(String e:r_ds)
    		{
    			if(e.length()>0)
    			{
    				String[] r_e=e.split(":",2);
    				map.put(r_e[0],r_e[1]);
    			}
    		}//for
    		Pattern p=Pattern.compile("\$\{(.+?)\}");
    		Matcher m=p.matcher(tmp);
    		StringBuffer sb=new StringBuffer();
    		while(m.find())
    		{
    			m.appendReplacement(sb, map.get(m.group(1)));
    		}//while
    		m.appendTail(sb);
    		res=sb.toString();
    		return res;
    	}
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
            System.out.print("请输入模板串:");
            Scanner sc=new Scanner(System.in);
            String tmp=sc.nextLine();
            System.out.print("请输入数据源串:");
            String ds=sc.nextLine();
            String res=process(tmp,ds);
            System.out.println("处理结果:"+res);
    	}
    }
    

    分子量计算

    public class TestREG {
    	private static HashMap<String, Float>map=new HashMap<String, Float>();
    	static {
    		/*
    		C, H, O, N,原子量分别
    		为12.01, 1.008, 16.00, 14.01
    		(单位:g/mol)。		
    		*/
    		map.put("C",12.01f);
    		map.put("H",1.008f);
    		map.put("O",16.00f);
    		map.put("N",14.01f);
    		
    	}
    	public static float cal(String s)
    	{
    		float s_w=0;
    		Pattern  p=Pattern.compile("([CHON])(\d*)");
    		Matcher m=p.matcher(s);
    		while (m.find()) {
    			String k=m.group(1);
    			String n=m.group(2);
    			float w=map.get(k);
    			int num=1;
    			if(n.length()>0)
    			{
    				num=Integer.parseInt(n);
    			}
    			s_w += w*num;
    		}//while
    		return s_w;
    	}
    	
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
            System.out.print("请输入一个分子式:");
            Scanner sc=new Scanner(System.in);
            String s=sc.nextLine();
            if(s.matches("([CHON]\d*)+"))
            {
                float w=cal(s);
                System.out .println("分子式:"+s  +"分子量是:"+w+"g/mol");
            }
            else {
                System.out.println("分子式不对");
    		}
        }	
    }
    

    键盘上输入的任何内容,在屏幕上输出

    public class Exp1 {
    
    	public static void main(String[] args)
    	throws Exception
    	{
    		int ch;
    		while((ch=System.in.read())!=-1)
    		{
    			System.out.print(ch);
    		}//while
    		
    	}
    
    }
    

    键盘上输入的任何内容,写入到D:/data.dat中

    public class TestKB {
    
    	public static void  main(String[] args)
    	throws Exception
    	{
    		FileOutputStream fos=new FileOutputStream("D:/data.dat");
    		int ch;
            while((ch=System.in.read())!=-1)
            {
            	fos.write(ch);	
            }//while
    		fos.flush();
    		fos.close();
    	}
    }
    

    任何文件(字节文件)的复制

    public class TestFIIO {
    	public static void main(String[] args) 
    	throws Exception
    	{
    		FileInputStream fis=new FileInputStream("w:/1.jpg");
    		FileOutputStream fos=new FileOutputStream("d:/test.jpg");
    		int ch;
    		while((ch=fis.read())!=-1)
    		{
    			fos.write(ch);
    		}//while
    		fis.close();
    		fos.flush();
    		fos.close();
    	}
    }
    

    使用DataOutputStream类,完成:基于JAVA基本数据类型的写。

    public class TestDOS {
    	public static void main(String[] args)
    	throws Exception
    	{
    		DataOutputStream dos=new DataOutputStream(new FileOutputStream("d:/t.dat"));
    		dos.writeInt(10);
    		for(int i=1;i<=10;i++)
    		{
    			dos.writeInt(i*3);
    		}
    		dos.writeInt(5);
    		for(int i=1;i<=5;i++)
    		{
    			dos.writeDouble(i*3D);
    		}
    		dos.flush();
    		dos.close();
    	}
    }
    

    使用DataInputStream类,完成:基于JAVA基本数据类型的读。

    public class TestDio {
    	public static void main(String[] args)
    	throws Exception 
    	{
    		DataInputStream dis=new DataInputStream(new FileInputStream("d:/t.dat"));
    		int len=dis.readInt();
    		System.out.println("Len:"+len);
    		for(int i=1;i<=len;i++)
    		{
    			int v=dis.readInt();
    			System.out.print(" "+v);
    		}
            len=dis.readInt();
            System.out.println("
     Double Len:"+len);
            for(int i=1;i<=len;i++)
            {
            	double d=dis.readDouble();
            	System.out.print(" "+d);
            }
            dis.close();
    	}
    }
    

    使用DataInputStream类,完成:在不知道数值总数的情况下,基于JAVA基本数据类型的读。

    public class TestDio2 {
    	public static void main(String[] args) 
    	throws Exception
    	{
    	 	DataInputStream dis=new DataInputStream(new FileInputStream("d:/t1.dat"));
             try {
                 while(true)
                 {
                     int v=dis.readInt();
                     System.out.println(" "+v);
                 }
             }catch (EOFException e) {	}
    
             dis.close();
    	}
    }
    

    24,使用File类,输出D:/目录下所有的内容。

    File f=new File("d:/");
    String[] fs=f.list();
    for(String e:fs)
    {
    	System.out.println(""+e);	
    }
    
    

    25,使用File类,输出D:/目录下所有的文件名以.txt结尾的内容。

    File f=new File("d:/");
    //过滤器
    String[]  fs=f.list(
        new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                return name.endsWith(".txt");
            }
        }
    );
    System.out.println("==========");
    for(String e:fs)
    {
    	System.out.println(e);	
    }
    

    以文件行的方式(使用 Bufferedreader类),输出文本文件d:/test.txt中内容;

    BufferedReader br=new BufferedReader(new FileReader("d:/test.txt"));
    String line=null;
    while((line=br.readLine())!=null)
    {
    	System.out.println(line);
    }
    br.close();
    

    打开一个文本文件,输出其默认采用的编码。

    FileReader fr=new FileReader("d:/test.txt");		
    System.out.println("编码:"+fr.getEncoding());
    

    使用UTF-8编码,打开d:/test.txt文件,并输出其内容

    InputStreamReader isr=new InputStreamReader(new FileInputStream("d:/test.txt"),
    					"UTF-8");
    int ch1;
    while((ch1=isr.read())!=-1)
    {
    	System.out.print((char)ch1);	
    }
    isr.close();
    

    键盘上输入一行整数值,以 ,分隔。计算这些整数值的和。

    br=new BufferedReader(new InputStreamReader(System.in));
    System.out.println("请输入一行整数值,以,分隔:");
    line=br.readLine();
    System.out.println(""+line);
    String[] rs=line.split(",");
    int sum=0;
    for(String e:rs)
    {
    	if(e.trim().length()>0)
    	{
    		int v=Integer.parseInt(e.trim());
    		sum += v;
    	}
    }
    System.out.println("sum="+sum);		
    

    使用PrintWriter类,向文件 d:/99.txt中输出99乘法表

    public class P99 {
    
    	public static void main(String[] args) 
    	throws Exception
    	{
    		PrintWriter pw=new PrintWriter(new FileWriter("d:/99.txt"));
    		for(int i=1;i<=9;i++)
    		{
    			for(int j=1;j<=i;j++)
    			{
    				pw.print(" "+i+"*"+j+"="+(i*j));
    			}//for--j
    			pw.println();//换行
    		}//for--i
          pw.flush();
          pw.close();
    	}//main
    }
    /**
        运行结果:99.txt文件中内容:
        1*1=1
        2*1=2 2*2=4
        3*1=3 3*2=6 3*3=9
        4*1=4 4*2=8 4*3=12 4*4=16
        5*1=5 5*2=10 5*3=15 5*4=20 5*5=25
        6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36
        7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49
        8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64
        9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81
    **/
    

    综合设计部分:

    单例模式:只能创建一个实例

    public class Singleton {
      private Singleton(){
      	//.....
      }
      private static Singleton obj= new Singleton();
      public static Singleton getObj()
      {
      	return obj;
      }    
    }
    
    //饿汉式单例模式
    public class HungryMan {
    
        //可能会浪费空间
        private byte[] buffer1 = new byte[1024*1024];
        private byte[] buffer2 = new byte[1024*1024];
        private byte[] buffer3 = new byte[1024*1024];
        private byte[] buffer4 = new byte[1024*1024];
    
        private HungryMan() {
        }
    
        private final static HungryMan HUNGRY_MAN = new HungryMan();
    
        public static HungryMan getInstance(){
            return HUNGRY_MAN;
        }
    }
    
    package com.frans;
    
    import javafx.scene.control.Tab;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    
    //懒汉式单例模式
    public class LazyMan {
    
        //红绿灯
        private static boolean frans_fan = false;
    
        private LazyMan() {
            synchronized (LazyMan.class){
                if(frans_fan == false){
                    frans_fan = true;
                }else{
                    throw new RuntimeException("不要使用反射破坏单例");
                }
                /*
                if(lazyMan != null){
                    throw new RuntimeException("不要使用反射破坏单例");
                }*/
            }
            System.out.println(Thread.currentThread().getName() + "ok");
        }
    
        /**
         * Java并发编程
         * volatile关键字的两层语义
         *   一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:
         *
         *   1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。
         *
         *   2)禁止进行指令重排序。
         */
        private static volatile LazyMan lazyMan; //volatile防止指令重排。
    
        //双重检测锁模式的懒汉式单例,DCL单例
        public static LazyMan getInstance(){
            //加锁
            if(lazyMan == null){
                synchronized (LazyMan.class){
                    if(lazyMan == null){
                        lazyMan = new LazyMan();  //不是原子操作
                    }
                }
            }
    
            return lazyMan;
        }
    
        //反射可以破坏单例
        public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
    
            Field frans_fan = LazyMan.class.getDeclaredField("frans_fan");
            frans_fan.setAccessible(true);
    
    
            //LazyMan instance = LazyMan.getInstance();
            Constructor<LazyMan> declaredConstructor = LazyMan.class.getDeclaredConstructor(null);
            declaredConstructor.setAccessible(true);
            LazyMan lazyMan = declaredConstructor.newInstance();
    
            frans_fan.set(lazyMan, false);
    
            LazyMan lazyMan1 = declaredConstructor.newInstance();
    
            System.out.println(lazyMan);
            System.out.println(lazyMan1);
        }
    
        /*
        //多线程并发问题
        public static void main(String[] args) {
            for (int i = 0; i < 10; i++) {
                new Thread(() -> {
                    LazyMan.getInstance();
                }).start();
            }
        }*/
    }
    /**
     * 1. 分配内存空间
     * 2. 执行构造方法,初始化对象
     * 3. 把这个对象指向这个空间
     *
     * 默认执行顺序 123
     * 但是可能会出现 132 的执行顺序,此时lazyman还没有完成构造
     */
    
    
    package com.frans;
    //枚举
    import java.lang.reflect.Constructor;
    import java.lang.reflect.InvocationTargetException;
    
    public enum  SingletonEnum {
        INSTANCE;
    
        public SingletonEnum getInstance(){
            return INSTANCE;
        }
    }
    
    class Test{
        public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
            /*
            SingletonEnum instance = SingletonEnum.INSTANCE;
            SingletonEnum instance1 = SingletonEnum.INSTANCE;
    
            System.out.println(instance);
            System.out.println(instance1);
    
             */
    
            SingletonEnum instance = SingletonEnum.INSTANCE;
            Constructor<SingletonEnum> declaredConstructor = SingletonEnum.class.getDeclaredConstructor();
            declaredConstructor.setAccessible(true);
            SingletonEnum instance1 = declaredConstructor.newInstance();
            System.out.println(instance);
            System.out.println(instance1);
        }
    }
    
  • 相关阅读:
    依赖反转Ioc和unity,autofac,castle框架教程及比较
    webform非表单提交时防xss攻击
    tfs分支操作
    防火墙入站出站规则配置
    前端流程图jsplumb学习笔记
    Js闭包学习笔记
    word中加入endnote
    Rest概念学习
    DRF的版本、认证、权限
    博客园自动生成目录
  • 原文地址:https://www.cnblogs.com/fans-fan/p/13202965.html
Copyright © 2020-2023  润新知