this关键字,表示这个对象,当前对象,它代表当前对象的引用
public static class Test {
private int i = 0;
public Test iii() {
i++;
return this;
}
public void getI() {
System.err.println(i);
}
}
public static void main(String[] args) {
Test test = new Test();
test.iii().iii().iii().getI();
}
输出 : 3
this调用构造器,只能调用一个,必须置于起始处
public static class Test {
public Test() {
this("a");
}
public Test(String a) {
this(a, "b");
}
public Test(String a, String b) {
}
}
可变参数列表
public static class Test {
public Test(int a, String... strings) {
for (String s : strings) {
System.err.print(s + "-");
}
System.err.println(a);
}
}
public static void main(String[] args) {
new Test(0);
new Test(1, "a", "b", "c");
new Test(2, new String[] { "a", "b" });
}
输出:
0
a-b-c-1
a-b-2
------------------------------------------------数组---------------------------------------------
1. 数组是一个简单的线性序列,比ArrayList快,代价大小固定。
2. Arrays..toString() 格式化输出数组。
int[] i = new int[]{1,2,3,4};
System.err.println(i); //[I@330cdec1
System.err.println(Arrays.toString(i) );//[1, 2, 3, 4]
3. 数组的方法length 貌似还有clone()。
4. 对象数组保存的是引用,基本类型数组直接保存基本类型的值。
5.多维数组 用Arrays.deepToString()格式化输出,多维数组中构成矩阵的每个向量都可以具有任意的长度 int[][] i = new int[][]{{1,2},{1}};初始化的时候可以这样 int[][] i = new int[3][];,然后再去慢慢定义第二维度
int[][] i = new int[2][2];
System.err.println(i); //[[I@330cdec1
System.err.println(Arrays.toString(i) );//[[I@11f46b16, [I@45a27a8f]
System.err.println(Arrays.deepToString(i) );//[[0, 0], [0, 0]]
6.数组与泛型不能很好的结合,有解决办法,但是既然java这么设计,干脆就不这样结合了。直接用泛型容器吧。
7.Arrays类中有一套用于数组的静态方法,其中有6个本地方法
equals(数组1,数组2) 比较两个数组是否相等,deepEquals用于多维数组。基本元素比较,需要使用基本类型的包装器类的equal()方法。
fill() 用一个值填充各个位置,对对象而言就是复制同一个引用进行填充
sort() 用于对数组排序,对象要实现Comparable<T>或者Comparator<T>接口
Arrays.sort(i,Collections.reverseOrder());//倒叙
Arrays.sort(i,String.CASE_INSENSITIVE_ORDER);//忽略大小写
binarySearch() 用于在已经排序好的数组中查找元素。
还有上面的toString。
Arrays.asList() 接收任意的序列或者数组作为其参数
8. java标准类库还提供有static方法System.arraycopy(),用它复制数组必用for循环要快很多
System.arraycopy(数组1, 从这里开始复制, 复制到数组二, 从这里开始复制, 复制长度);
9.程序设计的基本目标:将保持不变的事物与会发生改变的事物相分离。
10. java标准类库中的排序算法针对正排序的特殊类型进行了优化-对于基本类型设计的快速排序,针对对象设计的稳定归并排序。所以无需担心排序的性能,除非你可以证明排序部分确实是程序效率的瓶颈。
------------------------------------------------类初始化顺序---------------------------------------------
在类内部,变量的先后顺序,决定了初始化的顺序,即使变量定义散步于方法定义之间,它依旧会在任何方 法包括构造器被调用之前得到初始化。 静态变量的顺序优先于非静态
通过类直接调用静态方法或着类变量,类中的所有静态变量都会被初始化。这也是所谓静态变量在类加载的时候初始化。也是为什么要有懒汉式和饿汉式
------------------------------------------------守护线程---------------------------------------------
定义: 守护线程--也称“服务线程”,在没有用户线程可服务时会自动离开。
优先级: 守护线程的优先级比较低,用于为系统中的其它对象和线程提供服务。
设置: 通过setDaemon(true)来设置线程为“守护线程”;将一个用户线程设置为守护线程的方式是在 线程v 对象创建 之前 用线程对象的setDaemon方法。
example: 垃圾回收线程就是一个经典的守护线程,当我们的程序中不再有任何运行的Thread,程序就不会再 产生垃圾,垃圾回收器也就无事可做,所以当垃圾回收线程是JVM上仅剩的线程时,垃圾回收线程 会自动离开。它始终在低级别的状态中运行,用于实时监控和管理系统中的可回收资源。
生命周期:守护进程(Daemon)是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种 任务或等待处理某些发生的事件。也就是说守护线程不依赖于终端,但是依赖于系统,与系统“同 生共死”。那Java的守护线程是什么样子的呢。当JVM中所有的线程都是守护线程的时候,JVM就 可以退了;如果还有一个或以上的非守护线程则JVM不会退出。
Thread daemonTread = new Thread();
// 设定 daemonThread 为 守护线程,default false(非守护线程)
daemonThread.setDaemon(true);
// 验证当前线程是否为守护线程,返回 true 则为守护线程
daemonThread.isDaemon();
这里有几点需要注意:
(1) thread.setDaemon(true)必须在thread.start()之前设置,否则会跑出一个IllegalThreadStateException异常。你不能把正在运行的常规线程设置为守护线程。
(2) 在Daemon线程中产生的新线程也是Daemon的。
(3) 不要认为所有的应用都可以分配给Daemon来进行服务,比如读写操作或者计算逻辑。
------------------------------------------------多参数方法---------------------------------------------
可以将参数,设置成自定义的枚举。
将多个有关系的参数放到一个类中。