powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / instanceof есть сомнения
22 сообщений из 22, страница 1 из 1
instanceof есть сомнения
    #38245987
medvedko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть супер-пупер проект, но в нем вижу больше тысячи instanceof и полторы тысячи проверок на null.
Вопрос: можно ли уже по этим признакам перестать считать проект суперским? Или я ошибаюсь?
...
Рейтинг: 0 / 0
instanceof есть сомнения
    #38246005
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
instanceof скорее всего свидетльствует о кривом дизайне. Потому что он появляется там где нужно было использовать полиморфизм. А уж если это массовый подход в десятках класса, то архитектуры у кода нет совсем.
вездесущие проверки на null - палка о двух концах. С одной стороны, да. Это тоже признак не самого лучшего кода. С другой стороны, не так много есть действительно работающих альтернатив.
...
Рейтинг: 0 / 0
instanceof есть сомнения
    #38246014
medvedko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Первая моя мысль была тоже о кривой архитектуре, но какая-то нерешительная мысль, не люблю критиковать и обижать людей, всегда присутствует сомнение: может я просто не понимаю гениальной задумки архитектора? Вот и ищу подтверждения незаинтересованной публики с некоторым опытом разработки. Спасибо.
...
Рейтинг: 0 / 0
instanceof есть сомнения
    #38246085
just_vladimir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Массовые instanceof не встречал, а вот проверки на null в последнее время сам стараюсь расставлять везде, где есть хоть малейшие сомнения. А то смотришь логи продакшен сервака, а там неведомые NPE, которые непонятно откуда берутся, так что лучше явная проверка на null и выкидываем адекватное исключение, чтобы потом можно было размотать, откуда эти null'овые объекты берутся.
...
Рейтинг: 0 / 0
instanceof есть сомнения
    #38246106
Leonidv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowiczinstanceof скорее всего свидетльствует о кривом дизайне. Потому что он появляется там где нужно было использовать полиморфизм.
Я знаю два исключения:
1. Проект является фрейморком, в котором очень много завязано на рефлексию (правда, не уверен насчет именно instanceof);
2. Реализация паттерна visitor удобно делается через instanceof.
...
Рейтинг: 0 / 0
instanceof есть сомнения
    #38246112
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonidv1. Проект является фрейморком, в котором очень много завязано на рефлексию (правда, не уверен насчет именно instanceof);
Это единичные случаи. Топикастер говорит о массовом использовании.

Leonidv2. Реализация паттерна visitor удобно делается через instanceof.
Покажи.
...
Рейтинг: 0 / 0
instanceof есть сомнения
    #38246226
Leonidv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Идея такая:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
public void visit(Visitor visitor) {
  for (Node n : nodes) {
   if (n instanceof NodeTypeA) {
       visitor.onNodeTypeA((NodeTypeA)n);
   } else if (n instanceof NodeTypeB) {
       visitor.onNodeTypeB((NodeTypeB)n);
   }
 }
}


Насколько я понимаю, чистое ООП решение заключается в том, что каждый имет метод getType.

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
public void visit(Visitor visitor) {
  for (Node n : nodes) {
   switch(n.getType() {
   case NODE_TYPE_A:
       visitor.onNodeTypeA((NodeTypeA)n);
       break;
   case NODE_TYPE_B:
       visitor.onNodeTypeB((NodeTypeB)n);
       break;
 }
}
...
Рейтинг: 0 / 0
instanceof есть сомнения
    #38246233
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Недоперепроектировали
LeonidvИдея такая:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
public void visit(Visitor visitor) {
  for (Node n : nodesA) {
       visitor.onNodeTypeA((NodeTypeA)n);
   }
   for (Node n : nodesB) {
       visitor.onNodeTypeB((NodeTypeB)n);
   }
 }
...
Рейтинг: 0 / 0
instanceof есть сомнения
    #38246420
mad_nazgul
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LeonidvИдея такая:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
public void visit(Visitor visitor) {
  for (Node n : nodes) {
   if (n instanceof NodeTypeA) {
       visitor.onNodeTypeA((NodeTypeA)n);
   } else if (n instanceof NodeTypeB) {
       visitor.onNodeTypeB((NodeTypeB)n);
   }
 }
}


Насколько я понимаю, чистое ООП решение заключается в том, что каждый имет метод getType.

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
public void visit(Visitor visitor) {
  for (Node n : nodes) {
   switch(n.getType() {
   case NODE_TYPE_A:
       visitor.onNodeTypeA((NodeTypeA)n);
       break;
   case NODE_TYPE_B:
       visitor.onNodeTypeB((NodeTypeB)n);
       break;
 }
}



Чистое ООП решение:

Код: java
1.
2.
3.
4.
5.
public void visit(Visitor visitor) {
  for (Node n : nodes) {
       visitor.onNodeType(n);
  }
}



А какой там Тип у ноды должно быть пофиг.
Полиморфизм рулит и педалит.

<:o)
...
Рейтинг: 0 / 0
instanceof есть сомнения
    #38246435
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
либо же, там высокооптимизированный код. способ с istanceof работает раз в 10 быстрей полиморфизма.
...
Рейтинг: 0 / 0
instanceof есть сомнения
    #38246445
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chabapokлибо же, там высокооптимизированный код. способ с istanceof работает раз в 10 быстрей полиморфизма.
Вместо с даункастингом? Что-то не верится
...
Рейтинг: 0 / 0
instanceof есть сомнения
    #38246864
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowiczchabapokлибо же, там высокооптимизированный код. способ с istanceof работает раз в 10 быстрей полиморфизма.
Вместо с даункастингом? Что-то не верится

сам был удивлен. Сейчас наверное вы попросите предоставить код, которым оно тестилось. Этот код утерян, т.к. тестил давно, но вот набросал на скору руку аналог. Полиморфизм получается вдвое дольше.

При этом если прибить класс С, то полиморфизм будет сравним по времени с instanceof, т.к. jvm умеет делать какую-то хитрую оптимизацию когда только 2 подкласса.

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
package javaapplication7;

public class InstanceOf {
 
	private static final int REPS = 1000000000;

 
	public static void main(String[] args) {
		for (int i = 0; i < 10; i++) {
			System.out.println("\nRep " + i);
				testInstanceOf();
				testIsClass();
				testOO();
				testId();
		}
	}
 
    
    
    static int i;
    
    static A a = new A();
    static B b = new B();
    static C c = new C();
    
    static Base[] x = {a,b,c};
    static Base calcNextObj(){
        i++;
        if (i<0){i=0;}
        return x[i%3];
    }
    
    
	private static void testInstanceOf() {
		long start = System.currentTimeMillis();
        a.sum = 0;
        b.sum = 0;
        c.sum = 0;
		for (int i = 0; i < REPS; i++) {
            
            Base base = calcNextObj();
			if (base instanceof A) {
				((A) base).doA();
			} else if (base instanceof B) {
				((B) base).doB();
			} else if (base instanceof C) {
				((C) base).doC();
			} else {
                throw new RuntimeException("wrong class");
            }
		}
		long diff = System.currentTimeMillis() - start;
		System.out.println("InstanceOf " + diff + " " + a.sum+" "+b.sum+" "+c.sum);
	}
 
	private static void testOO() {
        a.sum = 0;
        b.sum = 0;
        c.sum = 0;
		long start = System.currentTimeMillis();
		for (int i = 0; i < REPS; i++) {
            Base base = calcNextObj();
			base.doSomthing();
		}
		long diff = System.currentTimeMillis() - start;
		System.out.println("OO " + diff + " " + a.sum+" "+b.sum+" "+c.sum);
	}
 
	private static void testId() {
        a.sum = 0;
        b.sum = 0;
        c.sum = 0;
		long start = System.currentTimeMillis();
		for (int i = 0; i < REPS; i++) {
            Base base = calcNextObj();
			switch (base.type) {
                case A.A_TYPE:
                    ((A) base).doA();
                    break;
                case B.B_TYPE:
                    ((B) base).doB();
                    break;
                case C.C_TYPE:
                    ((C) base).doC();
                    break;

                default:
                    throw new RuntimeException();
			}
		}
		long diff = System.currentTimeMillis() - start;
		System.out.println("Id " + diff + " " + a.sum+" "+b.sum+" "+c.sum);
	}
 
	private static void testIsClass() {
        a.sum = 0;
        b.sum = 0;
        c.sum = 0;
		long start = System.currentTimeMillis();
		for (int i = 0; i < REPS; i++) {
            Base base = calcNextObj();
			if (base.getClass() == A.class) {
				((A) base).doA();
			} else if (base.getClass() == B.class) {
				((B) base).doB();
			}else if (base.getClass() == C.class) {
				((C) base).doC();
			}
		}
		long diff = System.currentTimeMillis() - start;
		System.out.println("class== " + diff + " " + a.sum+" "+b.sum+" "+c.sum);
	}
 
}


    interface IdoSome{
        void doSomthing();
    }


	class Base  implements IdoSome{
        
		int sum;
		int type;
 
		public Base(int type) {
			this.type = type;
		}
 
        @Override
		public void doSomthing(){
            sum +=1;
        }
	}
 
	class A extends Base implements IdoSome{
        final static int A_TYPE=1;
		public A() {
			super(A_TYPE);
		}
 
		public void doA() {
			sum += 2;
		}
 
		@Override
		public void doSomthing() {
			sum += 2;
		}
	}
 
	class B extends Base implements IdoSome {
        final static int B_TYPE=2;
        
		public B() {
			super(B_TYPE);
		}
 
		public void doB() {
			sum -= 2;
		}
 
		@Override
		public void doSomthing() {
			sum -= 2;
		}
	}


	class C extends Base implements IdoSome {
        final static int C_TYPE=3;
        
		public C() {
			super(C_TYPE);
		}
 
		public void doC() {
			sum -= 2;
		}
 
		@Override
		public void doSomthing() {
			sum -= 2;
		}
	}



И это оно еще быстро работает. Когда я тестил, то у меня ооп получалось раз в 10 медленей (видимо старая jvm), но этот код утерян.
...
Рейтинг: 0 / 0
instanceof есть сомнения
    #38246869
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
кстати, jvm вполне может видеть (в том смысле, что я не вижу препятствий против такой оптимизации), что кастинг осуществляется внутри проверки instanceof и второй раз такую проверку не делать.
...
Рейтинг: 0 / 0
instanceof есть сомнения
    #38246972
mad_nazgul
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chabapokBlazkowiczпропущено...

Вместо с даункастингом? Что-то не верится

сам был удивлен. Сейчас наверное вы попросите предоставить код, которым оно тестилось. Этот код утерян, т.к. тестил давно, но вот набросал на скору руку аналог. Полиморфизм получается вдвое дольше.

При этом если прибить класс С, то полиморфизм будет сравним по времени с instanceof, т.к. jvm умеет делать какую-то хитрую оптимизацию когда только 2 подкласса.

И это оно еще быстро работает. Когда я тестил, то у меня ооп получалось раз в 10 медленей (видимо старая jvm), но этот код утерян.

Вопрос конечно философский, что важнее время исполнения программы или скорость модификации программы :-)
Лично я бы, вместо оптимизации выбрал бы упрощение кода.
Просто когда вдруг понадобиться добавить классы D, E, F и пр.
Причем программистами которые не с самого начала проекта (будем считать что прошло 1-2 поколения программиста), то поиск что-то вроде testInstanceOf(), testID() и testIsClass() может вылиться в увлекательное приключение как минимум на неделю.
...
Рейтинг: 0 / 0
instanceof есть сомнения
    #38246991
пролетевший
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
visitor не требует instanceof или каких либо проверок типа. Все делает компилятор:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
for(Node n: nodes ) {
       node.visit(visitor);
}

class NodeA extends Node {
.............
@Override
public void visit(Visitor visitor) {
      visitor.onNodeA(this);
} 


В целом если куча instanceof, то или унаследованный с Java <1.5 код, без дженериков, или таки архитектура кривая.
Проверки на null хороши в assert на входе публичных методов, в остальных местах лучше пользоваться "специальными значениями". Например, для коллекции использовать пустую если нет результата.
...
Рейтинг: 0 / 0
instanceof есть сомнения
    #38247006
Leonidv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mad_nazgulЧистое ООП решение:
Код: java
1.
2.
3.
4.
5.
public void visit(Visitor visitor) {
  for (Node n : nodes) {
       visitor.onNodeType(n);
  }
}


А какой там Тип у ноды должно быть пофиг.
Полиморфизм рулит и педалит.
<:o)
В Java так нельзя.
...
Рейтинг: 0 / 0
instanceof есть сомнения
    #38247007
Leonidv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonНедоперепроектировали
LeonidvИдея такая:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
public void visit(Visitor visitor) {
  for (Node n : nodesA) {
       visitor.onNodeTypeA((NodeTypeA)n);
   }
   for (Node n : nodesB) {
       visitor.onNodeTypeB((NodeTypeB)n);
   }
 }



Это сработает только в том случае, если порядок следования элементов в структуре нам не нужен.
...
Рейтинг: 0 / 0
instanceof есть сомнения
    #38247010
Leonidv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
пролетевшийvisitor не требует instanceof или каких либо проверок типа. Все делает компилятор:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
for(Node n: nodes ) {
       node.visit(visitor);
}

class NodeA extends Node {
.............
@Override
public void visit(Visitor visitor) {
      visitor.onNodeA(this);
} 



Красивое решение, спасибо. Есть недостаток, что элемент начинает заниматься еще и логикой перехода, но он не значительный и перевешывает бонусы.
...
Рейтинг: 0 / 0
instanceof есть сомнения
    #38247035
mad_nazgul
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonidvmad_nazgulЧистое ООП решение:
Код: java
1.
2.
3.
4.
5.
public void visit(Visitor visitor) {
  for (Node n : nodes) {
       visitor.onNodeType(n);
  }
}


А какой там Тип у ноды должно быть пофиг.
Полиморфизм рулит и педалит.
<:o)
В Java так нельзя.

Странно почему?!
Во всех других ООП ЯП можно, а в Java нельзя. :-)
...
Рейтинг: 0 / 0
instanceof есть сомнения
    #38247062
scymaks
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mad_nazgul,

да, я тоже чего-то не понял. Чего там в Java нельзя? Итерировать?
...
Рейтинг: 0 / 0
instanceof есть сомнения
    #38247385
Leonidv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mad_nazgulВо всех других ООП ЯП можно, а в Java нельзя. :-)
Не во всех есть dynamic dispatch.
...
Рейтинг: 0 / 0
instanceof есть сомнения
    #38247508
mad_nazgul
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonidvmad_nazgulВо всех других ООП ЯП можно, а в Java нельзя. :-)
Не во всех есть dynamic dispatch.

Например?
Просто я не встречал таких ООП ЯП.
...
Рейтинг: 0 / 0
22 сообщений из 22, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / instanceof есть сомнения
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]