Java继承2.0

Posted 364.99°

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java继承2.0相关的知识,希望对你有一定的参考价值。

反射机制;继承设计;装箱拆箱、变参、枚举


1.对象包装器与自动装箱

装箱:基本类型(byte、short、int、long、float、double、char、boolean)转换为对象/包装器类wrapper(Byte、Short、Integer、Long、Float、Double、Character、Boolean)
拆箱: 顾名思义

包装器类:

  1. 不可变,一旦构造了包装器,就不允许更改包装在其中的值
  2. 包装器类为final类,不允许派生子类

注意: ArrayList<Integer>的效率远远低于int[]数组,因为每个值分别包装在对象中

1.1.装箱与拆箱

  1. 装箱
int i = 3;
Integer it = new Integer(i);

2 . 拆箱

 int i1 = it.intValue();

1.2.自动装箱与拆箱

  1. 自动装箱
int i = 3;
Integer it1 = i;
  1. 自动拆箱
int i = 3;
Integer it1 = i;
int i3 = it;

1.3.API

java.lang.Integer //前5个
java.text.NumberFormat //第6个

int intValue()将Integer对象的值多为一个int返回(覆盖Number中的intValue方法)
static String toString(int i)返回一个新的String对象,表示指定数值i的十进制表示
static String toString(int i,int radix)返回数值i基于radix参数指定进制表示
static int parseInt(String s)
static int parseInt(String s,int radix)
返回字符串s表示的整数,指定字符串必须表示一个十进制整数
采用radix参数指定的进制
static Integer valueOf(String s)
static Integer valueOf(String s,int radix)
返回一个新的Integer对象,用字符串s表示的整数初始化,指定字符串必须表示一个十进制整数
采用radix参数指定的进制
Number parse(String s)返回数字值,假设给定的String表示一个数值

2.参数数量可变的方法(变参(varargs))

printf

public class PrintStream{
  public PrintStream printf(String fmt,Object... args){
    return format(fmt,args);
  }
}

...:代码的一部分,表明此方法可以接收任意数量的对象(除fmt参数之外)
实际上: printf方法接收两个参数,一个是格式字符串,另一个是Object[ ]数组(保存着所有其他参数)

  1. 如果提供的是整数或者其他基本类型的值,会把他们自动装箱为对象
  2. 扫描fmt字符串时,将第i个格式说明符args[i] 的值匹配起来
  3. 编译器需要转换每个printf调用,将参数绑定到数组中,并在必要的时候自动装箱
    System.out.printf("%d %s",new Object[]){new Integer(n),"widgets"})

自定义变参方法
计算出最大值

public static double max(double...values){
  double largest = Double.NEGATIVE_INFINITY;
  for (double v:values){
    if (v > largest)
      largest = v;
  }
  return largest;
}

3.枚举类

枚举类只有实例,不能构造新的对象,在比较两个枚举类时,直接使用==进行比较

  1. 如下,枚举类Size的实例对象为SMALL,MEDIUM等4个,除此之外不能构造新的对象
  2. 枚举类的构造器总是私有的(可以省略private)只在构造枚举常量的时候调用
  3. 所有的枚举类都是Enum的子类
package Test;


public enum Size {
    SMALL("S"),MEDIUM("M"),LARGE("L"),EXTRA_LARGE("XL");

    private String abbreviation;

    private Size(String abbreviation){
        this.abbreviation = abbreviation;
    }
    public String getAbbreviation(){
        return abbreviation;
    }
}


package Test;

import java.util.*;

public class TestEnum {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        System.out.println("输入一个尺码:(SMALL,MEDIUM,LARGE,EXTRA_LARGE):");
        String input = in.next().toUpperCase();
        Size size = Enum.valueOf(Size.class,input);
        System.out.println("尺码缩写:" + size.getAbbreviation());
        if (size == Size.EXTRA_LARGE){
            System.out.println("这是最大尺码了");
        }
    }
}

API
java.lang.Enum

static Enum valueOf(Class enumClass,String name)返回给定类中有指定名字的枚举常量
String toString()返回枚举常量名
int ordinal()返回枚举常量在enum生命中的位置,基0
int compareTo(E other)枚举常量出现在other之前,返回一个负整数
this==other,返回0
否则,返回一个正整数

4.反射

反射库(reflection library)提供了一个丰富且精巧的工具集,可以用来编写能够动态操纵Java代码的程序。

反射: 能够分析类能力的程序
反射机制的作用:

  1. 在运行时分析类的能力
  2. 在运行时检查对象
  3. 实现泛型数组操作代码
  4. 利用Method对象,这个对象很像C++中的函数指针

4.1.Class类

    在程序运行期间,Java运行时系统始终为所有对象维护一个运行时类型标识,此信息会跟踪每个对象所属的类,虚拟机利用运行时类型信息选择要执行的正确的方法
    可以使用一个特殊的Java类访问这些信息,保存这些信息的类名为Class

4.1.1.获取Class类的三种方法

  1. getClass():返回一个Class类型的实例

String s = new String("字符串");
Class cla = s.getCLass; 
  1. forName(String className):返回一个Class实例,表示名为className的类,会抛出ClassNotFoundException异常

package test;

public class Role {
    protected String name;
}




package test;

public class Test {
    public static void main(String[] args) throws ClassNotFoundException {
        String className = "test.Role";
        Class cla = Class.forName(className);
        System.out.println(cla);
    }
}

  1. T.Class:T代表任意的Java类型(或void关键字),T.Class代表匹配的类对象
    注意: Class表示的是一个类型,可以是类,也可以不是类

       Class c1 = Random.class;
       Class c2 = int.class;
       System.out.println(c1);
       System.out.println(c2);

虚拟机为每个类型管理一个唯一的Class对象,因此,可以使用==运算符来实现两个类对象的比较

        String str1 = new String();
        System.out.println(str1.getClass() == String.class);

4.1.2.利用Class类型的对象,构造实例

调用getConstructor方法得到一个Constructor类型的对象,然后用newInstance方法构造一个实例
    getConstructor:获取构造方法,会抛出异常
    newInstance:实例化对象,会抛出异常

package test;

public class Role {
    protected String name;
    protected int age;
    public Role(){

    }
    public Role(String name){

    }

}



package test;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;

public class Test {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        String className = "test.Role";
        Class cl = Class.forName(className);

        //获取全部公共构造方法
        Constructor cons[]=cl.getConstructors();
        System.out.println(Arrays.toString(cons));
        //获取空参构造函数(公共的)
        Constructor con = cl.getConstructor();
        //根据参数列表,获取指定构造函数(公共的)
        Constructor con1 = cl.getConstructor(String.class);

        //通过构造函数的newInstance()实例化对象
        Object obj = con.newInstance();
        Object obj1 = con1.newInstance("Allen");


    }
}

4.1.3.API

java.lang.Class

static Class forName(String className)返回一个Class对象,表示名为className的类
Constructor getConstructer(Class...parameterTupes)生成一个对象,描述有指定参数类型的构造器

java.lang.reflect.Constructer

Object newInstance(Object...params)将params传递到构造器,来构造这个构造器声明类的一个新实例

java.lang.Throwable

void printStackTrace()将Throwable对象和堆栈轨迹打印到标准错误流

4.2.资源

Java资源定义:一些与类关联的资源

类通常有一些关联的数据文件,如:图像和声音文件,包含消息字符串和按钮标签的文本文件

Class类提供了一个很有用的服务可以查找资源文件

步骤:

  1. 获得拥有资源的类的Class对象
  2. 有些方法,如ImageIcon类的getImage方法,接收描述资源位置的URL
  3. 否则,使用getResourceAsStream方法得到一个输入流来读取文件中的数据

重点: Java虚拟机知道如何查找一个类,所以它能搜索相同位置上的关联资源
除了上述将资源文件与类文件放在一个文件夹中,还可以提供一个相对/绝对路径

package test;

import javax.swing.*;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

public class TestResource {
    public static void main(String[] args) throws IOException {
        Class cl = TestResource.class;
        URL aboutURL = cl.getResource("罗小黑.gif");
        ImageIcon icon = new ImageIcon(aboutURL);
        System.out.println(icon);

        InputStream stream = cl.getResourceAsStream("Re0/JustForTest.txt");
        String about = new String(stream.readAllBytes(),"UTF-8");
    }
}

API

URL getResource(String name)
InputStream getResourceAsStream(String name)
找到与类位于同一位置的资源,返回一个可以用来加载资源的URL或者输入流
没有找到资源,就返回null,所以不会抛出异常或I/O错误

4.3.利用反射分析类的能力

检查类的结构——反射机制最重要的内容

查看任意对象数据字段的名字和类型:

  1. 获取对应的Class对象
  2. 在Class对象上调用getDeclaredField

4.3.1.API

java.lang.class

Filed[ ] getFields()
Filed[ ] getDeclaredFileds()
getFields()方法返回一个包含Filed对象的数组,这些对象对应这个类或其超类的公共字段
getDeclaredFiled()方法也返回包含Filed对象的数组,这些对象对应这个类的全部字段
当类中没有字段,或者Class对象描述的是基本类型或数组类型,这些方法将返回一个长度为0的数组
Method[ ] getMethods()
Method[ ] getDeclaredMethods()
返回包含Method对象的数组
getMethod()返回所有的公共方法,包括从父类继承来的公共方法
getDeclareMethod()返回这个类或接口的全部方法,但不包含父类的方法
Constructor[ ] getCOnstructors()
Constructor[ ] getDeclaredConstructor()
返回包含Constructor对象的数组,其中包含Class对象所表示的类的所有公共构造器(getConstructor)或全部构造器(getDeclaredConstructor)
String getPackageName()得到包含这个类型的包的包名,如果这个类型是一个数组类型,则返回元素类型所属的包
当这个类型是一个基本类型,则返回"java.lang"

java.lang.reflect.Filed
java.lang.reflect.Method
java.lang.reflect.Constuctor

Class getDeclaringClass()返回一个Class对象,表示定义了这个构造器、方法或字段的类
Class[ ] getExceptionTypes()返回一个Class对象数组,其中各个对象表示这个方法所抛出异常的类型(Constructor和Method classes类中)
int getModifiers()返回一个整数,描述这个构造器、方法或字段的修饰符
使用Modifier类中的方法来分析这个返回值
String getName()返回一个表示构造器名、方法名或字段名的字符串
Class[ ] getParameterTypes()返回一个Class对象数组,其中各个对象表示参数的类型(Constructor和Method classes类中)
Class getReturnType()返回一个用于表示返回类型的Class对象(在Method类中)

java.lang.reflect.Modifier

static String toString(int modifiers)返回一个字符串,包含对应modifiers中位设置的修饰符
static boolean isAbstract(int modifiers)
static boolean isFinal(int modifiers)
static boolean isInterface(int modifiers)
static boolean isNative(int modifiers)
static boolean isPrivate(int modifiers)
static boolean isProducted(int modifiers)
static boolean isPublic(int modifiers)
static boolean isStatic(int modifiers)
static boolean isSynchronized(int modifiers)
static boolean isVolatile(int modifiers)
这些方法用以检测modifiers值中与方法名中修饰符对应的二进制位

4.3.2.打印一个类的全部信息

package test;

import java.util.*;
import java.lang.reflect.*;

/*
    This program uses reflection to print all features of a class.
 */
public class ReflectionTest {
    public static void main(String[] args) throws ReflectiveOperationException{
        //read class name from command line args or user input
        String name;
        if (args.length > 0)
            name = args[0];
        else {
            Scanner in = new Scanner(System.in);
            System.out.println("Enter class name (e.g.java.util.Date): ");
            name = in.next();
        }

        //print class name and superclass name (if != Object)
        Class cl = Class.forName(name);
        Class supercl = cl.getSuperclass();
        String modifiers = Modifier.toString(cl.getModifiers());
        if (modifiers.length() > 0)
            System.out.print("class " + name);
        if (supercl != null && supercl != Object.class)
            System.out.print("extends " + supercl.getName());

        System.out.print("\\n{\\n");
        printConstructors(cl);
        System.out.println();
        printMethods(cl);
        System.out.println();
        printFields(cl);
        System.out.println("}");
    }

    /**
     * Prints all constructors of a class
     * @param cl a class
     */
    public static void printConstructors(Class cl){
        Constructor[] constructors = cl.getDeclaredConstructors();

        for (Constructor c : constructors){
            String name = c.getName();
            System.out.print("   ");
            String modifiers = Modifier.toString(c.getModifiers());
            if (modifiers.length() > 0)
                System.out.println(modifiers + " ");
            System.out.print(name + "(");

            //print parameter Types
            Class[] parmaTypes = c.getParameterTypes();
            for (int j = 0;j < parmaTypes.length;j++){
                if (j > 0)
                    System.out.print(", ");
                System.out.print(parmaTypes[j].getName());
            }
            System.out.println(");");
        }
    }

    /**
     * Print all methods of a class
     * @param cl a class
     */
    public static void printMethods(Class cl){
        Method[] methods = cl.getDeclaredMethods();

        for (Method m : methods){
            Class retType = m.getReturnType();
            String name = m.getName();

            System.out.print("    ");
            //print modifiers, return type and method name
            String modifiers = Modifier.toString(m.getModifiers());
            if (modifiers.length() > 0)
                System.out.print(modifiers + " ");
            System.out.print(retType.getName() + " " + name + "(");

            //print parameter types
            Class[] paramTypes = m.getParameterTypes();
            for (int j = 0;j < paramTypes.length;j++){
                if (j > 0)
                    System.out.print("'");
                System.out.print(paramTypes[j].getName());
            }
            System.out.println(");");
        }
    }
    /**
     * Print all fields of a class
     * @param cl a class
     */
    public static void printFields(Class cl){
        Field[] fields = cl.getDeclaredFields(操作 Java 泛型:泛型在继承方面体现与通配符使用

java中封装,继承,多态,接口学习总结

Java Socket Server-Client模式 2.0

google drive Oauth 2.0 for java web application

Linkedin OAuth 2.0 重定向 URL 不能包含片段标识符 (#)

用于模糊的 OpenGL ES 2.0 片段着色器速度慢且质量低