Java 笔记
Hello World
System.out.println("Hello World")
- Javac
javac -yourJava.java
产生的.class是由 字节码 组成的
接下来会交给JVM。
- 操作符
public class Equivalence{
public static void main(String[] args){
Interger n1 = new Integer(47);
Interger n2 = new Integer(47);
System.out.println(n1 == n2);
System.out.println(n1 != n2);
}
} /* Output:
false
true
*///:~
==与!=比较的是对象的引用,所以是false,如果我们想像操作基本类型那样,我们就需要使用 equals() 方法。
System.out.println(n1.quals(n2));
初始化与清理
构造器:没有返回值(这与void是明显不同的)
但他是可以接受参数的,但必须有相同的名字(类名),即 方法重载。
构造器的初始化
class Window{
Window(int marker){print("Window("+marker+")")}
}
class House{
Window w1 = new Window(1);
House(){
print("House()");
w3 = new Window(33);
}
Window w2 = new Window(2);
void f(){print("f()");}
Window w3 = new Window(3);
}
public class OrderOfInitialization{
psvm(){
House h = bew House();
h.f();
}
} /* Output
Windows(1)
Windows(2)
Windows(3)
House()
Windows(33)
f()
*///:~
w3引用被初始化了2次,第一次的会被丢弃回收。
从概念是讲,初始化与创建是彼此独立的,你找不到initialize()的明确调用的。在Java中,两者是捆绑在一起的,无法分离。
垃圾回收
由于GC只知道释放那些new的内存,所以我们有一个finalize()的方法来回收内存,但注意他与C++中的析构函数是不一样的,对象不一定会被回收,对象可能不被GC回收。(and 不要用它 p90
数据结构
数组初始化
int[] a1;
int a1[];
//等价于new的
int[] a1={1,2,3,4,5};
//数组是可以相互赋值的,但只是赋值了一个引用
a1=a2;
//初始化在赋值时才结束的
Integer[] a = new Integer[rand.nextInt(20)]
...
a[i] = rend.nextInt(20)
//Object数组
static void printArray(Object... args){
for(Object obj : arfs)
System.out.print(obj+" ");
System.out.println();
}
psvm{
printArry(47.3.14F,11.11)
//在没有新特性之前我们要显示式申明数组,这样
printArry((new Integer(47),....)
}
enum和switch是好基友。
访问权限控制器
package是定义包的位置
import是要导入的包
- final关键字
这个单词意思是,这是无法改变的。
· 修饰基础数据成员的final
其含义相当于C/C++的const,即该成员被修饰为常量,意味着不可修改。
· 修饰类或对象的引用的final
public final A a = new A();
事实上a指向的对象的数据依然可以被修改,不能修改的是a本身的引用值,即你不能再对a进行重赋值。
· 修饰方法的final
修饰方法的final含义不是“不可修改” !
而是指该方法不可被继承成员重新定义。
final也可以提高效率,不过这是SE5之前的故事了...
接口
package com.lin;
interface USB{ //USB接口
public void work();
public void read();
public void write();
public void speed();
}
class PC{ //PC设备
public void comm(USB device){ //communicate方法
device.work(); //调用usb接口设备的工作方法
device.read();
}
}
class Socket{ //插座设备
public void comm(USB device){ //communicate方法
device.work(); //调用usb接口设备的工作方法
}
}
class Fan implements USB{ //风扇实现USB接口功能
public void work(){
System.out.println("转转转~");
}
public void read() {
// TODO Auto-generated method stub
System.out.println("风扇是不读取数据的");
}
public void write() {
// TODO Auto-generated method stub
System.out.println("风扇是不写入数据的");
}
public void speed() {
// TODO Auto-generated method stub
System.out.println("风扇是不在意速度的");
}
}
class Type_c implements USB{ //新式type-c实现USB接口功能
public void work(){
System.out.println("Type_c~");
}
public void read() {
// TODO Auto-generated method stub
System.out.println("Type_c读取很快");
}
public void write() {
// TODO Auto-generated method stub
System.out.println("Type_c写入很快");
}
public void speed() {
// TODO Auto-generated method stub
System.out.println("Type_c速度很快");
}
}
class Micro_usb implements USB{ //旧式micro_usb实现USB接口功能
public void work(){
System.out.println("micro_usb~");
}
public void read() {
// TODO Auto-generated method stub
System.out.println("micro_usb读取很慢");
}
public void write() {
// TODO Auto-generated method stub
System.out.println("micro_usb写入很慢");
}
public void speed() {
// TODO Auto-generated method stub
System.out.println("micro_usb速度很慢");
}
}
class USBDemo{
public static void main(String[] args){ //主函数
//买设备
PC pc = new PC();//pc上的USB使用
Socket socket=new Socket();//插座也有USB接口
Fan fan = new Fan();
Type_c typec = new Type_c();
Micro_usb microusb = new Micro_usb();
//pc通过communicate方法,调用相应USB设备功能.
pc.comm(fan);
pc.comm(typec);
pc.comm(microusb);
socket.comm(typec);
socket.comm(microusb);
}
}
所以没有USBj接口,我们就要不停的换插头了。
重写
例如,父类为Class animal,并且具有吃肉,吃草等方法。而子类分别为猫,狗,牛等,但是牛是不吃肉的,所以他不会重写吃肉这个方法。但是万一我们的子类太多,我们记不清是否重写了某个类,这时候这种写法就显得很有用了。
这时我们用Animal a = new niu()来实例化的话,我们先查找吃草的方法时,由于牛这个类中重写了吃草的方法,所以调用的是牛.吃草()的方法,如果我们找吃肉的方法,那么这时调用的就是animal.吃肉()的方法。
内部类
似乎是为了满足闭包性,隐藏方法。
实现多重继承。
可以避免修改接口而实现同一个类中两种同名方法的调用。
Collection
List
必须按照插入顺序保存
ArrayList更适合读取数据,LinkedList适合添加删除(链表)
Vector(多线程)
Set
无序无下标,不重复
HashSet equals与==,
SortedSet、ThreeSet
Map (键值对)
object-object
HashMap 操作快,允许null
LinkedMap ...
Queue (队列)
FIFO...略
迭代器 Iterator & ListIterator
和foreach思维不同的是,他可以修改对象
单项移动 & 双向
一个有趣的的...
public class list {
public static void main(String[] args) {
for (Map.Entry entry : System.getenv().entrySet()) {
System.out.println((entry.getKey() + ": " + entry.getValue()));
}
}
}
打印系统环境变量,.getenv返回一个Map。entrySet()产生一个由Map.Entry的 元素 构成的Set,并且这个Set是一个 Iterble(Iterator的接口)
异常处理
try catch throw finally、
鸡肋Excaption 和C#一样
字符串
String final的
StringBuilder 其实用这个更好
其实还有个多线程的
StringReader ...
重写
- 关于重写 equals & hashCode
可以看另一篇 <关于重写 equals & hashCode>
多线程
Q:为啥使用多线程?
A:CPU是多核的,为啥不用呢。可以防止程序阻塞。
多线程实现有两种
public class TicketThread extends Thread{
private static int tick=100;
public void run(){
while(true){
if(tick>0)
System.out.println(Thread.currentThread().getName()+" sale:"+tick--);
}
}
}
public class Treads {
public static void main(String[] args) {
TicketThread t1=new TicketThread();
TicketThread t2=new TicketThread();
TicketThread t3=new TicketThread();
t1.start();
t2.start();
t3.start();
}
}
在Thread中有 start() & run() 方法
区别: 只有调用了start()方法,才会表现出多线程的特性,不同线程的run()方法里面的代码交替执行。如果只是调用run()方法,那么代码还是同步执行的,必须等待一个线程的run()方法里面的代码全部执行完毕之后,另外一个线程才可以执行其run()方法里面的代码。
Runnable只有run(),没有start()
所以,即使实现了Runnable接口,那也无法启动线程,必须依托其他类。
实现Runnable接口,并不能启动或者说实现一个线程。Runnable接口,并不能代表一个线程。
而Thread类,有一个构造方法,参数是Runnable对象,也就是说可以通过Thread类来启动Runnable实现的多线程.
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
//实现Runnable接口后,需要使用Thread类来启动
public class MyRunnable implements Runnable {
private static int tick=100;
@Override
public void run() {
while(true){
if(tick>0)
System.out.println(Thread.currentThread().getName()+" sale:"+tick--);
}
}
//启动线程还是调用Thread类的start()方法
public class Test1 {
public static void main(String[] args){
MyRunnable r1=new MyRunnable();
MyRunnable r2=new MyRunnable();
MyRunnable r3=new MyRunnable();
Thread myT1=new Thread(r1);
Thread myT2=new Thread(r2);
Thread myT3=new Thread(r3);
myT1.start();
myT2.start();
myT3.start();
}
}
Runnable只是纯粹的去执行run()返回值为void。
Callable有返回值,是一个泛型,可以帮助我们获取异步执行的结果。
参考文档:http://www.importnew.com/18459.html
sleep()
join()
wait()释放锁标记,等待
notify()唤醒等待
I/O
可以看另一篇 <JAVA I/O>
反射
可以看另一篇 <JAVA 反射>
-和C#的不同
//判断类型
if(a instanceof Cat)
//使用父类方法
super.method()
//并没有override,只是注释作用
@Override
//内部类