java进阶学习笔记
2018-08-19
1.基本数据类型的认识
int a = 0;
double b = (double)a;
System.out.println(3/b); // -- Infinity
System.out.println(3/a); // -- / by zero
以上说明:double类型的数据并不是‘完全’准确的,此处的 b 并不是真正的 0,而是“近似”为0;(ps: 近似的大小取决于数据类型的精度)
2.文件的创建及其路径分析
Configuration cf = new Configuration(Configuration.VERSION_2_3_0); //freemarker
cf.setDirectoryForTemplateLoading(
new File("F:/shxt/workspace/term2_1/Test/src/freeMarker"));
ApplicationContext context =
new ClassPathXmlApplicationContext("classpath:/aop/application-context.xml");
绝对路径下:项目的根目录为: src
相对路径下:项目的根目录为:classpath:
3.aop技术
(1)application-context.xml
<!-- 读取对应LoggingAspect类 -->
<bean id="loggingAspect" class="aop.logging.LoggingAspect"></bean>
(2)LoggingAspect.java
@Before("execution(* aop.BookShop.*(..))")
private void artitheticDolog(JoinPoint jp) {
System.out.println(" jp.toString(): " + jp.toString());
}
@Before("execution(* aop..IService1.*(..))")
private void before(JoinPoint jp) {
System.out.println("方法参数 :" + Arrays.asList(jp.getArgs()));
System.out.println("接口实现类: " + jp.getSignature().getDeclaringTypeName());
System.out.println("方法名: " + jp.getSignature().getName());
}
①同一个aspect下可以写两个以上的相同advice;
②pointcut的切入点为对应测试类Test中测试对象的引用所属类别(即:若该引用为接口的引用,则切入点为该接口;若该引用为实现类的引用,则该切入点为该实现类)
(3)测试类Test
IService1 s1 = context.getBean("iService1",IService1.class); //此处一定得写接口名.class
IService2 s2 = context.getBean("iService2",IService2.class);
前提条件:如果进行AOP的话;否则抛出异常;
相反,如果不进行aop操作,且pointcut没有设置该对象所属类或接口范围时,系统就不会抛出:Exception in thread "main" org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'iService2' must be of type [aop.service.serviceImpl.ServiceImpl2], but was actually of type [com.sun.proxy.$Proxy6]
(4)异常处理(@AfterThrowing)
http://sishuok.com/forum/posts/list/7331.html
https://blog.csdn.net/owen_william/article/details/50812780
https://ask.csdn.net/questions/361538
https://blog.csdn.net/tengdazhang770960436/article/details/7037190
2018-01-26
1.构造函数执行顺序:构造函数的 函数名->成员变量->该构造函数体 内容。
2.notes.toArray(a);数组的拷贝,将数组notes拷贝到数组a中;
3.ArrayList,HashList都已经实现了toString()函数,所以能直接用数组名输出数组各项值;
4.clock设计:
返回boolean是个好设计:
进一步封装,对‘数据保护’更好;
减少了主程序的判断步骤,减少了资源的消耗(减少Clock里面对getvalue的调用。速度更快。)。
5.为什么说private是对类的不是对对象的
只有在同一个类生成的对象可以相互访问对方的私有属性,所以它是属于类的。
6.在类函数中有this吗?为什么?
没有。类函数属于类,类函数在被引用时,可以在不指明对象的情况下被使用。如果类函数中有了this,那就表示在使用过程中会涉及到对象。这与类函数应用情况相矛盾。因此类函数中没有this。
7.String类型的add函数,add(String , int location);在location位置插入,原数据依次后移一位;
8.***究竟把什么放进容器里去了?
当我们用add函数把对象放进容器中去的时候,究竟是把什么放进了容器?放进去的是对象本身吗?放进去以后,那个对象还在外面吗?如果修改了放进去的那个对象,容器中的对象会变化吗?写点代码来验证自己的猜测吧。
错误例子:
public class Test{
public static void main(String[] args) {
ArrayList<String> s=new ArrayList<String>();
String a="Hello,world!";
s.add(a);
System.out.println(s.get(0)); //Hello,world
s.set(0, "change"); //!!!!!!!!!!!!!!!!!!!!!!该位置上的对象引用(地址)已经改变
System.out.println(s.get(0)); //change
System.out.println(a); //Hello,world;
}
}
正确的例子:
public class Test {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder("456");
ArrayList<StringBuilder> a = new ArrayList<StringBuilder>();
a.add(sb);
System.out.println("a.get(0) = " + a.get(0));
sb.append("789"); //用append避免再次创建对象;
System.out.println("在执行了 sb.append("+789+")后,sb = " + sb);
System.out.println("a.get(0) = " + a.get(0));
/*
* 对外部对象的操作已经影响到了容器内部内容的变化,可见,add()添加的是对象的引用(地址);
*/
②import java.util.ArrayList;
public class TestArrary {
public static void main(String[] args) {
Test test1 = new Test(100);
ArrayList<Test> test_list = new ArrayList<Test>();
test_list.add(test1);
test1.setValue(150); //通过对外部引用test1的修改,以达到对容器内部的操作
System.out.println("修改从ArrayList中取得的对象test2, 查看test1, test_list");
System.out.println(test1.getValue() + ", " + test_list.get(0).getValue());
Test test2 = test_list.get(0); //test_list.get(0)把获取到的地址,赋给引用test2;
test2.setValue(50); //这时,得到地址的test2,就可以改变该地址上的值(100)了;
System.out.println("修改从ArrayList中取得的对象test2, 查看test1, test_list");
System.out.println(test1.getValue() + ", " + test_list.get(0).getValue());
/*
* 综上:add()的是对象的引用,而非对象本身;
*/
}
}
class Test{
private int value;
public Test(int _a){
value = _a;
}
public void setValue(int _value){
value = _value;
}
public int getValue(){
return value;
}
- }
- 修改从ArrayList中取得的对象test2, 查看test1, test_list
- 50, 50
===================================== Java 中String ===================================================
- String str1 = new String("hhh");
- String str2 = str1;
- if(str1 == str2){
- System.out.println("str1 is equal to str2.");
- }else{
- System.out.println("str1 is not equal to str2.");
- }
- str1 = "hello"; // str1 会变成另一个对象!!!!!!
- if(str1 == str2){
- System.out.println("str1 is equal to str2.--");
- }else{
- System.out.println("str1 is not equal to str2.--");
- }
- 当数组的元素的类型是类的时候,数组的每一个元素其实只是对象的管理者而不是对象本身。因此,仅仅创建数组并没有创建其中的每一个对象!
-
对理解继承来说,最重要的事情是,知道哪些东西被继承了,
- 除了构造方法。
- 构造方法是父类所独有的,因为它们的名字就是类的名字,所以父类的构造方法在子类中不存在。
-
但是得到不等于可以随便使用。每个成员有不同的访问属性
- Frienly:
如果子类与父类在同一个包内:只有包内其它类可以访问
否则:相当于private,不能访问
-
-
- Prvate:
-
不能访问
-
- 子类中如何为父类传递参数?
在构造一个子类的对象时,父类的构造方法也是会被调用的,而且父类的构造方法在子类的构造方法之前被调用。在程序运行过程中,子类对象的一部分空间存放的是父类对象。因为子类从父类得到继承,在子类对象初始化过程中可能会使用到父类的成员。所以父类的空间正是要先被初始化的,然后子类的空间才得到初始化。在这个过程中,如果父类的构造方法需要参数,如何传递参数就很重要了。
-
基本数据类型的‘强制转换’vs 对象的造型(仅可以向上造型)。
- 前者:是强制转换,实实在在的转换数据本身类型;
- 后者:只是把它“看做”另一个类的对象,实质上它本身没有变化。
- 所谓多态:通过一个变量调用一个函数,我们只是写了一句话,我们并不是去判断变量实际的类型是多少,不需要去写switch-case,不需要去写if-else,我们只是说s.draw();/item.print(),然后对应的那个函数就会被调用出来,这件事情就叫做多态。
- 可扩展性:程序增加或减少一些类似功能时,不需要做大的改动。
可维护性:同上;
14.优秀的软件设计者的一个素质就是有预见性。什么是可能会改变的?什么是可以假设在软 件的生命期内不会改变的?
15.以代码实现框架,将部分功能以数据的方式加载,这样能在很大程度上实现可扩展性。
-
String,StringBuffer与StringBuilder的区别??
-
- String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象
-
17.预见性:
优秀的软件设计者的一个素质就是有预见性。什么是可能会改变的?什么是可以假设在软 件的生命期内不会改变的? 在游戏的很多类中硬编码进去的一个假设是,这个游戏会是一个基于字符界面的游戏,通 过终端进行输入输出,会永远是这样子吗? 以后如果给这个游戏加上图形用户界面,加上菜单、按钮和图像,也是很有意思的一种扩 展。如果这样的话,就不必再在终端上打印输出任何文字信息。还是可能保留着命令字,还是会在玩家输入帮助命令的时候显示命令字帮助文本,但是可能是显示在窗口的文字域中,而不 是使用System.out.println?
可扩展性的意思就是代码的某些部分不需要经过修改就能适应将来可能的变化。
- 硬编码:
- 缺点:不具有可扩展性
- 覆盖:
- 继承抽象类的子类必须覆盖父类中的抽象函数
- 抽象类中的非抽象方法的作用:
- 抽象类中的非抽象成员方法可以供它的子类继承啊!
- 举个例子吧:有个抽象类:人类其中有个非抽象成员方法:吃饭(因为假定人类吃饭的方法都是咀嚼)而抽象方法则有:获取语言,获取性别等等。当子类需要继承“人类”这一抽象类时,它可以不用重写吃饭这一方法,只需要重写“获取语言”方法来满足对应的特殊对象需求。
- 所以总而言之抽象类中的非抽象成员方法也是为了提高复用而产生的机制
- 抽象类中的非抽象成员方法可以供它的子类继承啊!
- 抽象的本质:
- 与具体相对:表示一种概念而非实体
- 与细节相对:表示在一定程度上忽略细节而着眼大局
如何实现任意门?
如果想要实现任意门,即在某个房间,想要从某个出口出去,结果每次会走到不同的房间去。
如果要实现这样的任意门,整个程序的架构应该是怎样的?
如果任意门只是在这个房间的所有的门之间轮转,应该怎样实现?
如果任意门能在整个城堡的所有的门之间轮转,应该怎样实现?
-
- Math.Random()
- ArraryList()
- HashMap <Integer,Room> doors = new HashMap<Integer,Room>();
- 问题一:(第六周:6.2数据与表现分离)
为什么没有Cell.setAlive()?
为什么不是在Cell提供
setAlive(boolean)
函数?而是采用复杂的die()、reborn()两个函数?
- 耦合度:增加一个Boolean参数值,意味着增加了Cell类和CellMachine类之间的数据交流,即:耦合度提高;
- 可读性:CellMachine类是要‘获取’Cell类对象的状态值,而不是去‘设置’;
- 可扩展性:cell提供两个接口,cell本身还可以对这两个接口做些扩展性的动作;
- 问题二:
关于Field.getNeighbour()
为什么Field.getNeighbour()不直接看Cell.isAlive()来返回一个数字,而是要返回一个数组让外面来数数?
- 问题是如果让Field.getNeighbour()直接看Cell.isAlive()返回的数字的话,那么filed和cell之间存在关联,我们所希望的程序是各司其职,filed和cell和view主要是做自己的事情,而调用他们主要是通过cellmachine来调用,降低耦合,利于扩展,才是好程序!
- 降低函数之间耦合性,而且这里是两个不同的package。不过,如果从算法优化的角度来想返回Cell.isAlive()一个数字比较好,因为可以减少时间的消耗
24.
问题三:Cell为什么不自己判断邻居情况?
为什么不是由Cell自己判断自己的邻居的情况来决定自己是否应该被die或reborn?
- 对象之间也要保持距离,每一个细胞都是一个对象,这个对象怎么能知道其他8个对象的状态呢。要解决这个问题势必会增加cell与其他类的耦合。
- 接口:一种纯面向对象类,表达一种概念;
- 所有成员函数都是抽象函数
- 所有成员变量都是public static final
- L