类型信息

2016-03-17  本文已影响14人  zlb

运行时的类型信息使得你可以在程序运行时发现和使用类型信息

public abstract class School {
    String name;
    public String getName(String name){
        this.name = name;
        System.out.println(this.getClass().getName()+name);
        return this.name;
}
    public abstract String toString();
}
public class Primary extends School{
    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return "Primary";
    }
}
public class University extends School{
    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return "University";
    }
}
import java.util.Arrays;
import java.util.List;
public class test {
    public static void main(String[] args) {
        List<School> school = Arrays.asList(new Primary(),new High(),new University());
        for(School str : school){
            str.getName("hello");
        }
    }
}

面向对象编程的基本目的是:让代码只操纵对基类引用。在这个例子的School接口中动态的绑定了draw()方法,目的就是让程序员使用泛化的School引用来调用getName()方法
因此:它解放了程序在编期间执行的面向类型的操作,不管是程序的安全性还是可扩展性和可维护性,都得到了大大的加强。

 interface HasBatteries{}
interface WaterProof{}
interface Shoots{}
class Toy{
    Toy(int i){
    }
}
class FancyToy extends Toy implements HasBatteries,WaterProof,Shoots{
    //FancyToy(){}
    FancyToy(int i){super(i);}
}
public class ToyTest {
    static void printInfo(Class c){
        System.out.println("class name is \t"+c.getName()+"\tis intercace?"+c.isInterface());
        System.out.println("getSimpleName:\t"+c.getSimpleName());//产生类名
        System.out.println("getCanonicalName\t"+c.getCanonicalName());//产生全限定的类名  包括包名
    }
    public static void main(String[] args) throws ClassNotFoundException {
        // TODO Auto-generated method stub
        Class cc= null;
        try{
            cc = Class.forName("FancyToy");
        }catch(ClassNotFoundException ex){
            throw new ClassNotFoundException("这个类未发现");
        }
        System.out.println(cc);
        for(Class c : cc.getInterfaces()){
            System.out.println(c);
        }
        Class up = cc.getSuperclass();//得到基类
        Object obj = null;
        try {
            obj =  up.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        printInfo(obj.getClass());
    }
}

<b>注意如果把默认的构造器注释掉,则会出现java.lang.InstantiationException 错误,因为需要这个默认的构造器创建对象</b>
例子中有三种获得Class对象的方法:
Class.forName();最简单的,也是最快捷的方式,因为我们并不需要为了获得class对象而持有该类的对象实例。
obj.getClass;当我们已经拥有了一个感兴趣的类型的对象时,这个方法很好用
obj.class;类字面常量,这种方式很安全,因为它在编译时就会得到检查(因此不需要放到try语句块中),而且高效。

 class A{  
}  
class B extends A {  
}  
class C extends B {  
}  
public class IsInstance {  
    public static void main(String[] args) {  
        // TODO Auto-generated method stub  
        C c = new C();  
        B b = new B();  
        A a = new A();  
        B bc = new C();  
        A ac = new C();  
        System.out.println(c instanceof C);  
        System.out.println(c instanceof B);  
        System.out.println(c instanceof A);  
        System.out.println();  
        System.out.println(c.getClass().isInstance(c));  
        System.out.println(c.getClass().isInstance(b));  
        System.out.println(c.getClass().isInstance(a));  
        System.out.println();  
        System.out.println(c.getClass().isInstance(bc));  
        System.out.println(c.getClass().isInstance(ac));  
        System.out.println();  
        System.out.println(A.class.isInstance(a));  
        System.out.println(A.class.isInstance(b));  
        System.out.println(A.class.isInstance(c));  
        System.out.println(A.class.isInstance(ac));  
        System.out.println(A.class.isInstance(bc));  
        System.out.println();  
        System.out.println(B.class.isInstance(a));  
        System.out.println(B.class.isInstance(b));  
        System.out.println(B.class.isInstance(c));  
        System.out.println(B.class.isInstance(ac));  
        System.out.println(B.class.isInstance(bc));  
    }  
}  

需要判断一个对象是否his一个类的实力上时,可以用.isInstance()和instanceof 方法
instanceof运算符 只被用于对象引用变量
Class类的isInstance(Object obj)方法,obj是被测试的对象,如果obj是调用这个方法的class或接口 的实例,则返回true。这个方法是instanceof运算符的动态等价。

public class Generic_1 {
    public static void main(String[] args) {
        Class initClass = int.class;
        Class<Integer> generClass = int.class;
        generClass = Integer.class;
        initClass = double.class;
    }
}

如果希望稍微放松一些这种限制,应该怎么办呢?我们使用了通配符? 它是java泛型的一部分

 import java.util.ArrayList;
import java.util.List;
class CounterInteger{
    private static long couter;
    private final long id = couter++;
    public String toString(){
        return Long.toString(id);
    }       
}
public class FilledList<T> {
    private Class<T> type;
    public FilledList(Class<T> type){
        this.type = type;
    }
    public List<T> create(int ele){
        List<T> result = new ArrayList<T>();
        try{
            System.out.print(type.newInstance() instanceof CounterInteger);
            for(int i=0;i<ele;i++){
                result.add(type.newInstance());
            }
        }catch(Exception ex){
            throw new RuntimeException();
        }
        return result;
    }
    public static void main(String[] args) {
         FilledList<CounterInteger> list = new FilledList<CounterInteger>(CounterInteger.class);
         System.out.println(list.create(10));
    }
}
上一篇 下一篇

猜你喜欢

热点阅读