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("\n 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);
    }
}