17.11
记录自己17年十一月学习中所遇到的部分问题
感想:
- 泛型类,有点容器的感觉?
- 泛型的出现就是为了创造容器类。
- 面向对象编程中基本目的:只操纵对基类的用,这样如果要添加一个新类来扩展程序,就不会影响到原来的代码。
问题:
- 导出类会合成一个默认的构造器???
- java为什么使用代理???代理的解释和理解???
- 不要使用finalize()???
- @override注解???
- 对象引用的向上转型的好处???
- Data类型,传进来的是String类型使用SimpleDataFormat进行转换
- Servlet获取多个复选按钮的值
- JAVA中String.split()
- list.subList();
- 为什么使用泛型类?不直接使用基类?自定义的类与泛型的区别对比?
- 使用forname()的好处?与new的对比还有newInstance作用?好处?
- 正则表达式
- 工厂类的必要性?
- Generator,Iterator,Comparable接口?
- Iterator it = sortedSet.iterator();什么意思?用法?
- 接口回调,回调结构。是怎么回事?
- Struts2使用前的准备?
- OGNL判断是否根对象?对值栈和OGNL的理解?
解答:
一:即使你不为Cartoon创建构造器,编译器也为会你合成一个默认的构造器,该构造器将调用基类的构造器
二:这个问题现在的我还没有理解,等过一段时间再来回答吧
http://blog.csdn.net/ljt2724960661/article/details/52507314
http://www.cnblogs.com/chentingk/p/6433372.html
代理模式:是一种使用代理对象来执行目标对象的方法并在代理对象中增强目标对象方法的一种设计模式。代理对象代为执行目标对象的方法,并在此基础上进行相应的扩展。
(开闭原则:对扩展开放,对修改关闭)
三:final,finally,finalize的区别:
1. 如果类被声明为final,意味着不能在派生出新的子类,不能作为父类被继承。将变量或者方法声明为final,可以保证它们在使用中不被改变。被声明为final的变量必须在声明时给定初值,在以后的引用中只能被读取,不可修改,声明final的方法一样,只能使用,不可重载。
2. 一般在finally中执行清理工作,不管怎样fianlly块都会被执行。
3. finalize()为一方法,JAVA允许finalize()方法在垃圾收集器将对象从内存中清除出去前做必要的清理工作,在Object类中定义的,子类覆盖finalize()方法以整理系统资源或者执行其他清理工作。finalize()方法是在垃圾收集器删除对象之前对这个对象调用的。
四:如果想重写父类的方法,比如toString(),在方法前面加上@Override系统可以帮你检查方法的正确性。例如:
@Override
public String toString(){......} //is true
//但是一旦写错,写成这样
@Override
public String tostring(){......} //is false
编译器会检测出这种写法是错误的,这样可以保证你的确重写的方法正确。
如果不加@Override
public String tostring(){......} //is false
是不会报错的,会认为你新加了一个方法。所以他说明了被标注的方法重载了父类的方法,起到了断言的作用。
五:
面向对象编程中基本的目的是:只操纵对基类的引用,这样,如果要添加一个新类来扩展程序,就不会影响到原来的代码
—–《Thinking in JAVA》
向上转型:子类引用的对象转换为父类类型成为向上转型,也就是将子类对象转为父类对象,此处父类对象可以是接口
public class Animal {
public void eat(){
print("Animal eat!");
}
}
class Bird extends Animal{
public void eat(){
print("Bird eat!");
}
public void fly(){
print("Bird fly!");
}
class Main{
public static void main(String[] args){
Animal b = new Bird();//向上转型
b.eat();
b.fly();//Animal中没有定义fly方法
}
子类对象当成父类对象,只能调用父类的成员,如果子类重写了父类的方法就根据这个引用调用子类重写的这个方法,这个方法也就是覆盖(Override)。这个调用的过程就称为“动态绑定”。但是,向上转型时,父类指向子类引用对象会遗失除了与父类对象共有的其他方法。也就是在转型过程中,子类的新方法会遗失掉,系统会提示找不到方法的错误。例如b.fly();出错。
六:
Date birthday;
SimpleDateFormat sdf = New SimpleDateFormat("yyyy-MM-dd");
birthday = sdf.parse(request.getParameter("birthday"));
String date = sdf.format(regUser.getBirthday());
七:
获取多个复选按钮的值,其实传过来的是字符串数组
favorites=request.getParameterValues("favorite");
八:
public String[] split(String regex,int limit){}
split()方法是用于使用特定的切割符(regex)来分割字符串成一个字符串数组,函数返回的是一个数组。在其中每个出现regex的位置都要进行分解。
需要注意的以下几点:
1. regex是可选项。字符串或正则表达式对象,它表示了分割字符串时使用的是一个还是多个字符。如果忽略该选项,返回包含整个字符串的单一元素数组。
2. “.”和“|”都是转义字符,必须加“\”。即String.split(“\.”)而不是String.split(“.”)同理String.split(“\|”)
3. split()方法结果与regex密切相关,如下代码所示:
public class SplitTest {
public static void main(String[] args) {
String str1 = "a-b";
String str2 = "a-b-";
String str3 = "-a-b";
String str4 = "-a-b-";
String str5 = "a";
String str6 = "-";
String str7 = "--";
String str8 = "";
split(str1);
split(str2);
split(str3);
split(str4);
split(str5);
split(str6);
split(str7);
split(str8);
}
public static void split(String demo){
String[] array = demo.split("-");
int len = array.length;
System.out.print("\"" + demo + "\" 分割后的长度为:" + len);
if(len >= 0)
{
System.out.print(",分割后的结果为:");
for(int i=0; i<len; i++)
{
System.out.print(" \""+array[i]+"\"");
}
}
System.out.println();
}
}
运行结果为:
“a-b” 分割后的长度为:2,分割后的结果为: “a” “b”
“a-b-” 分割后的长度为:2,分割后的结果为: “a” “b”
“-a-b” 分割后的长度为:3,分割后的结果为: “” “a” “b”
“-a-b-” 分割后的长度为:3,分割后的结果为: “” “a” “b”
“a” 分割后的长度为:1,分割后的结果为: “a”
“-” 分割后的长度为:0,分割后的结果为:
“–” 分割后的长度为:0,分割后的结果为:
“” 分割后的长度为:1,分割后的结果为: “”
由此可以得出:
当字符串只包含分隔符时,返回数组没有元素;
当字符串不包含分隔符时,返回数组只包含一个元素(该字符串本身);
字符串最尾部出现的分隔符可以看成不存在,不影响字符串的分隔;
字符串最前端出现的分隔符将分隔出一个空字符串以及剩下的部分的正常分隔;
九:
List<E> subList(int fromIndex,int toIndex);
用来返回一个list的一部分视图,它返回原来list的从【fromIndex,toIndex】之间的这部分视图。返回的list是靠原来的list支持的。所以对原来的list和返回的list做的“非结构性修改”都会影响到彼此对方。
非结构性修改:指不涉及list的大小改变的修改,相反,结构性修改,指改变了list大小的修改。
如果发生结构性修改的是返回的子list,那么原来的list的大小也会发生改变;如果发生结构性修改的是原来的list(不包括由于返回的子list导致的改变),那么返回的子list语义上将会是undefined(未定义的,不明确的)。在AbstractLIst(ArrayList的父类)中,Undefined的具体表现形式是抛出一个ConcurrentModificationException。
因此,如果你在调用sublist返回了子list后,修改了原来的list大小,那么之前产生的子list将会失效,变得不可用。
tips:如何删除一个list的某个区域,比如删除list的第2-5个元素?
解:可以利用sublist的幕后还是原来的list的这个特性,比如:
list.subList(from,to).clear()
十:为什么使用泛型类?不直接使用基类?自定义的类与泛型的区别对比?
一般的类和方法,只能使用具体的类型:要么是基本类型,要么是自定义的类。如果要编写可以应用于多种类型的代码,这种刻板的限制对代码的束缚就会很大。
————《thinking in JAVA》
- 多态算是一种泛化机制,凡是需要说明类型的地方,都使用“基类”,有更好的灵活性,但是,考虑到除了final类不能扩展,其他任何类都可以被扩展,所以这种灵活性大多数时候也会有一种性能损耗。
- 有时候拘泥于单继承,会受到限制。而如果是接口也必须要求代码使用特定的接口。
而我们希望编写更通用代码,应用于“不具体类型”,而不是一个具体的接口或类。
泛型希望类或者方法能够具备最广泛的表达能力。
————《thinking in JAVA》
十一:
十二:
十三:
十四:
十五:
十六:
十七:
在要使用标签的jsp页面引入标签库
<%@ taglib uri=".struts-tags" prefix="s"%>
在web.xml中声明要使用的标签。
十八:
狭义值栈里面存放这一些OGNL可以存取访问的数据,典型如:
1. Action的实例,可以通过OGNL来访问Action实例中的属性的值
2. OGNL表达式运算的值,可以设置到值栈中,可主动访问值栈对象,强行设置
3. OGNL表达式产生的中间变量
OGNL访问非根对象属性,例如#session.msg表达式,由于Struts2中值栈被视为根对象,所以访问其他非根对象时,需要加#前缀。实际上,#相当于ActionContext.getContext();#session.msg表达式相当于ActionContext.getContext().getSession().getAttribute(“msg”);