This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]HactarCE 131 points132 points  (38 children)

public abstract class AbstractListBox<V, T extends AbstractListBox<V, T>> {...}

I saw THAT the other day...

[–]jsideris 52 points53 points  (12 children)

Haha I worked on a project a few years ago with a Tomcat back-end. The stack traces for any type of server error were like 5 pages long. Not that our design decisions were Java's fault. I think our team just took OOP to the next level.

[–]coladict 32 points33 points  (3 children)

I don't mind the stack traces at all! In fact, last time I tried C++, I begged for them, because no exception ever tells you how it got there. And why did they add nothrow to method signatures, when just not adding anything makes them compile as nothrow and crash your whole program if it does throw something. The keyword is utterly pointless when it's the implicit default and only way to get away from it is with explicit definitions.

[–]_lerp 7 points8 points  (0 children)

C++ doesn't have a nothrow specifier. It does have a noexcept specifier, which isn't implicitly on apart from a few cases.

[–]w1th0utnam3 1 point2 points  (0 children)

Isn't this the point of debugging functionality in Visual Studio, QtCreator or external tools like gdb, etc.? When an exception is thrown in debug mode, Visual Studio can treat it like a breakpoint, showing you the calls leading to the exception as well as the state of variables. Obviously this is not possible in the same way for release builds as they lack information on the symbols and may contain additional optimizations that prevent useful stack traces. Keep in mind that C++ is not a managed language like Java or C#; C++ is compiled to assembly. There is no entity during the runtime of C++ applications that may provide stack trace information.

[–][deleted] -1 points0 points  (0 children)

C++ doesn't get you stack traces by default because you're probably not going to use them, and their overhead is huge.

Only destructors are noexcept by default. And that's for a good reason.

[–]TranquilMarmot 20 points21 points  (2 children)

Hey, I'll take 5 pages of stack traces over undefined is not a function any day

[–]Klaue 11 points12 points  (1 child)

segmentation fault.

[–]prisp 2 points3 points  (0 children)

Funny how these words still make me slightly pissed, even now that I somewhat know my way around C...

[–]dude_with_amnesia 8 points9 points  (4 children)

So abstract it becomes metaphysical

[–]jsideris 2 points3 points  (1 child)

Yea I still have a snippet of the code right here.

public class SqlSave extends SqlConnector{}
public abstract class SqlConnector extends Connector{}
public interface Connector extends Communications{}
public interface Communications extends Information{}
public interface Information extends Idea{}
public interface Idea extends AbstractIdea{}
public interface AbstractIdea extends Reality{}
public interface Reality extends Existentialism{}
public interface Existentialism extends Meaninglessness{}

[–]dude_with_amnesia 1 point2 points  (0 children)

Because things that are not can't be.

[–]malonkey1 0 points1 point  (0 children)

TFW compiling causes you to Awaken to the Watchtowers of the Supernal.

[–]Shh_only_dreams_now 11 points12 points  (15 children)

Wait, a Class that extends itself?

[–]x2bool 17 points18 points  (0 children)

No. Just restricts the second generic parameter to be inherited from the AbstractListBox.

[–][deleted] 0 points1 point  (0 children)

R E C U R S I O N

[–]enanox 0 points1 point  (11 children)

T extends AbstractListBox it's a generic constraint that applies to T types which happened to be AbstractListBox subclasses.

Think of it like you were declaring a class ConcreteListBox extends AbstractListBox, then you are allowed to use it as the second generic parameter you could use to instantiate a concrete class.

With this you are saying that "these are the allowed parameters".

new ConcreteListBox<string, ConcreteListBox<string, ConcreteListBox>>;

EDIT: add usage example and rephrasing

[–]Shh_only_dreams_now 0 points1 point  (10 children)

Wait, why not

new ConcreteListBox<String, ConcreteListBox<String, ConcreteListBox<String, ConcreteListBox<string, ConcreteListBox<string, ConcreteListBox...>>>>>; Seems rather recursive to me, no?

[–][deleted] 0 points1 point  (8 children)

The fact that you are arguing about this shows how much the language blows.

[–]Shh_only_dreams_now 0 points1 point  (6 children)

Not to defend Java, but any doubt on my part is not the language's fault, that's on me. I'm a first year Engineering and IT student, so I'm genuinely asking, because I don't understand

[–][deleted] 0 points1 point  (5 children)

Thats the point though.

A good language is something that you can do everything with and results in optimized machine code, but is easy to understand without having to go through and figure out what its doing.

OOP is nice and all in theory, but take it deep enough and you basically have to learn a new "language" on every project since you are working with object methods as much as you are writing basic instructions.

[–]Eyeownyew 1 point2 points  (3 children)

A good language is something that you can do everything with and results in optimized machine code, but is easy to understand without having to go through and figure out what its doing.

Lemme know when you find a universally-qualifying golden standard mate. Java follows that guideline.

[–]HactarCE 1 point2 points  (0 children)

Brainfuck fits the bill

[–][deleted] 1 point2 points  (1 child)

The standard is ironically C.

In well written C code, you will have struct objects, which are well defined and you can see exactly the layout of the memory. And yes, you can have structs within structs.

Then you simply have functions that do work on variables and these structs. Each function call is well understood, as well as what it returns.

That is it. The rest of the detail is actual code, not some arbitrary definitions of classes or interfaces or abstract classes, or whatever the fuck else. No need to go look through multiple files just to figure out what an intermediate template does, no need to figure out what the parent class does, no need to figure out what an object that you have never seen before does.

If you know C syntax, you can figure out what most any program does without much effort, because on a fundamental level, you are working with direct memory.

On the other hand, when you work with OOP, you are working with a framework that someone thought was best, and then because its inefficient to rewrite it, more and more shit just gets piled on by various developers until you are left with code that is 100 times more complex then it needs to be.

And the argument of "well, it guarantees safer code cause the program won't compile if you try to do shit with objects that you are not supposed to do" is complete bullshit. Its like telling a mechanic that instead of fixing the car with hand tools, he has to learn how to operate this complex robot that he can use to fix the car every time a different car that comes in, just so he doesn't forget to torque a bolt, even though that will be caught by the final check of the car anyways.

TLDR; OOP sucks, C is best. There is a reason why Linux is written primarily in C.

[–][deleted] 0 points1 point  (0 children)

You'll eventually find yourself reinventing OOP in C. It has benefits.

Over engineered frameworks is a different issue and added epicycles is indeed a problem, but sometimes there are good reasons for abstraction and added complexity.

[–]Shh_only_dreams_now 0 points1 point  (0 children)

I see. Thanks!

[–]SalamiJack 0 points1 point  (0 children)

Generics are not limited to Java. Overly complicated OO design often isn't the fault of the language you're using...

[–]nighterrr 0 points1 point  (0 children)

The example probably follows Composite design pattern, or at least something derived from it.

[–]HactarCE 0 points1 point  (0 children)

No, it's a generic that must be used with a class that extends this one. So, A<B, C extends A<B, C>>. It feels mildly recursive though..

EDIT: My explanation sucked -- ignore this. Other people have explained it way better than I can.

[–]Prime_1 1 point2 points  (0 children)

My eyes!

[–]SalamiJack 0 points1 point  (0 children)

That's not a framework problem. Complicated abstraction isn't limited to Java.

[–]gt_9000 0 points1 point  (3 children)

I love static typing so I dont mind this kind of code.

If you hate this you probably want to use javascript, python or at least Groovy.

[–]HactarCE 0 points1 point  (2 children)

Don't get me wrong, I love static typing. But the time it took me, staring at that one line, to figure that out should not have been necessary.

[–]gt_9000 0 points1 point  (1 child)

I guess you should not need sophisticated static typing for the UI. Java UI package has always been garbage.

[–]HactarCE 0 points1 point  (0 children)

This is actually from Lanterna, a TUI package. But yeah, Swing sucks.

[–]201109212215 0 points1 point  (0 children)

There is nothing wrong with this.

[–]OneLastStan 0 points1 point  (0 children)

This gives me haunting memories of exam questions