二进制及java反射机制(培训笔记)

来源:互联网 发布:阶乘c语言编程 编辑:程序博客网 时间:2024/06/08 11:52

2进制

计算机的底层全部都是2进制的!

byte short int long float double char String

Java 利用算法支持了10进制:

  • parseInt 将10进制转换为2进制
  • toString 将2进制转换为10进制

原理:



案例:

public class Demo01 {    public static void main(String[] args) {        /*         * 显示整数的2进制, 也就是显示内存中实际的2进制         * 存储情况.          */        //编译以后 "50" 就被编译为2进制        int i = 50;        System.out.println(            Integer.toBinaryString(i));         //Java输出整数时候自动调用了Integer.toString()        //将2进制转换为10进制字符串输出!        System.out.println(i); //50    }}

案例:

public class Demo02 {    public static void main(String[] args) {        /*         * 输出0~50全部的2进制         */        for (int i = 0; i <= 50; i++) {            System.out.println(                StringUtils.leftPad(                Integer.toBinaryString(i), 32, "0"));        }    }}

16进制

16进制用于简写2进制!!!

2进制书写繁琐! 使用16进制可以将2进制每4位数缩写为一个16进制数字

01101001 00100001 11101001 00101001简写为 69ade929


案例:

public class Demo03 {    public static void main(String[] args) {        /*         * 16进制用于缩写2进制.         * 16进制就是2进制!!!         */        int i = 0x69ade929;        System.out.println(            Integer.toBinaryString(i));         //Java 利用算法 parseInt(hex, 16) 将16进制        //转换为2进制.        String hex = "69ade929";        int n = Integer.parseInt(hex, 16);        System.out.println(            Integer.toBinaryString(n));     }}

补码

将2进制数的一半作为负数的算法, 称为补码


max =  01111111 11111111 11111111 11111111  int max = 0x7fffffff;

案例:

public class Demo05 {    public static void main(String[] args) {        /*         * 输出-50 到 50的全部补码         */        for(int i=-50; i<=50; i++){            System.out.println(                StringUtils.leftPad(                Integer.toBinaryString(i),32,"0"));        }    }}

案例:负数

public class Demo04 {    public static void main(String[] args) {        int i = -3;        System.out.println(            Integer.toBinaryString(i));         System.out.println(i);//-3        long l = -3L;        System.out.println(            Long.toBinaryString(l));     }}

案例:

public class Demo06 {    public static void main(String[] args) {        /*         * 输出整数的最大值         */        //int max = 0x7fffffff;        int max = Integer.MAX_VALUE;        System.out.println(max);        System.out.println(                Integer.toBinaryString(max));         /*         * 输出整数的最小值         */        int min = 0x80000000;        System.out.println(min);        System.out.println(                Integer.toBinaryString(min));     }}

题目

int i = 0xffffffff;System.out.println(i);如上代码输出结果:A.2147483647 B.-2147483647 C.2147483648 D.-2147483648 E.-1

补码互补对称现象

面试题:

System.out.println(~3+1);如上代码的结果是: ( C )A.3 B.4 C.-3 D.-4原理如下: 3    =  00000000 00000000 00000000 00000011  = 3~3   =  11111111 11111111 11111111 11111100  = -4~3+1 =  11111111 11111111 11111111 11111101  = -3System.out.println(~20+1);如上代码的结果是: ( C )A.20 B.21 C.-20 D.-21原理: 20     = 00000000 00000000 00000000 00010100  =  20~20    = 11111111 11111111 11111111 11101011  = -21~20+1  = 11111111 11111111 11111111 11101100  = -20System.out.println(~20);如上代码的结果是: ( D )A.20 B.21 C.-20 D.-21System.out.println(~-20);如上代码的结果是: ( E )A.20 B.21 C.-20 D.-21 E.19

2进制计算

~ 取反运算& 与运算| 或运算>>> 逻辑右移位运算>>  数学右移位运算<<  左移位运算

& 与运算(逻辑乘法)

规则:

0 & 0 = 00 & 1 = 01 & 0 = 01 & 1 = 1

| 或运算 (逻辑加法)

规则:

0 | 0 = 00 | 1 = 11 | 0 = 11 | 1 = 1

>>> 逻辑右移位运算

每个位向右移位, 高位补0

例子:

n       = 00101011 10110111 10100101 11011010m=n>>>1 = 000101011 10110111 10100101 1101101k=n>>>2 = 0000101011 10110111 10100101 110110

<< 左移位运算

每个位向左移位, 低位补0

例子:

n       = 00101011 10110111 10100101 11011010m=n<<1  = 0101011 10110111 10100101 110110100 k=n<< 2 = 101011 10110111 10100101 1101101000  

案例: 利用2进制计算, 将 '中' 进行UTF-8编码

int c = '中';//0x4e2d //  c   00000000 00000000 0100 1110 0010 1101//utf-8 b1= 1110XXXX  //utf-8 b2= 10XXXXXX  //utf-8 b3= 10XXXXXX

编码:


解码:


代码:

public class Demo07 {    public static void main(String[] args)         throws Exception{        /*         * 利用2进制计算实现 中文字的UTF-8编码         */        int c = '中';        //UTF-8 空白编码格式:        int b1=0xe0;        int b2=0x80;        int b3=0x80;        //填充第一个编码        int c1 = (c>>>12) | b1;        //填充第二个编码        int c2 = (c>>>6) & 0x3f | b2;        //填充第三个编码        int c3 = c & 0x3f | b3;         print(c);        print(b1);        print(c>>>12);        print(c1);        print(c2);        print(c3);        //解码: 测试        String str = new String(                new byte[]{(byte)c1,(byte)c2,(byte)c3}                , "UTF-8");        System.out.println(str);        //utf-8 解码的工作原理        int ch = (c1<<12)& 0xffff |                 (c2<<6) & 0xfff  |                 c3 & 0x3f;        System.out.println((char)ch);//中    }    public static void print(int c) {        System.out.println(                StringUtils.leftPad(                Integer.toBinaryString(c),32,"0"));    }}

经典面试题目:

优化计算 n % 4 可以优化为 ( n & 0x3 )n = 5 = 00000000 00000000 00000000 00000101  % 4 = 1 n = 6 = 00000000 00000000 00000000 00000110  % 4 = 2n = 7 = 00000000 00000000 00000000 00000111  % 4 = 3n = 8 = 00000000 00000000 00000000 00001000  % 4 = 0n = 9 = 00000000 00000000 00000000 00001001  % 4 = 1优化计算 n % 8 可以优化为 ( n & 0x7 )优化计算 n % 16 可以优化为 ( n & 0xf )if (year & 0x3 == 0){    //可以被4整除!}

移位计算的数学意义

142323.1423230. 扩大10倍14232300. 扩大10倍  142323. 1423230. 扩大10倍14232300. 扩大10倍小数点不动, 数字向左移动i    =  00000000 00000000 00000000 00110010. = 50 i<<1 =  0000000 00000000 00000000 001100100. = 100i<<2 =  000000 00000000 00000000 0011001000. = 200

案例:

public class Demo08 {    public static void main(String[] args) {        /*         * 左移位的数学意义         */        int n = 50;        int m = n<<1;        int k = n<<2;        System.out.println(m);        System.out.println(k);        Demo07.print(n);        Demo07.print(m);        Demo07.print(k);        /*         * 右移位的数学意义         */        n = 50;        m = n>>1; //>>>        k = n>>2; //>>>        System.out.println(m);//25        System.out.println(k);//12        Demo07.print(n);        Demo07.print(m);        Demo07.print(k);        /*         * >>> >> 在正数情况下一样         * >>> >> 在负数情况下不同         *  >> 负时候, 高位补1         *  >>> 负时候, 高位补0         *          * n =   11111111 11111111 11111111 11001110 -50         * n>>1  111111111 11111111 11111111 1100111 -25         * n>>2  1111111111 11111111 11111111 110011 -13         * n>>>1 011111111 11111111 11111111 1100111         *          * 将 >> 称为数学移位计算(向小方向取整)         * 将 >>> 称为逻辑移位计算         *          */        n = -50;        n = n>>1;        k = n>>>1;        System.out.println(n);        System.out.println(k);    }}

反射

反射是Java提供的API, 是Java 中的动态执行机制, 可以动态加载类,动态创建对象,动态访问属性,动态调用方法. 等

甚至打破访问限制, 访问私有成员(打破了封装)

静态执行

按照编译期间约定执行执行顺序, 在运行期间顺序执行.

Foo foo = new Foo();foo.test();

动态执行

编译期间不指定执行顺序, 在运行期间才缺点创建那个对象, 执行方法.

利用反射API, 可以实现动态执行!

动态加载类

Class cls = Class.forName(类名);


动态创建对象

Object obj = cls.newInstance();

这个类型必须有无参数构造器, 如果没有将抛出异常, 反射提供了调用有参数构造器的API方法! 不是重点!

反射API可以动态获取类的信息

包括: 类中声明的属性, 类中声明的方法, 等

案例:

public class Foo {    private int id = 5;    public String name = "Tom";    public void test(){        System.out.println("test()");    }    public void hello(){        System.out.println("Hello()");     }}public class Demo01 {    public static void main(String[] args)        throws Exception{        /*         * 利用反射API动态加载类到方法区         * 在运行期间加载一个类到内存中         */        Scanner in = new Scanner(System.in);        System.out.print("输入类名:");        //在运行期间得到类名        String className = in.nextLine();        //动态加载类, 如果类名错误将抛出异常        Class cls = Class.forName(className);        //显示加载的结果        System.out.println(cls);        //动态创建对象        Object obj = cls.newInstance();        System.out.println(obj);         //Declared: 声明的  Field: 字段,属性        //动态获取类中声明的全部属性信息        Field[] fields=cls.getDeclaredFields();        for (Field field : fields) {            System.out.println(field);         }        //动态获取类中声明的全部方法信息        Method[] methods = cls.getDeclaredMethods();        for (Method method : methods) {            System.out.println(method);         }    }}

经典题目:

Eclipse 的快捷菜单用到了哪些技术?答: 反射 呗!
原创粉丝点击