JavaSE学习体会
- 总结
- 整体感受
总结
我是最棒的!基础不牢,地动山摇!
整体感受
通过一个月沉下心来重新学习JavaSE部分,真的是收获颇多。想我之前自学的路上走了不少弯路,也有许多东西未曾了解,不过这一个月给我带来的提升真的很大。
人成长是一个过程,Java学习也是一个过程。首先,对我产生最大影响的就是一个观念,不仅知道一个东西怎么用,也需了解这个东西是怎么做出来的。从最简单的定义变量,例如基本数据类型和引用数据类型,了解到堆栈中他们是怎么出来的。
举个栗子
public static void main(String[] args){
int a = 1;
String str = "Hello World";
}
上面的main方法在栈中有一个栈桢,int a = 1;相当于在main方法这个栈桢里面开辟了一块空间,里面有一个a变量,存放了 1 这个值。而String是引用类型,它会在堆中开辟空间,存储“Hello World”,并且有一个地址,然后将这个地址存放在栈中的str里面。以前都是片面的认为定义变量都是一回事,现在画一个堆栈图很容易就能理解。后面的许多知识点都可以用堆栈图来分析。示例图如下
然后,我的代码的风格也变得越来越好,格式注释还有空行等。以前自己写的代码可能是一团乱麻,现在看起来条理清楚,自己看着也很有成就感。命名使用大小驼峰来完成,不会使用拼音或者中西结合。遇到不会的词就去查查,再用英文来命名,舒服多了。可能现在的我看到我以前写的xuesheng类也会有打死自己的冲动吧2333。
但是呢,我现在写注释的习惯不是很好,感觉一个东西很简单就不愿意去写注释,这一点出大问题,需要静下心来多写写注释,不然以后人家提刀来见我就不好了。
下面是我自己写的一个模拟断点续传代码,勿喷(注释确实写的少)
package cn.itsource.randomaccess;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* 模拟实现文件的断点续传
*/
public class Resume {
//记录指针位置
private static long position = -1;
public static void main(String[] args){
//定义源文件与目标文件
File srcFile = new File("test.txt");
File destFile = new File("F:/test.txt");
//使用随机文件访问类来完成
RandomAccessFile srcRaf = null;
RandomAccessFile destRaf = null;
try {
srcRaf = new RandomAccessFile(srcFile, "rw");
destRaf = new RandomAccessFile(destFile, "rw");
//定义字节数组,一个字节一个字节的读取
byte[] bs = new byte[1];
//读取操作
while(srcRaf.read(bs) != -1){
//写出操作
destRaf.write(bs);
//模拟网络中断
if(destFile.length() == 3){
//记录断开时的指针位置
position = srcRaf.getFilePointer();
System.out.println("网络连接中断");
throw new FileAccessException();
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (FileAccessException e) {
//续传操作
resume(srcRaf, destRaf, position);
}finally{
//关流操作
try {
if(destRaf != null){
destRaf.close();
}
} catch (IOException e) {
e.printStackTrace();
}finally {
if(srcRaf != null){
try {
srcRaf.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
/**
* 续传方法
* @param src
* @param dest
* @param position
*/
public static void resume(RandomAccessFile src,RandomAccessFile dest,long position){
//模拟网络中断10s
try {
Thread.sleep(10000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
try {
byte[] bs = new byte[1];
//将指针位置设置为上次断开时的位置
src.seek(position);
dest.seek(position);
//继续完成读写操作
while ((src.read(bs)) != -1) {
dest.write(bs);
}
System.out.println("续传成功");
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 自定义异常类
*/
class FileAccessException extends Exception{
}
最重要的是学到了很多新的知识点,比如JDK8新特性里面的Lambda表达式,简化了匿名内部类很多步骤,同时也认识了函数式接口。还有就是以前一些很模糊的概念也变得很清晰了,比如设计类的时候需要注意的很多地方,封装、无参构造、public修饰符、get和set方法等等。
还有代码块的执行顺序,继承和多态等。以前我都是一知半解,现在应该掌握了大半,剩下的就是用心敲代码至熟练咯。IO流里面的各种流,以前自学的时候没分清楚字节流和字符流,不知道到底有什么区别,现在问题不大。后面学习的流式处理,从头到尾就像管道一样,对源数据操作,但是不会改变源数据的类型。
Lambda表达式的一个栗子
接口
package cn.itsource.lambda;
@FunctionalInterface
public interface IMyInterface {
void test();
}
测试类
package cn.itsource.lambda;
public class LambdaTest {
public static void main(String[] args) {
//匿名内部类方式
IMyInterface iMyInterface = new IMyInterface() {
@Override
public void test() {
System.out.println("wdnmd");
}
};
iMyInterface.test();
//Lambda表达式
IMyInterface iMyInterface2 = () -> System.out.println("wdnmd");
iMyInterface2.test();
}
}
是不是感觉很舒服,这代码量!
最后一天学习了反射,这个知识点我以前只是有所耳闻,现在有一点理解了,通过全限定类名来获取该类的字节码文件,然后通过字节码文件获得该类里面的成员(字段,构造方法,普通方法等)。后面会学习的框架很多是基于反射的,后续会继续加强。
反射的示例代码
package cn.itsource.reflectdemo;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ReflectTest {
public static void main(String[] args) throws Exception{
/*
* 利用反射获取该类的构造方法并且使用newInstance创建对象
*/
Class<?> forName = Class.forName("cn.itsource.reflectdemo.A");
Constructor<?> constructor = forName.getConstructor(int.class,int.class);
System.out.println(constructor);
// Constructor<?>[] constructors = forName.getConstructors();
// for (Constructor<?> constructor : constructors) {
// System.out.println(constructor);
// }
// Constructor<?>[] declaredConstructors = forName.getDeclaredConstructors();
// for (Constructor<?> constructor : declaredConstructors) {
// System.out.println(constructor);
// }
Object newInstance = constructor.newInstance(1,2);
System.out.println(newInstance);
/*
* 使用反射调用普通方法
*/
Method[] declaredMethods = forName.getDeclaredMethods();
for (Method method : declaredMethods) {
System.out.println(method);
}
Method method = forName.getMethod("test");
method.invoke(newInstance);
Method method2 = forName.getMethod("test3", int.class);
method2.invoke(newInstance, 3);
/*
* 使用反射调用字段
*/
Field[] fields = forName.getFields();
for (Field field : fields) {
System.out.println(field);
}
Field[] declaredFields = forName.getDeclaredFields();
for (Field field : declaredFields) {
System.out.println(field);
}
// Field field = forName.getDeclaredField("a");
Field field = forName.getField("c");
field.setAccessible(true);
field.set(null, 3);
System.out.println(field.get(null));
/*
* 获取限定名和简写名
*/
String name = forName.getName();
System.out.println(name);
String simpleName = forName.getSimpleName();
System.out.println(simpleName);
}
}
/**
* 自定义类
*/
class A{
private int a;
int b;
public static int c;
private A(){
}
public A(int a,int b){
this.a = a;
this.b = b;
}
public void test(){
System.out.println("test");
}
public void test3(int a){
System.out.println(a);
}
private void test2(){
System.out.println("test2");
}
}
这个月的学习获益匪浅,不过需戒骄戒躁,继续保持下去。感谢每个真心待我的人!谢谢你们!也感谢自己,有勇气做出选择,铁石心肠也有水滴石穿的一天,继续加油!