易错点总结

本文深入解析Java中的static、final、abstract、多态等关键概念,详细解释内部类的使用方式,以及静态变量、final变量的特性。同时,探讨抽象类的构造函数需求,多态的变量引用限制,并对比comparable与comparator的使用场景。此外,文章还讲解了TreeSet的工作原理及List与Set的区别。
摘要由CSDN通过智能技术生成

1.static是成员修饰符,只能修饰成员位置的变量,方法或者是类,不能修饰局部的。

2.如果内部类不是静态的,不能再另一个类中用Outer.Inner.BB();的方法调用内部类,应该先在外部类中创建内部类的对象,然后在创建外部类的对象的方法调用这个内部类。
https://www.imooc.com/article/9867#

3.多态形式创建的变量,只能引用子类父类共有的东西,否则就会报错:找不到符号。

4.对象必须写在方法里才能够输出

5.注意:
(1)静态变量是属于整个类的变量而不是属于某个对象的。注意不能把任何方法体内的变量声明为静态,例如:
fun()
{
static int i=0;//非法。
}
静态变量先于静态代码块执行。

6.被final修饰的变量如果是基本数据类型的那么这个变量是不能被重新赋值的,但是如果是一个引用类型的,比如数组,那么堆内存中的数据是可以更改的,即等号左边不变就行,只要他还是指向这个数组的就没有问题,但是等号右边的数组只要你的位置信息没有变,里面的值是可以随便改的。例如:

class Demo{
	public static void main(String[] args){
		final int[] arry=new int[]{1,2,3};
		arry[1]=0;		//这个是可以的,改变的是数组内部的值,地址没有改变
		arry=null;		//这个编译会报错,因为改变了arry这个引用所指向的地址值
		System.out.println(arry[1]);
	}
}

7.抽象类中一定要有构造函数吗?
一定要有。构造函数是对象的基本,没有构造函数就没有对象,子类实例化的时候要先将父类实例化,所以父类一定要有构造函数,有参无参都可以。

8.抽象类中可以没有抽象方法吗?
可以。可以只要非抽象的成员,只要这个类是抽象的就可以。

9.TreeSet如果添加自定义对象需要先实现comparable接口并重写该接口的compareTo方法才可以,该方法的返回值为一个boolean值,返回正值或负值则证明两者不同,根据正负排序后存入集合,若等于0则不会存进集合
TreeSet会自动对存进去的元素进行排序,所以存进去的元素必须可以直接使用自然排序或者字典排序,否则就要使用comparable或者comparator进行改写

什么时候用comparable什么时候用comparator

1.TreeSet在创建对象的时候选用的是哪个构造方法,如果选用的是comparator的构造方法那么就必须用comparator
2.如果操作的类型可以直接使用自然排序那么就使用comparable
Comparable: 他让某个类具备比较功能,当创建出这个对象的类,就可以直接使用这个对象中的compareTo方法进行比较大小,Comparable是让对象自己具备了比较功能
Comparator: 他是提供比较两个对象大小,但是这个功能和对象自身并没有任何关系。只要将需要比较的两个对象传递给compare方法即可。提供单独的比较器对象,可以比较任意两个对象。

import java.util.Comparator;
import java.util.TreeSet;
//comparator后面的泛型在实现的时候要具体指出是哪一个,因为是Person2对象的比较,所以此处写Person2
/*什么时候用comparable什么时候用Comparator?二者其实作用相同,comparator是comparable的子接口,
comparator是创建TreeSet是的构造器中带的方法,此时需要用comparator,还有就是comparable中已经写好了按照自然顺序/字典顺序排序
不能随便更改,不然就要改源码,比较麻烦,适合可以直接适用自然排序的数据类型使用*/
//class Person2 implements Comparator<Person2> {
//	int age;
//	String name;
//	public Person2(){}	//一定要写一个无参构造函数,方便下面用这个类创建对象,否则就只能带参数创建对象,比较麻烦
//	public Person2(String name,int age){
//		this.name=name;
//		this.age=age;
//	}
//	@Override
//	public String toString() {
//		return name+"---"+age;
//	}
//	@Override
//	public int compare(Person2 p1, Person2 p2) {
//		int num=p1.age-p2.age;
//		if(num==0){
//			return p1.name.compareTo(p2.name);
//		}
//		return num;
//	}
//}
//public class Demo3 {		//TreeSet
//	public static void main(String[] args) {
/*TreeSet(Comparator<? super E> comparator) 构造一个新的空 TreeSet,它根据指定比较器进行排序。
下面使用了匿名内部类,父接口创建实现类对象,comparator不能直接创建对象,要使用他的实现类,所以直接把他的实现类
Person2中的compare方法重写一遍,这样就相当于创建了comparator对象,或者直接像下面那样创建Person2的对象*/
//		TreeSet<Person2> ts=new TreeSet<>(new Comparator<Person2>(){	
//			public int compare(Person2 p1, Person2 p2) {
//				int num=p1.age-p2.age;
//				if(num==0){
//					return p1.name.compareTo(p2.name);
//				}
//				return num;
//			};
//		});
//		
//		TreeSet<Person2>ts=new TreeSet<>(new Person2());//如果上面没写无参构造函数那么创建对象就只能写成new Person2("",2)
//		ts.add(new Person2("zhangsan",20));
//		ts.add(new Person2("lisi",21));
//		ts.add(new Person2("wangwu",20));
//		ts.add(new Person2("zhaoliu",24));
//		ts.add(new Person2("heqi",20));
//		
//		for(Object obj:ts){
//			Person2 p=(Person2)obj;//Object是父类,但是name和age是子类特有的,所以要向下转型
//			System.out.println(p);
//		}
//	}
//}
//下面用comparable方法,很简便
class Person3 implements Comparable<Person3>{
	int age;
	String name;
	public Person3(){}
	public Person3(String name,int age){
		this.name=name;
		this.age=age;
	}
	@Override
	public String toString() {
		return name+"-----"+age;
	}
	@Override
	public int compareTo(Person3 p) {
		int num=this.age-p.age;
		if(num==0){
			return this.name.compareTo(p.name);//此处调用的是String类中的compareTo方法
		}
		return num;
	}
}

public class Demo3{
	public static void main(String[] args) {
		TreeSet<Person3> x=new TreeSet<>();
		x.add(new Person3("zhangsan",20));
		x.add(new Person3("lisi",21));
		x.add(new Person3("wangwu",20));
		x.add(new Person3("zhaoliu",24));
		x.add(new Person3("heqi",20));
		for(Object obj:x){
			Person3 y=(Person3)obj;//Object是父类,但是name和age是子类特有的,所以要向下转型
			System.out.println(y);
		}
	}
}

10.list和他的实现类是有序可重复的,set和他的实现类是无序不可重复的,他们都可以接收null元素。
list的实现类包括ArrayList、LinkedList和VectorArrayList和Vector几乎差不多,三者差距主要在增删改查的效率和线程安全性上set的实现类包括HashSet和TreeSet。HashSet保证了存入数据的唯一性,以为每一个存入的元素都必须具有hashcode和equals算法,Tree保证了元素的有序性,因为每一个存入的元素都先执行了一遍compareTo方法,所以每一个元素必须是实现了Comparable接口的才可以,常见的有String,Integer等。虽然set类是无序的,但是HashSet的子类LinkedHashList可以保证存入取出的顺序是一致的,因为有一个linked限制了他。

在这里插入图片描述
在这里插入图片描述

出现这个错误的原因是没有给jsp中的标签赋值,如果没有给标签 name或者value 属性的话就会出现赋不上值的情况。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值