一个demo学会java


全栈工程师开发手册 (作者:栾鹏)

快捷链接:
java开发大全

这篇demo较长,包含了java基本的内容,若不是出于校验自己java基础能力的朋友,建议按照上面的链接分章节学习。本demo包含了java的数组、对象、对象属性、接口,面向对象,重载,多态、封装、字符串、正则表达式、函数、参数、容器、算法、线程、异常等方面的知识,可以全面检验你的java学习效果。

此demo包括文件:测试文件index.java和接口interface1.java、接口interface2.java、基类Student.java、派生类Monitor.java文件

Student.java实现了一个java基类

//static int var=10;  															//java禁止使用全局数据
//一个包可以包含多个类,类默认访问修饰符为包访问,每个文件只能有一个public类,类只能是包访问或public
public class Student implements Comparable<Student>{  							//implements继承接口关键字,Comparable<Student>类比较接口
	public static void main(String[] args) {}  									//每个类中都可以有一个main函数,用于调试
	
	public Student(){															//不接受任何参数的叫默认构造器,没定义构造器,编译器会自动创建
		this("student",12); 													//通过this仅能调用一个构造器,必须将构造器调用置于起始处
		getname(); 																//构造器会调用成员函数和数据,所有在初始化构造器前会初始化成员数据
		printf("基类无参构造器"); 												
	}
	public Student(String name,int age){										//有参构造器
		this.age = age;this.name = name;
		printf("基类有参构造器"+name);
	}
	public Student(String name,Character...args){								//可变参数列表args是一个参数数组,重载方法中应只有一个可变参数列表,编译器
		this.name = name;
		printf("基类变参构造器"); 												   //args[0]表示变参中的第一个参数
	}
	public void setname(String name){this.name=name;printf("基类设置名称:"+name);} //this表示对当前对象的引用
	public String getname(){printf("基类获取名称"+name);return name;} 			//使用public方法实现对private数据的控制,保证类内数据安全
	void setage(int age){printf("基类设置名称"+age);this.age=age;}
	private int getage(){return age;} 											//private属于final方法
	
	static long time=10;  														//所有类型数据均可在定义时初始化,数据均有默认值,所有类的静态数据最先初始化
	private int age=0; 															//private外部不可以访问
	String name = "student";  													//不加访问修饰符,默认为包访问
	
	public enum allsex{man,woman}  												//枚举类型,等价于类内组合class allsex{man,woman},枚举类型可以有构造函数,有几个枚举实例就调用几次构造函数
	class Sextype{ 																//内部类,在内部类声明为static时为嵌套类,嵌套类不属于对象,而属于类名
		public void setsex(allsex sextype){										//枚举类型,可作为变量,相当于const
			printf("设置内部类性别");
			switch (sextype) {  												//枚举类型用在switch中,用于限制参数的可选项
			case man:sexstring="boy";break;  
			case woman:sexstring="girl";break;
			default:break;
			}
		}
		public Student getStudent(){
			sexstring+=name;  													//内部类,嵌套类可以任意访问外部类数据,无论嵌套多少层
			return Student.this;												//返回外部类引用,当内部类是static时,内部类不存在对外部类的引用
		}
		private String sexstring;
	}
	public static <T> void printf(T str)  										//泛型方法,
	{
		System.out.println(str.toString());					        		//System.out.println打印输出
	}
	
	
	//重写equals虚函数,java中除了static和final都是虚函数,(private属于final方法)
	public final boolean equals(Student another){   							//final标记的函数不能被派生类重写
		printf("比较了两个基类");
		if(this.age==another.age && this.name==another.name)
			return true;
		return false;
	}
	//垃圾回收器准备收回对象占用内存时执行,java虚拟机并未面临内存耗尽的情形不会浪费时间执行垃圾回收,(垃圾回收:停止-复制,标记-清扫)
	public void finalize(){
		printf("基类对象"+name+"内存被收回");
	}
	void dispose(){
		printf("基类对象"+name+"清理函数");
	}
	
	@Override
	public int compareTo(Student arg0){   										//要实现排序,必须要实现的比较接口
		return age<arg0.age?-1:(age==arg0.age?0:1);  							//返回-1表示小于,0不表示等于,1表示大于
	}

}





//一个文件可以包含多个类,但是文件名必须和public类名相同,否则只能使用默认的包访问权限
abstract class Teacher{  														//abstract关键字表示为抽象类
	abstract void setname();   													//abstract抽象方法
	public String getname(){return name;}  										//使用public方法实现对private数据的控制,保证类内数据安全
	String name="teacher";  													//不加修饰符默认为报访问
}

Interface1.java定义了一个接口

public interface Interface1{   													//interface接口声明,完全抽象类
	abstract void init1();   													//abstract抽象方法,接口自动是public的,接口中,不能定义函数体,只能声明,abstract可以不写
	class manclass implements Interface1{   									//接口内部类自动是public和static的。属于嵌套类,接口内部类实现接口函数,为了创建接口所有不同实现的公共代码
		@Override
		public void init1() {
			System.out.println("接口内部类,实现公共代码");
		}
		
	}
}

Interface2.java实现了一个派生接口

public interface Interface2<A> extends Interface1{   					//接口也支持继承,接口可以多继承,extends后可以有多个子接口,接口可以嵌套在类中<A>泛型接口
	abstract void init2(A name);   										//abstract抽象方法,接口自动是public的
	void init1();   													//接口重写了函数
	
	int DEFAULT_GAE =12;   												//接口中的任何域都是自动的static和final的,static final使用大写风格
	String DEFAULT_NAME ="name";  
	
}

Monitor.java文件实现了一个继承自Student,并继承自Interface1和Interface2的派生类

import java.util.EnumSet;


final class Monitor<T> extends Student implements Interface1,Interface2<String>{    //<>泛型,extends继承类,implements继承接口,final终态类,不能再被继承
	Monitor(){  																	//派生类无参构造器
		super("monitor");printf("派生类无参构造器");  								//关键字super显示调用基类构造器,printf调用基类函数
	}																				//构造前会调用父类无参构造函数,如果父类没有构造函数,则会默认生成。如果有构造函数(无参),则会调用无参构造函数。如果只有有参构造函数,必须显示调用
	Monitor(int age){printf("派生类有参构造器");} 									//派生类有参构造器,
	static Student mysStudent = new Student("monitor",12);  						//静态数据初始化只在调用时刻才会进行,在第一次创建类对象或者第一次访问静态数据时最先被初始化
	final static Student student1;  												//final用于,保持引用不变,对象可变
	static Student student2;
	static{   																		//静态块,仅执行一次,对象创建或静态数据访问时执行,仅定义对象的话不执行
		student1 = new Student();
		student2 = new Student();
		printf("派生类静态块执行");
	}
	//重写函数的返回类型可以是基类型的派生类型,访问权限必须大于原访问权限,子类抛出异常小于等于父类方法抛出异常
	public String getname(){  														//重写虚函数不需要关键字,因为在java中除了static和final都是虚函数(private属于final方法)
		printf("派生类获取名称:"+name);  												//
		//name = super.name+"的派生";  												//super代表基类
		return name;
	}
	public int getage(){return 11;}   												//private不能重写,派生类重名,覆盖了基类私有方法
	
	
	String name="monitor";  															//同名变量和静态函数,不能动态绑定到基类引用上,和基类数据存储在不同的区域
	String task ="帮助老师管理班级";  
	
	private T a;  																	//设置泛型,也可以使用原始基类Object
	public T getT(){return a;}   													//设置泛型函数,泛型会自动擦除传递过来的对象的类信息
	public void setT(T a){this.a=a;printf("派生类设置泛型变量");}
	
	public enum Group{   															//枚举类型,函数枚举
		SHUXUE{void action(){printf("数学");}},
		YINGYU{void action(){printf("英语");}},
		YUNWEN{void action(){printf("语文");}};
		abstract void action();   													//每个枚举元素要实现的函数
	}
	
	EnumSet<Group> allgroup=EnumSet.of(Group.SHUXUE,Group.YINGYU);  				//EnumSet枚举集合,EnumMap枚举映射
	public void printfgroup(){
		for(Group g:allgroup)
			g.action();
	}
	

	@Override
	public void init2(String name) {   												//泛型接口
		printf("派生类实现接口2初始化函数");
	}
	@Override
	public void init1() {
		printf("派生类实现接口1初始化函数,或接口2初始化函数");
	}

}


index.java文件实现了所有知识点的测试。

import java.io.ByteArrayInputStream;
import java.lang.reflect.Executable;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.SortedMap;
import java.util.Stack;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.prefs.Preferences;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.List;

import javax.naming.InitialContext;

public class index implements Runnable{  										//Runnable多线程,任务接口,如果类不是抽象类,必须实现接口函数,可以创建Thread的派生类,Callable<>有返回值的线程接口
	
	static String stringtemp;              										//类内共享变量
	public static void main(String[] args)
	{

		printf("===========基类相关操作==============");
		Preferences prefs=Preferences.userNodeForPackage(index.class);   		//Preferences只能存放基本类型和字符串的键值对
		prefs.put("default_name", "student");  									//Preferences用作属性配置
		prefs.putInt("default_age", 12);
		Student.time+=Student.time<<2+0x21^26;  								//静态数据,可以铜鼓类型访问,<<位左移动,低位补0,^按位异或,0X表示16进制
		Student student1=new Student(); 	 									//所有的对象都必须通过new来创建,基本数据类型可以定义创建
		student1.name = student1.name+1;   										//访问类内数据,字符串+重载
		student1.setage(-2*-6); 												//通过类内函数访问类数据,一元减号用于转变数据的符号
		Student.Sextype student1_sextype = student1.new Sextype(); 				//创建内部类,必须通过外部类变量new构造
		student1_sextype.setsex(Student.allsex.man);  							//调用枚举类型
		Student student2=student1;  											//仅是复制引用,两个变量名指向同一块内存
		if(student1==student2)  												//==和!=只是比较对象的引用,不比较对象内容
			if(student1.equals(student2))  										//对象的比较实用equals,比较对象的实际内容,但是定义类的equals默认行为还是比较引用,要在自定义类中重写equals函数
				//if(1)    														//非布尔值不能用在逻辑表达式中
				printf("创建了两个相同的类引用");
		
		Field[] fileds = student1.getClass().getDeclaredFields();				//反射获取对象类的属性
		try{             														//尝试运行代码
			for(Field field:fileds){
				if(!field.isAccessible())
					field.setAccessible(true);									//设置对象属性可读取
					Object obj=field.get(student2);  							//从实例对象中获取字段属性的值,(私有的没法获取,数值或对象统一为对象,没有值返回的)
			}
		}
		 catch (Exception e) {
			printf("错误内容:"+e.toString());  									//catch函数在try出错时调用,exception是所有异常类的基类,异常类可以捕获派生类异常
			e.printStackTrace(System.out);  									//堆轨迹,出错原因和位置
			//throw e;   														//抛出异常,停止运行
		}
		finally{  																//finally函数总要执行
			printf("finally函数总要执行");
		}
		
		


		
		printf("===========派生类相关操作==============");
		Monitor monitor1 =new Monitor(Interface2.DEFAULT_GAE);   					//基类构造函数(绑定后函数),派生类成员,派生类构造函数,接口中的域相当于枚举常量
		monitor1.name = "monitor1";													//基类静态-派生类静态-基类私有-基类构造-派生类私有-派生类构造。函数在构造前已经存在
		printf("===========11111111111111111==============");
		sprintf(monitor1,null);  													//可变参数,null为参数为空
		sprintf(monitor1);  														//传递实现接口的类,向上转型为接口,实现函数回调
		printf("===========2222222222222222==============");
		Student student3 = new Monitor();   									//基类引用,派生类对象
		student3.getname();   													//调用引用动态绑定的方法
		((Monitor)student3).getage();   										//向下转型成功,getage为派生类的公共函数
		
		
		printf("===========接口相关操作==============");
		Interface1 interface1=new Monitor();   									//向上转型,interface1是基类,普通类,接口,无所谓,实现接口的类(包括内部类),都可以向上转型转化为接口
		interface1.init1();   													//调用动态绑定的函数
		interface1=getInterface1();  											//通过匿名内部类实现接口函数的实现
		interface1.init1();
		
		
		printf("===========容器相关操作==============");
		//Collection接口,独立元素序列(List接口,Set接口,Queue接口)
		//List接口,插入顺序保存数组,(ArrayList数组,LinkedList链表)
		//Set接口,不能重复元素,(HashSet散列函数,TreeSet红黑树,LinkedHashList链表下的散列)
		//Queue接口,先进先出队列,(LinkedList链表,PriorityQueue优先级队列)
		
		//Map接口,键值对(字典,映射),HashMap(快速访问),TreeMap(键值排序),LinkedHashMap(保持元素插入顺序,通过散列提供快速访问)
		//list整体赋值,Arrays.asList方法返回的ArrayList是继承自AbstractList,不可变大小数组,作为参数生成可变大小的ArrayList
		List<String> allname = new ArrayList<String>(Arrays.asList("小明","小红","晓刚","小刘"));  //ArrayList实现向上转型为list接口,动态连续数组,<>内的对象类型可以不写,不能是基本,<>内类型擦除,编译器无法获取,
		allname.set(2,"小刚");  													//list元素赋值
		if(!allname.contains("小王"))   											//元素包含
			allname.add("小王");  												//添加元素
		allname.remove(0);  													//删除元素
		stringtemp=allname.get(1);  											//读取元素
		Iterator<String> iterator = allname.iterator();   						//集合的迭代器,next为首个元素的迭代器,ListIterator迭代器更厉害
		iterator.next();														//指向第一个元素
		iterator.remove();    													//删除迭代器的对应元素,删除可以继续使用此元素的迭代器了
		while(iterator.hasNext())												//迭代器是否有一下个元素
			printf(iterator.next());											//获取序列的下一个元素
		
		Stack<String> allname1 = new Stack<String>();   						//stack先进后出堆栈,各种队列和栈基于LinkedList链表实现
		LinkedList<String> allname2 = new LinkedList<String>();   				//双端队列,队列
		Set<String> allname3 = new HashSet<String>();  							//不重复集合
		Map<String,String> map = new HashMap<String,String>();					//或者是SortedMap
		map.put("小明", "12");
		Object x_name = map.get("小明");
		Iterator iterator1 = map.entrySet().iterator();   						//Map对象有keySet方法,返回key的Set集合,values()返回Collection集合,entrySet函数返回集合,元素类型为Map.Entry(一个<key,vlaue>的泛型接口)
		Map.Entry entry = (Map.Entry)iterator1.next();
		Object key=entry.getKey();
		Iterator iterator2 = map.keySet().iterator();
		key=iterator2.next();
		x_name=map.get(key);
		for(Map.Entry<String, String> entry2:map.entrySet()){
			entry2.getKey();
			entry2.getValue();
		}
		List<Map.Entry<String, String>> info_student= new ArrayList<Map.Entry<String,String>>(map.entrySet());
		

		
		
		
		
		
		printf("===========字符串相关操作==============");																
		StringBuilder sb = new StringBuilder();   							//StringBuilder包括insert,replace,substring,reverse,append,tostring,delete方法
		sb.append(String.format("这里%s字符串相关操作", "shi"));   			//string.format()格式化函数,内部创建formatter类设置字符串格式
		String outStr=sb.toString().replace("shi", "是");   					//string是不可变量,取值变化是生成新的类,replace替换,repalceAll,replaceFirst
		outStr=outStr.substring(3)+outStr.length();   						//substring取子字符串,length字符串长度,+重载连接字符串和整型
		if(outStr.indexOf("shi")<0)  										//indexof插叙子字符串所在位置,不存在返回-1,其他字符串相关操作较多
			printf("字符串\""+outStr+"\"不存在指定子字符串");
		outStr = "luanpeng luanpeng";
		outStr=outStr.split(" ")[0];   										//split分割字符串,返回数组,读取第一个数组赋值给outstr
		Pattern pattern = Pattern.compile("lu[a-n]");   					//创建正则法则,将正则字符串编译成正则表达式
		Matcher matcher = pattern.matcher(outStr);   						//创建匹配器
		while (matcher.find())   											//依次查询是否存在匹配项
			printf(matcher.group()+"起点"+matcher.start()+"终点"+matcher.end());//group匹配值,start起始位置,end结束位置
		matcher.reset("luan");												//将正则法则重新使用到新的字符串上
		
		Integer nn= Integer.parseInt("123");								//字符串转化为整型
		String str = String.valueOf(nn);									//整型转化为字符串
		char[] temparr ={'a','b'};											//字符数组
		str=new String(temparr);											//字符数组转化为字符串
		temparr = str.toCharArray();										//字符串转化为字符数组
		byte[] temp1=str.getBytes();										//字符串转化为字节数组
		
		StringBuffer buf=new StringBuffer(); 								//字符串的StringBuffer表示,
		buf.append(str+"\r\n");												//StringBuffer可以追加
		buf.deleteCharAt(buf.length()-1);									//StringBuffer与StringBuilder有很多类似功能,这里不一一列举
			

		
		
		printf("===========数组相关操作==============");
		Random random =new Random(17);  										//随机数
		int farrat[] =new int[10];   											//数组创建int var[] 和int[] var等效
		for(int x:farrat){   													//for语句的遍历形式
			x=random.nextInt();  												//读取伪随机序列
		}
		Student[] all1 = new Student[7];  
		Student[] all2 = new Student[10]; 
		Arrays.fill(all1, student1);    										//数组填充,填充对象时,只是填充了引用
		Arrays.fill(all2, student3);
		System.arraycopy(all1, 0, all2, 2, all1.length);   						//ii第0个开始复制到jj第2个开始,长度ii.length
		Arrays.sort(all2);  													//调用重写的比较函数执行数组排序
		int location = Arrays.binarySearch(all2, student1);   					//在数组中查找,不存在返回-1
		if(!Arrays.equals(all1, all2))    										//数组相等   个数和每个元素均相等
			printf(Arrays.toString(all2));  
		
		Monitor<Student> monitor2 = new Monitor<Student>();   						//包含泛型的类型调用,也可以不使用泛型创建对象
		monitor2.setT(student1);
		
		
		//注解
		//数据流
		//序列化
		printf("===========线程相关操作==============");
		new index().run();   													//在主线程中调用线程类中的run函数,不是多线程,只是调用函数
		Thread thread=new Thread(new index());   								//调用子函数,执行线程类中run函数,thread构造参数为runnable接口,线程类向上转型为接口
		thread.setDaemon(true);   												//设置线程为后台线程,否则为非后台线程
		thread.start();   														//线程启动,thread.join()等待线程执行完毕
		thread.interrupt();  													//线程中断,会在线程运行至阻塞时中断,弹出中断异常
		ExecutorService exec= Executors.newCachedThreadPool();  				//创建线程池管理器
		exec.execute(new index());  											//向线程管理器中添加一个线程实现接口,自动执行
		exec.submit(new index());   											//调用有返回的线程
		exec.shutdown();   														//关闭线程管理器,线程池继续运行
		
		synchronized (stringtemp) {   											//对象锁控制同步块,需要锁才能进入
			try {
				printf("进入同步块,释放对象锁");									//对象释放锁,进入等待锁定池,当接收到对象notify、notifyAll后进入对象锁定池,准备重新获取对象继续执行
				stringtemp.wait();     											//wait,会抛出异常,synchronized 的目标与 wait() 方法的物件不相同,会有 IllegalMonitorStateException
				printf("同步控制块恢复继续执行");									//java里面有专门捕获异常的try catch。异常是向上依次抛出的,如果在某一层被捕获就不会退出。如果一直没有被捕获直到抛出到系统层就是退出。
			} catch (InterruptedException e) {   								//中断异常类,会在线程运行至阻塞时中断,弹出中断异常
				e.printStackTrace();
			}
		}

		
		
		printf("结束");
		printf(Student.allsex.woman);
		
		
	}

	
	public static void sprintf(Student student,Object[] args)  					//基类参数允许传递派生类引用,//Object[] args用于可变参数列表,可以无参调用
	{
		student.setname("student1");   											//调用引用动态绑定的方法-基类函数,修改的是基类属性
		student.getname();  													//调用引用动态绑定的方法-派生类重写的虚函数,获取的是派生类属性
	}
	public static void sprintf(Interface1 interface1)   						//接口参数允许传递接口类为参数,sprintf函数名相同实现重载
	{
		if(interface1 instanceof Monitor){   									//判断引用的类型是否是指定类型
			Student student=(Student)interface1;  								//先向下转型为monitor,在向上转型为student
			printf("接口类型:"+interface1.getClass().getName());   				//获取引用指向的对象类型
			student.getname();  												//调用动态绑定的方法
		}
		interface1.init1();   													//接口相当于纯抽象类,调用动态绑定的方法	
	}
	
	
	
	public static Interface1 getInterface1() {    								//不用创建实现接口的类,而直接实现接口的方法的定义
		return new Interface1(){    											//匿名内部类,可以传递参数
			public void init1(){
				System.out.println("通过匿名内部类实现向上转型为接口");
			}
		};
	}
	
	
	public static synchronized <T> void printf(T str)  							//泛型方法,synchronized同步函数,检查锁,获取锁,执行代码,释放锁
	{
		System.out.println(str.toString());
	}
	
	int num=0;
	@Override   																//多线程,任务接口,只有调用线程接口才会执行
	public void run(){   														//线程接口重载函数
		Thread.currentThread().setPriority(++num);     							//设置线程优先级,优先级不会导致死锁,优先级低的执行频率低
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");		//设置日期格式
		printf(df.format(new Date())+"执行了线程"+num); 							// new Date()为获取当前系统时间
		Lock lock = new ReentrantLock();   										//创建线程锁
		lock.lock();       														//锁定资源
		try {
			Thread.yield();   													//线程让步,不释放锁,yield不能设置时间,只能控制同优先级
			Thread.sleep(1000);            										//sleep可以使低优先级的线程得到执行的机会,线程睡眠,不释放锁,保持监控,自动恢复,sleep不操作锁,所以可以在非同步控制方法(块)中调用
		} catch (Exception e) {
			printf(df.format(new Date())+"线程错误"+e.toString());
		}
		finally{
			lock.unlock();     													//释放锁
			printf(df.format(new Date())+"释放锁"); 					
			synchronized (stringtemp) {   										//对象锁控制同步块,需要锁才能进入
				stringtemp.notifyAll();   										//stringtemp调用线程恢复通知所有等待线程,wait、notify、notifyAll必须在同步控制方法(块)中调用 											
			}
		}
		
	}
	
}


  • 11
    点赞
  • 63
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

腾讯AI架构师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值