在构造器中调用构造器可以用this关键字,通常当你说 this,意味着"这个对象"或"当前对象",它本身生成对当前对象的引用。
import java.util.*;
class Flower {
int petalCount = 0;
String s = "initial value";
Flower(int petals) {
petalCount = petals;
System.out.println("Constructor w/ int arg only, petalCount = " + petalCount);
}
Flower(String ss) {
System.out.println("Constructor w/ string arg only, s = " + ss);
s = ss;
}
Flower(String s, int petals) {
this(petals);
//- this(s); // Can't call two!
this.s = s; // Another use of "this"
System.out.println("String & int args");
}
Flower() {
this("hi", 47);
System.out.println("no-arg constructor");
}
void printPetalCount() {
//- this(11); // Not inside constructor!
System.out.println("petalCount = " + petalCount + " s = " + s);
}
}
public class MyClass {
public static void main(String[] args)
{
Flower x = new Flower();
x.printPetalCount();
}
}
import java.util.*;
class T
{
int i;
T()
{
i = 10;
}
}
public class MyClass {
public static void main(String[] args){
T x = new T();
System.out.println(x.i);
}
}
output:
10
int是基本数据类型,存储的是数值,而Integer是引用类型,实际是一个对象,存储的是引用对象的地址
Integer a = new Integer(100),b = new Integer(100);
System.out.println(a==b);
output:
false
一个java源代码文件下只能含有一个public类,其他的类是为主类提供支持的,在包之外无法访问到这些为主类提供支持的类
public:无论是谁,无论在哪,都可以访问它。
包访问权限(默认,不加修饰):同一包内的其他类皆可访问。
private:除了包含该成员的类,其他任何类都无法访问这个成员。同一包中的其他类无法访问 private 成员,因此这等于说是自己隔离自己。
//private举例
class Sundae {
private Sundae() {}
static Sundae makeASundae() {
return new Sundae();
}
void f()
{
System.out.println("This is a test!");
}
}
public class MyClass {
public static void main(String[] args){
Sundae x = Sundae.makeASundae();
x.f();
}
}
当你定义一个具有包访问权限的类时,你可以在类中定义一个 public 构造器,在一个具有包访问权限的类中定义一个 public 的构造器并不能真的使这个构造器成为 public。
对于基类的构造函数是有参的情况,继承的派生类必须使用super关键字和适当的参数列表显式地编写对基类构造函数的调用:
class Game {
Game(int i) {
System.out.println("Game constructor");
}
}
class BoardGame extends Game {
BoardGame(int i) {
super(i);
System.out.println("BoardGame constructor");
}
}
public class MyClass {
public static void main(String[] args){
BoardGame x = new BoardGame(2);
}
}
当打算重写而不是重载一个方法时,可以使用注解@override
//像这样
class Homer{
float doh(float f)
{
System.out.println("float");
return f;
}
char doh(char c)
{
System.out.println("char");
return c;
}
}
class Lisa extends Homer
{
@Override float doh(float m)
{
System.out.println("void");
return m;
}
}
对于类自己内部的方法,自己调用不需加前缀。
class T
{
int i;
void f(int x)
{
i = x;
}
void set()
{
f(10);
}
}
使用 final 方法可以给方法上锁,防止子类通过覆写改变方法的行为。这是出于继承的考虑,确保方法的行为不会因继承而改变。
当说一个类是 final (final 关键字在类定义之前),就意味着它不能被继承。
一般用途:
帮助自己检查是否正确的复写了父类中已有的方法
告诉读代码的人,这是一个复写的方法
在面向对象中,私有方法不可以复写,根本就不存在复写私有方法的概念。私有方法本身就是为了封装在类内部,不希望别人来更改或者外部引用。
通常来说,extends 只能用于单一类,但是在构建接口时可以引用多个基类接口。注意到,接口名之间用逗号分隔。
class T
{
void f()
{
System.out.println("NJN");
}
public class t
{
public T cre()
{
return T.this;
}
}
}
public class MyClass{
public static void main(String[] args){
T x = new T();
T.t a = x.new t();
a.cre().f();
}
}
output:
NJN
在继承内部类的时候,不能使用默认构造器,必须重写
class Contents{
class c
{
}
}
class x extends Contents.c
{
x(Contents a)
{
a.super();
}
}
当继承了某个外部类的时候,内部类并没有发生什么特别神奇的变化。这两个内部类是完全独立的两个实体,各自在自己的命名空间内。
class Egg {
private Yolk y;
protected class Yolk {
public Yolk() {
System.out.println("Egg.Yolk()");
}
}
Egg() {
System.out.println("New Egg()");
y = new Yolk();
}
}
class B extends Egg
{
public class Yolk {
public Yolk() {
System.out.println("BigEgg.Yolk()");
}
}
Yolk y = new Yolk();
}
public class MyClass{
public static void main(String[] args){
new B();
}
}
output:
New Egg()
Egg.Yolk()
BigEgg.Yolk()
LinkedList 还添加了一些方法,使其可以被用作栈、队列或双端队列(deque) 。在这些方法中,有些彼此之间可能只是名称有些差异,或者只存在些许差异,以使得这些名字在特定用法的上下文环境中更加适用(特别是在 Queue 中)。例如:
//使用entry
//使用entry
for (Map.Entry<Integer,Integer> e: mp.entrySet())
System.out.println(e.getKey()+" "+e.getValue());
//使用iterator
Iterator<Map.Entry<Integer,Integer>> it = mp.entrySet().iterator();
while (it.hasNext())
{
Map.Entry<Integer,Integer> x = it.next();
System.out.println(x.getKey() + " " + x.getValue());
}
//使用for-in键值对
for (Integer i: mp.keySet())
System.out.println(i + " " + mp.get(i));
for (Integer i: mp.values())
System.out.println(i);
// generics/HasF.java
public class HasF {
public void f() {
System.out.println("HasF.f()");
}
}
//----------------------------------
// generics/Manipulation.java
// {WillNotCompile}
class Manipulator<T> {
private T obj;
Manipulator(T x) {
obj = x;
}
// Error: cannot find symbol: method f():
public void manipulate() {
obj.f();
}
}
public class Manipulation {
public static void main(String[] args) {
HasF hf = new HasF();
Manipulator<HasF> manipulator = new Manipulator<>(hf);
manipulator.manipulate();
}
}
//这里就会编译错误,因为擦除,Java 编译器无法将 manipulate() 方法必须能调用 obj 的 f() 方法这一需求映射到 HasF 具有 f() 方法这个事实上。为了调用 f(),我们必须协助泛型类,给定泛型类一个边界,以此告诉编译器只能接受遵循这个边界的类型。这里重用了 extends 关键字。由于有了边界,下面的代码就能通过编译:
public class Manipulator2<T extends HasF> {
private T obj;
Manipulator2(T x) {
obj = x;
}
public void manipulate() {
obj.f();
}
}
import java.lang.reflect.Array;
import java.util.*;
import java.nio.file.*;
import java.net.URI;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
//通过继承Thread来创建线程
class MyThread extends Thread
{
int i = 0;
@Override
public void run()
{
while (i<5) {
System.out.println(this.getName()+" i的值 "+i);
i++;
}
}
}
//通过实现 Runnable 接口来创建线程
class myRun implements Runnable
{
int i;
@Override
public void run()
{
try {
while (i++ < 5) {
System.out.println(Thread.currentThread().getName() + " i的值 " + i);
}
Thread.sleep(50);
}catch (InterruptedException e)
{
System.out.println("Thread " + " interrupted.");
}
}
}
//通过 Callable 和 Future 创建线程
//1. 创建 Callable 接口的实现类,并实现 call() 方法,该 call() 方法将作为线程执行体,并且有返回值。
//2. 创建 Callable 实现类的实例,使用 FutureTask 类来包装 Callable 对象,该 FutureTask 对象封装了该 Callable 对象的 call() 方法的返回值。
//3. 使用 FutureTask 对象作为 Thread 对象的 target 创建并启动新线程。
//4. 调用 FutureTask 对象的 get() 方法来获得子线程执行结束后的返回值。
class ca implements Callable<Integer>
{
@Override
public Integer call() throws Exception
{
int i = 0;
for (;i < 5;i ++)
System.out.println(Thread.currentThread().getName());
return i;
}
}
public class MyClass{
public static void main(String[] args){
MyThread x = new MyThread();
x.setName("By Thread");
x.start();
Thread y = new Thread(new myRun(),"By Runnable");
y.start();
FutureTask<Integer> t = new FutureTask<>(new ca());
new Thread(t,"By Callable and FutureRask").start();
}
}
非静态内部类(匿名内部类)都会默认持有对外部类的强引用,垃圾回收无效