public boolean save(String filename){ /* * 保存文件 */ try{ File file = new File(path + filename); ... // 未产生异常 return true; } catch (FileNotFoundException e){ // 产生异常 return false; } }
public void save(String filename) throws FileNotFoundException{ File file = new File(path + filename); ... }
public class Test { private String name; private class Test1{ public void sayHello(){ System.out.println("Hello, My name is " + name); // 会报错 } } }
public class Test { private final String name; // 加上了 final 关键字修饰 private class Test1{ public void sayHello(){ System.out.println("Hello, My name is " + name); } } }
for(int i = 0; i < 1000; i ++){ Message msg = new Message(); msg.what = UPDATE_PROGRESS; // 更新进度 // .... }
for(int i = 0; i < 1000; i ++){ Message msg = Message.obtain(); // 使用 api,以避免创建新对象 // ... }
先给出错误编码:for(int i = 0; i < 10000; i ++){ Object obj = new Object(); // 坏处:这样会在内存中产生大量的对象引用,浪费大量的内存空间,增大 GC 的负荷 System.out.println("wrong, obj=" + obj); }正确的编码方式:
Object obj = null; for(int i = 0; i < 10000; i ++){ obj = new Object(); // 好处:无论循环多少次,依旧仅在内存中保存一份对该对象的引用 System.out.println("right. Obj = " + obj); }即:正确的方法时,先在循环体外声明好需要使用的变量并置为空,然后再在循环体内初始化
public class Test { public static void main(String[] args){ Object obj = new Object(); // 使用 obj // .... // 使用完毕 obj = null; // 不要忽视这句代码的作用,它可以帮助你更好的管理内存,优化系统运行速度 } }
Java的引用几乎等同于C、C++ 中的指针,但是并不完全等同于。比如对于一个 int 类型的数组 arr,在C 中,指向该数组的指针 p 可以进行 ++ 操作,移动到下一个内存单元;但是Java中却不可以,绝对是通不过的。因此,可以说:Java 的引用是不可计数的指针
Person[] persons = new Person[4]; for(int i = 0; i < 4; i ++){ persons[i] = new Person(); }
对于上面的这一小段代码,是否存在疑问?为什么会要有 2 次 new 操作?
我们可以回想一下在 C 语言中,进行内存时的场景,就可以理解了。为什么会进行 2 次 new 操作呢?
因为,第一次的 new 操作,是给数组 persons 分配了一个连续的内存空间,但是 persons[1] 等,它们却是没有值的,即其值为 null。第二次的 new 操作,才是对每一个小的内存单元进行实例化,这些内存单元才会存在实际数据。[关于数组,一定要注意这一点]
不要有删除投产中代码的念头,如果方法或类确实不能在使用了,增加该注解
我们应该保持历史原貌,同时也有助于版本向下兼容,特别是在产品级研发中
/** * 旧方法 */ @Deprecated public static Person getPerson(){ return new Person(); } /** * 新的方法 */ public static Person getPerson(String key){ // ... }
再Java Swing编程中,可以使用 setDefaultCloseOperation() 方法来实现关闭当前窗体但不退出系统。但是在我使用该方法时却不依旧退出了系统。这是为什么呢?经过不断调试,才发现,我对 setDefaultCloseOperation() 的调用是写在自定义的 JFrame 中的。若是将该方法的调用写在创建自定义窗体的类中,才有效果。小结:不能写成 this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); 即不能再自定义 Frame 组件中调用该方法,只能在创建该窗体的类中进行设置,否则无效 new MyFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE)
List list = Arrays.asList(a[]); List arrayList = new ArrayList(list);
class A { private String name; public String getName () { return name; } } class B extends A { public void test () { System.out.println(name); // 这是错误的,编译器报错,没有 name 属性 } }
class A { private String name; public String getName () { return name; } } class B extends A { public void test () { System.out.println(super.getName()); // 这样才是正确的 }
8种基本数据类型:int、short、long、float、double、char、byte、boolean--->5个与数字相关的
各自所占的字节数:
// float f = 3.4; // 编译报错 float f = 3.04f; // 若要使用单精度需在后面加上字母f或F f = 3; short s = 1; // s = s + 1; // 编译报错,因为 s + 1 是的结果是 int 的,需要转型为 short s = (short) (s + 1); s += 1; // 相当于s1 = (short)(s1 + 1); 其中进行了隐含的强制类型转换
String s1 = "Hello,World"; String s2 = new String("Hello,World"); // 这句话创建了2个字符串对象,一个静态区的"Hello,World",一个new在堆上的对象 String s3 = "Hello" + ",World"; System.out.println(s1 == s2); // false System.out.println(s1 == s3); // true System.out.println(s1 == s2.intern()); // true,注意 intern() 方法
public void f () { System.out.println("1"); } public int f () { return 1; }上面那段代码是会出现编译报错的,报错内容为:Duplicate method f() in type Test。为什么会这样呢?因为有时候我们并不关心方法的返回值,想要的只是方法调用的其他效果。如我们在使用时,直接使用 f(); 而不用一个变量来接受其参数值,那么此时 Java 不知道该去调用哪一个 f() 方法,因此根据方法的返回值来区分重载方法是行不通的。
初始化顺序如下:类的静态成员(从父类到子类)---> 父类构造器--->子类非静态成员---->子类构造器