[随笔][Java][something]
- import 只能导入包中的类,不能导入某个包。为了方便,一般不导入单独的类,而是导入包下的所有类。import java.util.*;
- 包java.lang中的所有类默认由编译器全部导入了,不必手动显示的导入。
- import的搜索路径为环境变量中的CLASSPATH,一般将当前目录作为其中的一项“点.”添加到CLASSPATH中。
- 一个类中的变量类型有三种:局部变量(在方法中或者语句块中定义的变量),成员变量(定义在类中,方法体之外的变量),类变量(定义在类中,方法体之外的,使用static修饰的变量)。
- 在一个方法中使用成员变量,成员变量无论是否使用this进行调用,在编译的过程中都没有报错。但是如果成员变量的名字和方法的参数的名字一样,存在覆盖的效果。如果方法中不存在与成员变量一样的参数,则方法正常。
- 构造方法一般不能显示的调用,但是可以在构造方法中通过super关键字显示的调用父类的构造方法。在继承体系中,如果父类没有提供无参构造函数,需要在子类的构造函数中通过super关键字显示的调用父类的构造函数;如果父类提供了无参构造函数或者有默认的无参构造函数,在子类中可以不显示的调用父类的构造函数。猜想的原理有两个,如果一个类没有定义构造函数,编译器默认添加一个无参构造函数,自定义构造函数了,编译器不添加任何构造函数;如果一个类继承某个类,在构造函数中没有显示的调用父类的构造函数,编译器默认调用父类无参函数。
- java程序初始化顺序
父类静态变量 ->父类静态代码块 -> 子类静态变量 -> 子类静态代码块 -> 父类非静态变量 -> 父类非静态代码块 -> 父类构造函数 -> 子类非静态变量 -> 子类非静态代码块 -> 子类构造函数
- java通过访问修饰符来控制类,属性和方法的访问权限和其他功能。java的修饰符分为访问修饰符和非访问修饰符。
- 访问修饰符关键字总共有三个,权限控制类型有4种(多了一个默认的)。
- private关键字不能修饰类和接口,否则会在编译的时候报错。
- 不使用任何修饰符的属性和方法,对一个包内的类是可见的。接口里的变量都隐式的声明为public static final,而接口里的方法都隐式的声明为public。
- 继承规则
1. 父类中声明为public的方法在子类中也必须为public。
2. 父类中声明为protected的方法在子类中要么声明为protected,要么声明为public。不能声明为private。
3. 父类中默认修饰符声明的方法,能够在子类中声明为private。
4. 父类中声明为private的方法,不能够被继承。
java的变量的作用域分为4个级别:类级,实例级,方法级,块级。对于方法级和块级的变量,在使用之前必须初始化,否则不允许使用。
- 对于this关键字,java默认把成员变量、成员方法和this关键字关联在一起,所以有些时候使用this关键字是多余的。
- 在一个类的构造方法中,可以使用this关键字调用本类的其他构造方法。但是必须作为构造方法的第一句。
public class Demo{
public String name;
public int age;
public Demo(){
this("weixunyuan", 3);
}
public Demo(String name, int age){
this.name = name;
this.age = age;
}
public void say(){
System.out.println("web site name " + name + ", are launched " + age + " year");
}
public static void main(String[] args) {
Demo obj = new Demo();
obj.say();
}
}
- 在一个构造方法中调用另外一个构造方法的语句必须在第一行;不能在构造方法之外的任何方法内调用构造方法;在一个构造方法内只能调用一个构造方法。使用this关键字做构造方法的重载。
- this关键字也可以作为参数进行传递,表示的是当前对象的引用。
public class Demo{
public static void main(String[] args){
B b = new B(new A());
}
}
class A{
public A(){
new B(this).print(); //匿名对象
}
public void print(){
System.out.println("Hello from A!");
}
}
class B{
A a;
public B(A a){
this.a = a;
}
public void print() {
a.print();
System.out.println("Hello from B!");
}
}
匿名对象就是没有名字的对象,如果对象只使用一次,可以使用匿名对象。
- 方法的重载(over load)指的是在同一个类中,相同的方法名,不同的参数。声明为final的方法不能重载,声明为static的方法不能被重载,但是能够被再次声明。
- 重载的方法的返回值类型可以相同也可以不相同,仅仅返回类型不同不足以成为方法的重载因素。
- 对于初始化的顺序
public class Demo{
A a = new A();
public Demo() {
System.out.println("demo");
}
public static void main(String[] args){
Demo d = new Demo();
}
}
class A {
public A() {
System.out.println("a");
}
}
//输出结果
D:\Workspace\java>java Demo
a
demo
D:\Workspace\java>
- java中定义一个包,在语法层面需要使用package关键字定义,在文件系统层面需要按照包的名字将源码文件放到对应的位置。一个包中还可以包含其他的包。????
- 执行javac命令需要进入到当前目录,执行java命令需要进入当前目录的上级目录,并且类名前面要带上包名。?????
java的继承和多态
- 子类可以继承父类中除了private的所有成员。
- 类是单继承,接口允许多继承。
super关键字的三个作用:调用父类中声明为private的变量,获取已经覆盖的方法,作为方法名表示父类的构造方法。
- 覆盖:在子类中创建一个方法,名称,参数列表,返回值都和父类中的相同。则子类中的方法覆盖父类中的方法。被覆盖的方法在子类中通过super调用。
- 在子类中写方法对父类中的相应方法进行覆盖的时候,需要注意权限访问符的级别,返回值类型,方法名,参数列表。
1. 访问修饰符,子类中覆写的方法的访问权限修饰符级别要低于父类中的,也就是子类方法应具有高广的访问范围。如果父类的方法是private,则子类的覆写概念不成立,因为子类不会继承父类为private的成员,子类怎么写都无所谓。默认包权限 > protected > public
2. 子类的覆写的方法只覆写父类中的某个方法,如果父类中的有多个方法进行重载,则子类的方法只覆写其中的一个,其他的方法还是使用继承过来的方法。
3. 覆盖方法的返回类型、方法名称、参数列表必须与原方法的相同。
4. 覆盖方法不能比原方法访问性差(即访问权限不允许缩小)。
5. 覆盖方法不能比原方法抛出更多的异常。
6. 被覆盖的方法不能是final类型,因为final修饰的方法是无法覆盖的。
7. 被覆盖的方法不能为private,否则在其子类中只是新定义了一个方法,并没有对其进行覆盖。
8. 被覆盖的方法不能为static。如果父类中的方法为静态的,而子类中的方法不是静态的,但是两个方法除了这一点外其他都满足覆盖条件,那么会发生编译错误;反之亦然。即使父类和子类中的方法都是静态的,并且满足覆盖条件,但是仍然不会发生覆盖,因为**静态方法是在编译的时候把静态方法和类的引用类型进行匹配**。
如果子类中进行方法的覆写,那么父类中的那些没有被覆写的方法和子类中的方法一起进行重载。
- 一个多态的例子
public class Demo {
public static void main(String[] args){
Animal obj = new Animal();
obj.cry();
obj = new Cat();
obj.cry();
obj = new Dog();
obj.cry();
}
}
class Animal{
public void cry(){
System.out.println("animal\n");
}
}
class Cat extends Animal{
public void cry(){
System.out.println("cat\n");
}
}
class Dog extends Animal{
public void cry(){
System.out.println("dog\n");
}
}
- 多态的三个条件:有继承,有重写,父类变量引用子类对象。
重载是在一个类的范围内,不涉及继承,重写是在子类和父类范围内,涉及继承。
- 这块应该了解一下java的内存模型。对于每个对象,存储的是成员变量。在类定义的部分,如果继承了父类的方法,应该有个父类中该方法的入口地址。如果子类对该方法进行了覆写,那么子类中这个位置就是自己的方法的入口地址。对于多态的方法,在父类中首先应该存在这个方法,不然,沿着继承链向上,可能会没有这个方法,因此在进行多态的时候,首先检查父类中是否存在这个方法。
多态是面向对象的概念,java通过动态绑定实现多态。多态是概念,动态绑定是技术。
- 动态绑定流程
1. 编译器查看对象的声明类型和方法名。
2. ???
- 如果想实现多态,需要解决一个问题,就是如何判断一个变量所实际引用的对象的类型。C++使用TRRI,java使用instanceof操作符。
public final class Demo{
public static void main(String[] args) {
People obj = new Teacher();
if(obj instanceof Object){
System.out.println("i am a object\n");
}
if(obj instanceof People){
System.out.println("i am human\n");
}
if(obj instanceof Teacher){
System.out.println("i am a teacher\n");
}
if(obj instanceof President){
System.out.println("i am caption\n");
}
}
}
class People{ }
class Teacher extends People{ }
class President extends Teacher{ }
//输出
D:\Workspace\java>java Demo
i am a object
i am human
i am a teacher
D:\Workspace\java>
如果变量引用的是当前类或者他的子类的实例,instanceof返回true,否则返回false。
- 对象的类型转化,指的是存在继承关系的类的对象之间的转化。子类向上转换称为向上转型,父类向子类转换成为向下转型。使用父类的变量引用子类的实例,称为向上转型。将向上转型后的子类对象再转成子类,称为向下转型,调用子类的方法就是向下转型。
- 不能将父类的对象直接转换成子类的对象,只能将向上转型后的子类对象向下转型。也就是子类对象必须向上转型后才可以向下转型。如果直接将父类对象向下转型称为子类对象,编译的时候不会出错,但是在运行的时候会出错。
public class Demo {
public static void main(String args[]) {
SuperClass superObj = new SuperClass();
SonClass sonObj = new SonClass();
// SonClass sonObj2 = (SonClass)superObj;
superObj = sonObj; //向上转型
SonClass sonObj1 = (SonClass)superObj; //向下转型
}
}
class SuperClass{ }
class SonClass extends SuperClass{ }
java的高级特性
- java允许内部类(嵌套类)的存在。在一个类的内部,在一个方法体中,在一个语句块中,都可以定义另外一个类,称为内部类。
- 内部类和外部类之间存在所属关系,一般只用在定义他的类或语句块之内。实现一些没有通用意义的功能。在外部引用内部类的时候,需要给出完整的名称。
- 内部类的用途:
内部类可以访问外部类中的数据,包括私有的数据。
内部类可以对同一个包中的其他类隐藏起来。
**当想要定义一个回调函数且不想编写大量代码时,使用匿名(anonymous)内部类比较便捷。**
减少类的命名冲突。
public class Outer {
private int size;
public class Inner {
private int counter = 10;
public void doStuff() {
size++;
}
}
public static void main(String args[]) {
**Outer outer = new Outer();**
**Inner inner = outer.new Inner();** //必须先定义外部对象,才能生成内部类的对象。
inner.doStuff();
System.out.println(outer.size);
System.out.println(inner.counter);
System.out.println(counter); //不可以直接访问内部类的私有变量,但是可以使用inner.counter的方式进行访问。
}
}
- 内部类是编译器行为,是虚拟机无感知的,生成特殊名字的字节码文件。
java泛型
- 针对不同的数据类型,除了可以使用重载,还可以借助自动装箱和向上转型。
public class Demo {
public static void main(String[] args){
Point p = new Point();
p.setX(10); // int -> Integer -> Object
p.setY(20);
int x = (Integer)p.getX(); // 必须向下转型
int y = (Integer)p.getY();
System.out.println("This point is:" + x + ", " + y);
p.setX(25.4); // double -> Integer -> Object
p.setY("东京180度");
double m = (Double)p.getX(); // 必须向下转型
double n = (Double)p.getY(); // 运行期间抛出异常
System.out.println("This point is:" + m + ", " + n);
}
}
class Point{
Object x = 0;
Object y = 0;
public Object getX() {
return x;
}
public void setX(Object x) {
this.x = x;
}
public Object getY() {
return y;
}
public void setY(Object y) {
this.y = y;
}
}
向下转型存在风险,且在编译的期间不容易发现。
- 使用泛型的例子。
public class Demo {
public static void main(String[] args){
// 实例化泛型类
Point<Integer, Integer> p1 = new Point<Integer, Integer>();
p1.setX(10);
p1.setY(20);
int x = p1.getX();
int y = p1.getY();
System.out.println("This point is:" + x + ", " + y);
Point<Double, String> p2 = new Point<Double, String>();
p2.setX(25.4);
p2.setY("东京180度");
double m = p2.getX();
String n = p2.getY();
System.out.println("This point is:" + m + ", " + n);
}
}
// 定义泛型类
class Point<T1, T2>{
T1 x;
T2 y;
public T1 getX() {
return x;
}
public void setX(T1 x) {
this.x = x;
}
public T2 getY() {
return y;
}
public void setY(T2 y) {
this.y = y;
}
}
- 泛型的类的定义中,增加了类型参数。
2018年9月11日
- private的不可见性是对其他类不可见,对于本类中定义的成员方法或者静态方法都是可见的。单纯的理解为private成员变量在类的外部不可以显示调用表述的不够全面。只要是属于这个类的成员,都可以调用该类中的私有成员,成员包括成员变量,成员方法,静态方法。在静态方法中,可以创建一个本类的对象,然后在该对象上直接调用私有成员。
- 一个类的私有成员对其他类是不可见的,但是在其他类中创建一个该类的对象,然后将该类的引用传回该类的某个公共的方法,无论是静态的还是非静态的,使用传递过来的对象引用就可以访问私有成员。
public class Demo {
public static void main(String[] args) {
A a = new A();
System.out.println(A.value(a));
}
}
class A {
private int i = 11;
public static int value(A a) {
return a.i;
}
}
2018年9月20日
- 动态网页技术有两种:CGI技术和Servlet技术。
- php, python等脚本语言使用的是cgi技术,服务器每次接收到一个请求之后都会调用cgi程序,重新启动一个进程。后来的fast-cgi技术就是让cgi进程称为守护进程,无服务和cgi通信,将参数传递过去。
每次调用Servlet并不是启动一个新的进行,而是在服务器进程中共享和分离线程,也就是Servlet线程包含于服务器进程,但是Servlet不是线程安全的,单实例多线程。
[随笔][Java][something]的更多相关文章
- 工作随笔——Java调用Groovy类的方法、传递参数和获取返回值
接触Groovy也快一年了,一直在尝试怎么将Groovy引用到日常工作中来.最近在做一个功能的时候,花了点时间重新看了下Java怎么调用Groovy的方法.传递参数和获取返回值. 示例Groovy代码 ...
- 工作随笔—Java容器基础知识分享(持有对象)
1. 概述 通常,程序总是运行时才知道的根据某些条件去创建新对象.在此之前,不会知道所需对象的数量,甚至不知道确切的类型,为解决这个普遍的编程问题:需要在任意时刻和任意位置创建任意数量的对象,所以,就 ...
- [随笔][Java][修改pom仓库库为阿里云]
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://mave ...
- [随笔][Java][总结][java 类型系统]
java 的类型系统大体分为两类,对象和基本类型.java使用静态类型检查来保证类型安全.每个变量在使用之前需要声明.非静态类型的语言不要求变量在使用之前进行声明. 基本数据类型 java的基本类型不 ...
- 工作随笔——Java网络代理(http,socks)
简单说一下Java如何便捷的使用网络代理功能 此方法使用于大部分情况,一些特殊框架(如:mina)无效. // 代码设置http代理 System.setProperty("proxySet ...
- 随笔java面试基础
转:http://blog.csdn.net/wenwen360360/article/details/54969418 Application ―Java应用程序”是可以独立运行的Java程序.由J ...
- 学习随笔-Java WebService
webService 可以将应用程序转换成网络应用程序.是简单的可共同操作的消息收发框架. 基本的webService平台是 XML 和 HTTP. HTTP 是最常用的互联网协议: XML 是 we ...
- Java Gradle入门指南之依赖管理(添加依赖、仓库、版本冲突)
开发任何软件,如何管理依赖是一道绕不过去的坎,软件开发过程中,我们往往会使用这样那样的第三方库,这个时候,一个好的依赖管理就显得尤为重要了.作为一个自动构建工作,Gradle对依赖管理有着很好 ...
- Java泛型深入理解
泛型的优点: 泛型的主要优点就是让编译器保留參数的类型信息,执行类型检查,执行类型转换(casting)操作,编译器保证了这些类型转换(casting)的绝对无误. /******* 不使用泛型类型 ...
随机推荐
- dom编程艺术笔记1--第二章
第二章语法部分: 1.js注释:<!-- XXXXX 而“-->”这部分js会认为是注释内容的一部分 2.var 声明变量 不用声明变量类型 3.声明使用一个数组语法:var object ...
- Tensorflow实战系列之二:
还没想好,可能是人脸检测或者物体检测,或者加上动态检测~~
- effective_java 第34条:用接口模拟可伸缩的枚举
例如: /** * 加减乘除枚举 * Created by yulinfeng on 8/20/17. */ public enum Operation { PLUS { double apply(d ...
- python 面试题之 生成器
如下函数执行结果是什么? 答案: [20, 21, 22, 23] 核心要点:本题重点在对生成器的理解, 生成器具有惰性机制 ,只有在取值的时候才执行. 解析: for 循环遍历列表,执行了两次 第 ...
- dubbo的常用配置(基于注解)
之前记录了基于springboot的dubbo入门案例,今天在此基础上记录dubbo官网介绍的常用属性配置,dubbo读取我们配置的属性时是有优先级的,优先级如下图: 如图所示,优先级的属性依次为虚拟 ...
- nginx 学习(一)
今天不会nginx被怼了一顿.我必然不能忍,所以就赶忙来补充一下nginx知识!! nginx简介 nginx是一款高性能的http服务器,目前国内包括BAT在内的众多互联网企业均采用其作为反向代理服 ...
- QT_REQUIER_CONFIG
在qglobal.h中,定义了很多宏.下面这个QT_REQUIER_CONFIG,展开成: #define QT_REQUIRE_CONFIG(feature) Q_STATIC_ASSERT_X(Q ...
- 最近学习的 Node.js 之 http
利用 http 模块开始写简单的web服务. 模块: const http=require('http'); const fs=require('fs'); const path=require('p ...
- ajax如何渲染数据
染数据的方法 1).字符串拼接, 最常用的方法 优点:只进行一次dom回流 缺点:原有dom的事件都会丢失 原因:就在于innerHTML这个属性,这个属性是返回或设置dom中的内容,以字符串形式返 ...
- XShell转发数据库端口
隧道添加 源主机为本地 目标主机为需要转发的主机