JAVASE重点汇总

javase重点汇总

你是什么,你有什么用,怎么使用

1.名词解释
JVM(Java Virtual Machine):java虚拟机,用于支持java程序的运行。
JRE(Java Runtime Environment):java运行时环境 JVM 和java的核心类库(J2SE ),要想运行一个java程序,只需要安装公共JRE就行了。
JDK(Java Development Kit): JAVA的开发工具。包含了java的开发工具(javac.exe,java.exe,jar.exe)和JRE。
JDK=JRE+JAVA开发工具
JRE=JVM+JAVA核心类库(J2SE )


2.java8大基本类型排行
boolean(1位)< byte(8位) < char(16位) < short(16位) < Int(32位) < long(64位) < float(32位) < double(64位)


3.构造函数
1.跟类名一致
2.没有返回类型
3.对象初始化被调用
4.如果不写构造函数,默认又一个没有参数的构造函数


4.static关键字
static的作用
为了实现对象之间重复属性的数据共享以及行为的共享
static的使用范围
可以使用修饰在方法上(共享行为)。
可以修饰在属性上(共享属性)。
static的使用限制
1:静态函数中不能访问非静态成员变量,只能访问静态变量(静态方法开始的时候已经被加载了,所以没法使用非静态的属性。
非静态的属性是根据new对象后才动态分配的)。
2:静态方法不可以定义this,super关键字(因为对象没有被new出来所以不知道此this是哪个this).
3:非静态函数中可以访问静态变量(因为静态变量公用的)


5.final关键字
final 最终的
可以修饰的: 类 函数 属性
修饰的属性就是常量,常量不可以改变(大部分情况都会搭配static关键字)
修饰的成员变量 必须给与初始化赋值,如果没有初始化也要在 对象创建对象之前对其初始化赋值
修饰的局部变量 常量
修饰的函数函数 不可以被重写
修饰的类不可以被继承


6.java 包机制
1、把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用。
2、如同文件夹一样,包也采用了树形目录的存储方式。同一个包中的类名字是不同的,不同的包中的类的名字是可以相同的,当同时调用两个不同包中相同类名的类时,应该加上包名加以区别。因此,包可以避免名字冲突。
3、包也限定了访问权限,拥有包访问权限的类才能访问某个包中的类。


静态方法不能被重写

==与object的equals判断内存地址,string的equals判断的是内容,因为string已经重写了equals

在导入的包的类里面有一个同类名,那第二个类的导入则需要全路径


java.lang底下的包不需要导入


冒泡排序

for (int j = 0; j < a.length - 1; j++) {
	for (int i = 0; i < a.length - j - 1; i++) {
		if (a[i] > a[i + 1]) {
			int temp = a[i];
			a[i] = a[i + 1];
			a[i + 1] = temp;
		}
	}
}

二分查找

// 上限 中值 下限
int min, mid, max;
min = 0;
max = tmp.length - 1;
mid =( min + max) / 2;
while (tmp[mid] != search) {
	if (tmp[mid] < search) {
		min = mid + 1;
	} else if (tmp[mid] > search) {
		max = mid - 1;
	}
	mid = ( min + max) / 2;
}	

单例设计模式

饿汉式

public class Test3 {
	//	2在类中创建一个私有的本类对象  创建这个类要保证能被共享,能够被其他类使用
	private static  Test3 test = new Test3();
	// 1将构造函数私有化 构造函数 因为实例化会调用这个构造函数来进行初始化
	private Test3() {
}

//3提供一个用类名调用的公有方法获取该对象。
public static Test3 getTest3() {
	//保险,预防空指针报错
	if(test == null) {
		 test = new Test3();
	}
	return test;
}
}

懒汉式

public class Test3 {
	//	2在类中创建一个私有的本类对象  创建这个类要保证能被共享,能够被其他类使用
	private static  Test3 test = null;
	// 1将构造函数私有化 构造函数 因为实例化会调用这个构造函数来进行初始化
	private Test3() {
}
//3提供一个用类名调用的公有方法获取该对象。
public static synchronized Test3 getTest3() {
	//保险,预防空指针报错
	if(test == null) {
		 test = new Test3();
	}
	return test;
}
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QHxDUQWo-15735565904JAVASE重点汇总_第1张图片75)(E:\JKPS\FILE\快速算法.jpg)]


访问权限 本类 同包 子类 其他包
public Yes Yes Yes Yes
protected Yes Yes Yes No
default(缺省) Yes Yes No No
private Yes No No No

只有静态的变量才可以用对象名.变量-调用

抽象方法只能在抽象类或者接口里面出现,抽象方法必须被重写,所以不能被static,final以及private修饰

JDK1.8之前

有方法都是抽象方法,默认使用abstract以及public修饰(使用implements实现)

接口里面有的都是常量,并且没有构造器,接口可以继承接口并且可以多继承,

JDK1.8后

interface可以有default修饰的方法,然后允许他有方法体,他也可以不被重写

也可以被static修饰,但是不会被继承,也不会被重写,只能通过接口名调用,只能自己用


**instanceof 关键字:**是一个比较运算符,用于判断一个对象是否是属于指定类的对象.

使用: 对象 instanceof 类

补充

一个编译单元(java文件)可以存在多个类,在编译时产生多个不同的.class文件,.class文件便是程序运行的数据来源。java将public类作为每个编译单元的数据接口,只能有一个,不然不能处理存在多个类的java文件。当一个编译单元(java文件)有多个非public类时,运行时需要对数据来源进行选择


抽象类
1.abstract声明的
2.抽象方法只有声明没有实现
3.抽象类不能实例化对象,如:Parent p = new Parent();//编译报错 只能通过子类取实例化
4.抽象类中可以没有抽象方法
5.抽象类中也可以有普通成员(成员变量、成员函数、代码块)除了可以有抽象方法外,其他都是一毛一样

抽象方法
1.抽象方法用abstract声明的
2.抽象方法没有方法体
3.一定会被子类重写

接口:
如果一个抽象类里面的函数都是抽象函数 、那么这个类就是接口
interface 来定义一个接口 注意:不要写class
abstract可以省略

  1. 在interface中定义的变量必须给与初始值, 定义的变量相当于 static final int age = 10;
  2. 接口中的所有方法都是public修饰的,所以在实现类中实现的方法必须要用public修饰,否则编译出错
  3. 接口可以继承接口
  4. jdk8 的新特性 在类中可以声明一个default的函数
interface Test{
default void aaa(){			
		}			
	}

细节
不能有构造函数
不能有普通变量
只能是静态常量
所有方法都是public的,而且是抽象方法,不能是static修饰
可以继承多个接口

10.接口和抽象类的区别
抽象类可以有构造函数,接口不可以有构造函数
抽象类中可以有普通成员变量,接口中没有普通成员变量,只能有常量
抽象类中的方法可以被static修饰,接口中的方法不可以被static修饰
抽象类中可以有普通方法和抽象方法,接口中的方法全是抽象方法
抽象中的方法可以被public,protected等修饰符修饰,接口中的方法全都是public abstract的方法,如果省略修饰符,则默认的也都是public abstract修饰
一个类只能继承一个抽象类,接口可以被多实现,即一个类只能继承一个类,可以实现多个接口


**String类:**一个自定义类型,而且不可变的;

**StringBuffer类:**可变的;


**内部类:**定义在类里面的类,外部类不能访问内部类,内部类可以访问外部类


**包装类:**一些自定义类型的类,如:

原始类型:booleancharbyteshortintlongfloatdouble
包装类型:Boolean,Character,Byte,Short,Integer,Long,Float,Double

Interger在常量池里面的取值范围为(-128–127)


**Math类:**里面封装着许多与数学相关的方法

使用:

//不用新建对象,直接Math.方法;
Math.round()
随机数
Math.ceil()
向上取整
Math,floot()
向下取整

**BigDecimal类:**当你用有限的容量装无限的数的时候回出现精度丢失(如10/3.0);—基本类型;但是BigDecimal就不会出现这样的问题,他是专门用来计算商业数字的类;

使用:

public BigDecimal add(BigDecimal augend):加        
public BigDecimal subtract(BigDecimal subtrahend):减        
public BigDecimal multiply(BigDecimal multiplicand):乘        
public BigDecimal divide(BigDecimal divisor):除        
public BigDecimal divide(BigDecimal divisor,int scale, int roundingMode):商,几位小数,舍取模式


}
 
    /**
     * 精确加法
     */
    public static double add(double value1, double value2) {
        BigDecimal b1 = BigDecimal.valueOf(value1);
        BigDecimal b2 = BigDecimal.valueOf(value2);
        return b1.add(b2).doubleValue();
    }
 
    /**
     * 精确减法
     */
    public static double sub(double value1, double value2) {
        BigDecimal b1 = BigDecimal.valueOf(value1);
        BigDecimal b2 = BigDecimal.valueOf(value2);
        return b1.subtract(b2).doubleValue();
    }
 
    /**
     * 精确乘法
     */
    public static double mul(double value1, double value2) {
        BigDecimal b1 = BigDecimal.valueOf(value1);
        BigDecimal b2 = BigDecimal.valueOf(value2);
        return b1.multiply(b2).doubleValue();
    }
 
    /**
     * 精确除法 使用默认精度
     */
    public static double div(double value1, double value2) throws IllegalAccessException {
        return div(value1, value2, DEF_DIV_SCALE);
    }
 
    /**
     * 精确除法
     * @param scale 精度
     */
    public static double div(double value1, double value2, int scale) throws IllegalAccessException {
        if(scale < 0) {
            throw new IllegalAccessException("精确度不能小于0");
        }
        BigDecimal b1 = BigDecimal.valueOf(value1);
        BigDecimal b2 = BigDecimal.valueOf(value2);
        // return b1.divide(b2, scale).doubleValue();
        return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }
 
    /**
     * 四舍五入
     * @param scale 小数点后保留几位
     */
    public static double round(double v, int scale) throws IllegalAccessException {
        return div(v, 1, scale);
    }
 
    /**
     * 比较大小
     */
    public static boolean equalTo(BigDecimal b1, BigDecimal b2) {
        if(b1 == null || b2 == null) {
            return false;
        }
        return 0 == b1.compareTo(b2);
    }

解决随机数重复,定义一个标记,然后if判断,如果随机到标记就跳出本次循环(参考斗地主发牌)


**面向对象三大特征:**封装,继承,多态

**继承(extends)*就像人类的父子关系一样,儿子会继承父亲的所有(非private的)东西,当然,儿子也可以有自己的新特点,比如可以重写父亲的方法等等,只能继承一个父类;


**日期类:**是java中用于获取或者设置时间的类,一般可以作为,日期的国际化,日期和时间之间的转换,日期的加减运算,日期的展示格式等;

**Date类:**代表一个特定的瞬间,以毫秒为单位(1000毫秒=1秒)

使用:

eDate date =new Date();
date.方法;

拓展:System.currentTimeMillis() 获取当前时间的毫秒数,可以通过毫秒数进行时间比较,时间转化以及时间格式化等

**SimpleDateFormat类:**是简单的日期类,可以输出你相应的日期格式,含有特定的格式化编码,一般都会使用这个类来设置时间

**使用:**需要与Date类搭配使用

Date date1=new Date();
SimpleDateFormat s1=new SimpleDateFormat("yyyy年MM月dd日");//2019年08月15日

System.out.println(s1.format(date1));

**Calendar类:**也是一个日期类,不过比较老的类,不常用

使用:

Calendar cal1 = Calendar.getInstance();  
call.方法;

计算机时间从1970年1月1日0点0分0秒开始;中国在东八区,与之相差8个小时月是从0开始星期日也是


Da’y12,异常


**集合:**集合与数组都是一个容器,不同的是集合的长度是可变的,而数组的长度是固定的,而且数组中存储数据类型是单一的,集合中可以存储任意类型的对象。

Collection接口:集合只能保存对象以及自定义类型,不能保存基本类型,可以使用包装类,set, list , HashSet,ArrayList;

**集合运算:**交集,并集,补集,利用Collection接口提供的retainAll方法来实现

Collection和Collections的区别,Collection是集合的父类,而Collections是集合工具类

**List集合:**他是有序可重复的;ArrayList: 数组实现, 查找快, 增删慢,**LinkedList *链表实现, 增删快, 查找慢

使用:

List<String> list1 = new ArrayList<String>();
list1.方法
List<String> lis2 = new LinkedList <String>();
list2.方法

三种遍历的方法:

 //遍历方式  增强的for循环
		for (String string : list) {
			System.out.println(string);
		}
		//索引的方式 因为是数组的方式存储方式,所以索引从0开始
		for (int i = 0; i < list.size(); i++) {
			System.out.println(list.get(i));
		}
		//利用迭代器的方法
		Iterator<String> it = list.iterator();
		while(it.hasNext()) {
			System.out.println(it.next());
		}

**Set集合:**无序不可重复的,查找慢增删快;HashSet 内容无序 不可重复 支持null;TreeSet 内按字典序 不可重复 不支持null;LinkedHashSet 带存储顺序 不可重复

使用:

Set set =new HashSet();
set.方法;

**Map集合:**是一个以键值对的形式存储数值,键唯一,值不唯一;对于map集合遍历的时候,先要得到键的set集合,然后对set集合遍历,再得到相应的值

Map: 键值对 (key,value) key的特点是无序的,不可以重复的,通过唯一的key拿到唯一的value。

HashMap非线程安全,高效,key无序 key支持null 

TreeMap key按按字典序 key不支持null 

HashTable 线程安全,低效,key支持null 

LinkedHashMap

性能 : HashMap  > TreeMap > LinkedHashMap > HashTable

使用:

   Map map =new HashMap();
   map.方法  


//键找值方式:即通过元素中的键,获取键所对应的值
//1.增强的for循环(entry集合)  
    for(Entry<Integer, String> entry:map.entrySet()){  
        System.out.println(entry);  
    }  
    //2.增强的for循环(key集合)  
    for(Integer key:map.keySet()){  
        System.out.println(key+" = "+map.get(key));  
    }  
    //3.遍历值的集合  
    for(String value:map.values()){  
        System.out.println(value);  
    }  

**File类:**Java里面的一个文件类,用于操作文件的读写,一般配合IO流使用

使用:

File file =new File();
file.方法;

IO流:

**1.字节流(8位)*IO流里面,以一个字节一个字节传输读写的一个流,他是一个万能的流,可以读写所有的数据,比如文本,音频,视频.图片;

使用步骤:

输入流
读文件
1:打开流(即创建流)
2:通过流读取内容
3:用完后,关闭流资源

输出流
写文件
1:打开文件输出流,流的目的地是指定的文件
2:通过流向文件写数据
3: 刷新缓冲区域
4: 用完流后关闭流

InputStream in = new FileInputStream(new File("路径"));
OutputStream out =new FileOutputStream(new File("路径"));

2.字符流(16位):IO流里面,只能用于操作操作纯文字的文件,但是速度比字节流快(FileReader、FileWriter),使用方法与字节流一样

**3.缓冲流:**增加读写速度,(BufferedInputStream ,BufferedOutputStream)

**使用:**一般与字节流,字符流搭配使用

 BufferedReader a1=new BufferedReader(new FileReader("路径"));
        BufferedWriter a2=new BufferedWriter(new FileWriter("路径"));

对象流:将对象序列化成一个流,然后写在文件里面,用于保存对象

序列化就是把对象转为方便传输的格式(字符串格式),反序列化就是把序列化的字符串转为对象

**Serializable接口:**要实现对象流就必须实现这个接口,可以理解为一个工具;

**serialVersionUID:**版本号,在对象流序列化的时候,系统会判断两个程序的序列号是否一致,要一致才可以实现序列化;

对象序列化:

1.声明类实现了Serializable接口。是一个标示器,没有要实现的方法。

2.新建对象。

3.新建字节流对象(FileOutputStream)进序列化对象保存在本地文件中。如果没有该文件,利用输入流

4.新建ObjectOutputStream对象,调用writeObject方法序列对象。

5.writeObject方法会执行两个工作:序列化对象,然后将序列化的对象写入文件中。

6.异常处理和流的关闭动作要执行。

对象流之ObjectOutputStream对象序列化

    ObjectOutputStream可以将对象进行序列化的输出流。

示例代码如下:

//ObjectOutputStreamDemo类代码
  public class ObjectOutputStreamDemo{
 /*
  * void writeObject()
  * 将特定的对象转化为字节序列
  */
  @Test
  public void testOOS() throws Exception{
      FileOutputStream fos = new FileOutputStream("boy.obj");
      //构造方法ObjectOutputSteam(OutputStream out)
      ObjectOutputStream oos = new ObjectOutputStream(fos);
      Person boy = new Person("Peter",12,"男");
      oos.writeObject(boy);
      System.out.println("完成序列化");
      oos.close();
  }
}    




//Java对象类代码
public class Person implements Serializable {
     private static final long serialVersionUID = 1L;
     private String name;
     private int age;
     private String gender;

     public Person() {
         super();
     }

     public Person(String name, int age, String gender) {
         super();
         this.name = name;
         this.age = age;
         this.gender = gender;
     }

     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;
     }

     public String getGender() {
         return gender;
     }

     public void setGender(String gender) {
         this.gender = gender;
     }

     @Override
     public String toString() {
         return "name=" + name + ", age=" + age + ", gender=" + gender ;
     }
}

RandomAccessFile类,一个可以读写一体的类,而且可以随意访问文件的位置,主要用于多线程下载,用于在文章任意的位置添加或删减内容:

使用:

RandomAccessFile  AccessFile = new  =RandomAccessFile("文件位置","操作权限(r,rw,rws,rwd))"
                                                      AccessFile.方法;

Properties为属性文件,是用来写配置文件的

  1. 是Hashtable的子类 ,是一个特殊的建值对。保存的地方是文件

  2. key 与 value 都是String类型

使用:

Properties  ps = new Properties();
pps.load(new FileInputStream("配置文件的名字.properties"));
ps.方法;

Integer.parseInt(“String”):String转int


Java线程有两种创建方式,第一是继承Thread接口,第二种是实现Runnable接口

继承Thread类
1.继承Thread类
2.重写run方法(线程在执行的时候就是在执行线程类中的run方法中的代码)
3.创建线程对象
4.调用start 方法

一个任务一个线程就用这个Thread

实现Runnable接口

  1. 实现Runnable接口
  2. 重写run方法
  3. 创建线程对象(Thread),并且传入Runnable对象
    再通线程对象调用start方法,

一个任务多个线程并行处理就用这个Runnable

synchronized修饰方法:代表同一时刻只能一个线程进来

synchronized(对象){}代码块:锁住的对象只能有一个线程进来,而且这个对象必须是所有线程共有的

**死锁:**有A与B,有两个线程,两个线程都要获得AB才可以完成任务,现在,线程一获得了A,线程二获得了B,而线程一要去获得B,但是B已经被线程二获得了,所有他只能等待线程二释放B,但是线程二要同时获得AB才可以释放资源,而线程二也一样,所以大家就造成了死锁.

死锁不能解决,只能避免

避免方式:

1.线程互斥:synhronized修饰在同一个类的两个或者以上的方法都会出现互斥现象

2.线程同步,互斥的基础上的,使得线程有先后顺序

wait()–等待和notify()–唤醒是成对出现的:他们都不属于Tthread类,而是属于Object类的


Socket:用于TCP客户端

ServerSocket:服务端

TCP Socket开发步骤
服务端
// 1.创建一个ServerSocket对象
// 2.调用accept()方法接受客户端请求(建立连接)
// 3.获取socket对象的输入输出流
// 4.读取客户端传过来的数据
// 5.关闭流
// 6.关闭连接
客户端
// 1.创建一个Socket对象(相当于建立了连接)
// 2.获取输出流
// 3.输出内容
// 4.关闭流
// 5.断开连接


UDP Socket开发步骤
服务端
// 1.创建DatagramSocket对象,并且声明端口
// 2.创建接受包
// 3.通过socket调用receive等待包内容
// 4.接收到包后解释包内容
// 5.关闭DatagramSocket

客户端
// 1.创建DatagramSocket对象,并且声明端口(客户端端口可以省略,对于客户端不关注端口)
// 2.把发送的内容封装到DatagramPacket并且把服务端的IP以及端口带上
// 3.发送DatagramPacket
// 4.关闭DatagramSocket

服务端代码

public class SocketSever {
public static void main(String[] args) {
	try {
		// 1.创建一个ServerSocket对象 传入连接端口
		ServerSocket serverSocket = new ServerSocket(5500);
		System.out.println("服务端启动,等待连接......");
		/*
		 * 2.调用ServerSocket对象的accept()方法接受客户端请求(建立连接)得到一个Socket对象——第一次握手接收方
		 * 因为这里的服务端在等待客户端的连接,所以线程会阻塞,直到有客户端和这边连接为止,会一直等待下去
		 */
		Socket socket = serverSocket.accept();
		System.out.println("与客户端连接成功...");
		/*
		 * 3.获取Socket对象的输入输出流
		 * 因为这边预定会穿字符串,所以可是使用InputStreamReader将字节流转为字符流
		 * 再利用BufferedReader这个缓冲流
		 * */
		BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		PrintWriter pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
		
		/*
		 * 4.读取客户端传过来的数据读取
		 * readLine 方法直接将客户端传输过来的数字转为字符串,打印结果
		 * */
		String content = br.readLine();
		System.out.println("服务器接收到:"+content);
		//5.关闭流
		br.close();
		//6.关闭连接
		socket.close();
		
	} catch (IOException e) {
		e.printStackTrace();
	}
}
 }

客户端
// 1.创建DatagramSocket对象,并且声明端口(客户端端口可以省略,对于客户端不关注端口)
// 2.把发送的内容封装到DatagramPacket并且把服务端的IP以及端口带上
// 3.发送DatagramPacket
// 4.关闭DatagramSocket

public class SocketClient {
	public static void main(String[] args) {
		try {
			System.out.println("客户端准备连接服务端......");
			/*
			 * 1.创建一个Socket对象,传入想要连接的ip地址和端口 相当于建立了连接,也就是说三次握手在执行完这个步骤的就完成了
			 */
			Socket socket = new Socket("127.0.0.1", 5500);
			System.out.println("与服务端完成连接");
			// 2.通过Socket对象获取输出流,因为打算传字符串,所以还是转为字符流
			OutputStreamWriter writer = new OutputStreamWriter(socket.getOutputStream());
			// 使用缓冲流
			BufferedWriter bufferedWriter = new BufferedWriter(writer);
			// 3.输出内容
			bufferedWriter.write("我是客户端.");
			// 4.关闭流
			bufferedWriter.flush();// 记得刷新
			bufferedWriter.close();
			// 5.断开连接
			socket.close();
	} catch (IOException e) {
		e.printStackTrace();
	}
}
}

链接网络,两台电脑之间的通信,非常重要,面试有可能会要手写代码

**线程池(4种)*将若干个线程装在集合里,且线程可循环利用


XML解释

1,DOM解析

2,SAX解析

SAX的全称是Simple APIs for XML,也即XML简单应用程序接口。与DOM不同,SAX提供的访问模式是一种顺序模式,这是一种快速读写XML数据的方式。当使用SAX分析器对XML文档进行分析时,会触发一系列事件,并激活相应的事件处理函数,应用程序通过这些事件处理函数实现对XML文档的访问,因而SAX接口也被称作事件驱动接口。

优点:
      1、采用事件驱动模式,对内存耗费比较小。
      2、适用于只处理XML文件中的数据时。
    缺点:
      1、编码比较麻烦。
      2、很难同时访问XML文件中的多处不同数据。


**可变长参数(本质是一个数组,默认非null)*参数不一定,用三个逗号表现,且在调用的时候可以不传参也可以传任意个参数(无数);当时可变长参数一定要声明在最后,否则识别不了 ,而且String … args 只能有一个:

method(String a ,String ... args);正确
method1(String ... args ,String a);错误

**反射:**能够动态的获取一个类的的所有属性和方法以及构造函数,他可以在运行的时候构造任意一个类的对象,调用对象的方法以及属性,获取他所具有的所有成员变量和方法

使用:通过Class类获取对象

有三种方式:

1.通过类名获取      类名.class    
2.通过对象获取      对象名.getClass()
3.通过全类名获取    Class.forName(全类名)

**DEBUG:**利用eclipse等编程工具的debug功能寻找程序的bug


**泛型:**可以理解为一种自定义类型,普遍用于集合中.

**使用:**1.自定义泛型类.

​ 自定义泛型类的声明,是在类名后面加上 ;在类体中只能对这个 泛型进行声明,不能实现或赋值, 而且在静态成员中 都不可以使用泛型

​ 2.泛型方法

​ 方法上面也可以声明泛型,静态方法也可以泛型方法也可以定义多个

​ 3.泛型的上限与下限

  • - 限定通配符的上边界:
      extends 
        正确:Vector<? extends Number> x = new Vector<Integer>();
        错误:Vector<? extends Number> x = new Vector<String>();
    
      上边界只能获取不能添加。
    
    - 限定通配符的下边界
      super
      接收Integer 或者Integer的父类型
      正确:Vector<? super Integer> x = new Vector<Number>();
      错误:Vector<? super Integer> x = new Vector<Byte>();
    
      下边界只能添加,不能获取
    

**枚举:**可以理解为一种指定义类型的变量,在用enum修饰的类中声明

特性
	1.枚举是1个特殊类
	2.枚举默认修饰符是  public static final ;
	3.枚举值是所属类的类型
	4.构造方法 都是私有的
	5.枚举可以实现抽象的方法,但是枚举值也要实现该方法
	6.枚举的值必须要放在枚举类的第一行、
常用方法

**注解:**以@开头的字符串,例如@Overload,用于标识方法,(注解一般要配合反射一起使用),你还可以自定义注解(有四种注解@Retention、@Target、@Document、@Inherited):

public @interface  MyAnnotion{
}

Log4j:日志文件

你可能感兴趣的:(javase)