Why doesn't PHP allow class variables to be assigned as objects? - java

So I have the following question: Why doesn't PHP allow class variable to be instantiated as objects, this is probably the wrong question so I'll show some code to just clarify what I mean.
In java you can do this
private ServerSocket serverSocket;
But in PHP if you try to do something similar like the following
private $var = \MY_CLASS
It will throw a syntax error and you will have to instantiate it through the constructor.
I mean in java you also need to instantiate the variables through the constructor..

Most of the interpreters - including the PHP - is a language with a "free-typed data" (loose typed language):
Strong and weak typing
What is the difference between a strongly typed language and a statically typed language?
It's just one of the approaches to the practice of building language translators.
This does not mean that it is bad. It just means that when designing the architecture of your application, you are taking responsibility for control of the correctness of your data.
But how true it was already mentioned, you may use the annotation mechanism for describing what you want to do

Unfortunately you can only add a phpDoc comment for so that the IDE can help you but you can specify the type (class or array primitive) as arguments for a method
namespace Services;
use Services/SubNamespace/AnotherClass;
class Test
{
/**
* #var AnotherClass
*/
private $property;
public function __construct(AnotherClass $anotherClass){ ... }
public function addVars(array $array){ ... } //You must check your php version to make sure it supports array typehint
}

As an alternative, you could use type hinting comments for your IDE to pickup on, and is just general good practice I feel for PHP code. Here is an example:
<?php
class ExampleClass {
/** #var \MY_CLASS */
private $var;
public function __construct()
{
$this->var = new \MY_CLASS();
}
}
As a general rule for Object Orientation, you should favour dependency injection, rather than instantiating a new object in your class. Eg:
<?php
class ExampleClass {
/** #var \MY_CLASS */
private $var;
public function __construct(\MY_CLASS $var)
{
$this->var = $var;
}
}
$exampleVar = new \MY_CLASS();
$exampleClass = new ExampleClass($exampleVar);

Related

nameof equivalent in Java

C# 6.0 introduced the nameof() operator, that returns a string representing the name of any class / function / method / local-variable / property identifier put inside it.
If I have a class like this:
class MyClass
{
public SomeOtherClass MyProperty { get; set; }
public void MyMethod()
{
var aLocalVariable = 12;
}
}
I can use the operator like this:
// with class name:
var s = nameof(MyClass); // s == "MyClass"
// with properties:
var s = nameof(MyClass.OneProperty); // s == "OneProperty"
// with methods:
var s = nameof(MyClass.MyMethod); // s == "MyMethod"
// with local variables:
var s = nameof(aLocalVariable); // s == "aLocalVariable".
This is useful since the correct string is checked at compile time. If I misspell the name of some property/method/variable, the compiler returns an error. Also, if I refactor, all the strings are automatically updated. See for example this documentation for real use cases.
Is there any equivalent of that operator in Java? Otherwise, how can I achieve the same result (or similar)?
It can be done using runtime byte code instrumentation, for instance using Byte Buddy library.
See this library: https://github.com/strangeway-org/nameof
The approach is described here: http://in.relation.to/2016/04/14/emulating-property-literals-with-java-8-method-references/
Usage example:
public class NameOfTest {
#Test
public void direct() {
assertEquals("name", $$(Person.class, Person::getName));
}
#Test
public void properties() {
assertEquals("summary", Person.$(Person::getSummary));
}
}
Sadly, there is nothing like this. I had been looking for this functionality a while back and the answer seemed to be that generally speaking, this stuff does not exist.
See Get name of a field
You could, of course, annotate your field with a "Named" annotation to essentially accomplish this goal for your own classes. There's a large variety of frameworks that depend upon similar concepts, actually. Even so, this isn't automatic.
You can't.
You can get a Method or Field using reflection, but you'd have to hardcode the method name as a String, which eliminates the whole purpose.
The concept of properties is not built into java like it is in C#. Getters and setters are just regular methods. You cannot even reference a method as easily as you do in your question. You could try around with reflection to get a handle to a getter method and then cut off the get to get the name of the "property" it resembles, but that's ugly and not the same.
As for local variables, it's not possible at all.
You can't.
If you compile with debug symbols then the .class file will contain a table of variable names (which is how debuggers map variables back to your source code), but there's no guarantee this will be there and it's not exposed in the runtime.
I was also annoyed that there is nothing comparable in Java, so I implemented it myself: https://github.com/mobiuscode-de/nameof
You can simply use it like this:
Name.of(MyClass.class, MyClass::getProperty)
which would just return the String
"property"
It's also on , so you can add it to your project like this:
<dependency>
<groupId>de.mobiuscode.nameof</groupId>
<artifactId>nameof</artifactId>
<version>1.0</version>
</dependency>
or for Gradle:
implementation 'de.mobiuscode.nameof:nameof:1.0'
I realize that it is quite similar to the library from strangeway, but I thought it might be better not to introduce the strange $/$$ notation and enhanced byte code engineering. My library just uses a proxy class on which the getter is called on to determine the name of the passed method. This allows to simply extract the property name.
I also created a blog post about the library with more details.
Lombok has an experimental feature #FieldNameConstants
After adding annotation you get inner type Fields with field names.
#FieldNameConstants
class MyClass {
String myProperty;
}
...
String s = MyClass.Fields.myProperty; // s == "myProperty"

How to avoid argument-order dependencies in statically typed languages like Java or C#

I'm from Python, Ruby and PHP world and one of techniques that I try to follow is removing argument-order dependencies from my code. This is a short demonstration of this technique implemented in Ruby:
class Gear
attr_reader :chainring, :cog, :wheel
def initialize(args)
#chainring = args[:chainring]
#cog = args[:cog]
#wheel = args[:wheel]
end
...
end
Gear.new(
:chainring => 52,
:cog => 11,
:wheel => Wheel.new(26, 1.5)).gear_inches
As you can see the client code does not need to know the order of arguments for initializing a Gear instance and I like that. But now I just wonder how the same thing is implemented in statically typed languages like Java and I also wonder whether people try to follow such techniques or not in this kind of languages. If someone can share their experience and show some demo-code (let it be in Java, C# etc.), that would be great.
You don't have to adhere to an argument order in C#. If you know the parameter name you can take advantage of named and optional arguments by using the parameter name, a colon and your value.
static void Main(string[] args)
{
var variable1 = "1";
var variable2= 90056;
var variable3 = 'u';
// random order
TestMethod(arg3: variable3, arg1: variable1, arg2: variable2);
// you can even omit some argument
TestMethod(arg2: variable2);
}
private static void TestMethod(string arg1 = null, int arg2 = 0, char arg3 = '\0')
{
Console.WriteLine(arg1);
Console.WriteLine(arg2);
Console.WriteLine(arg3);
Console.ReadKey();
}
I believe that Xiaoy312's answer is what you're looking for, but I'll leave this here just in case someone is curious about it later.
If it is only for creating new object, you can use Object Initializer :
public class Gear
{
public int Chainring { get; set; }
public int Cog { get; set; }
public int Wheel { get; set; }
}
// ...
var gear = new Gear
{
// could be in any order,
Cog = 11,
Chainring = 52,
}
As for method arguments, check out KSid's answer on Named and Optional Arguments.
Try Lombok.
In Java, argument order in methods is very much mandatory unless you are talking about command line applications and for that I would suggest using Apache CLI. If you are talking about constructors, then Lombok is a good library for you. It implements a builder pattern and you can then create your instances based on any number of private variables you have declared and on any order you desire.
Say you have:
#Builder
public class MySuperClasse {
private int mySuperInt;
private String mySuperString;
private Date mySuperDate;
}
You can then build your instances like this:
MySuperClass super = MySuperClass.builder().mySuperString(string).mySuperInt(int).mySuperDate(date).build();
or you can do
MySuperClass super = MySupeClass.builder().mySuperDate(date).build();
Essentially what is happening is that when you annotate your class with #Builder, Lombok implicitly creates the builder and the different methods to create your instance. The beauty of it is that it does exactly what you want, however in a slighty different way.
That's a language feature that's present in some, but not all statically-typed languages. The feature is not present in Java, but it's present in Scala and it's present in C# (see KSib's answer).
Regarding your technique, there are a couple benefits.
Your code works even when argument order is changed
Improved compiler safety by being explicit about your parameters (e.g. compiler error if argument doesn't exist)
Improved readability where there are multiple overloads for a method
Improved readability/maintainability where there are multiple arguments of the same type
The downsides are
You're coupled to argument names
Argument names are more likely to change across minor revisions, but argument order is not supposed to change across minor revisions
More verbose code

How do I use a Java-defined instance method in Lua?

I'm aware that it is possible to use Java defined static methods in Lua, due to the section "Libraries of Java Functions" on http://luaj.org/luaj/README.html.
However I am struggling to find out how I can use the same for instance methods, I have a shortened example here:
private static class CallbackStore {
public void test(final String test) {
}
}
(I am aware that I can use a static method here as well, but it is not possible with the real life scenario)
I am using the following Lua code:
-- Always name this function "initCallbacks"
function initCallbacks(callbackStore)
callbackStore.test("test")
end
Which does not work as it is expecting userdata back, but I give it a string.
And I call the Lua code like this:
globals.load(new StringReader(codeTextArea.getText()), "interopTest").call();
CallbackStore callbackStore = new CallbackStore();
LuaValue initCallbacks = globals.get("initCallbacks");
initCallbacks.invoke(CoerceJavaToLua.coerce(callbackStore));
where the Lua code is returned by codeTextArea.getText()
Bottom line of my question is, how do I make my code running with test as an instance method?
When accessing member functions (in Lua objects in general, not just luaj) you have to provide the this argument manually as the first argument like so:
callbackStore.test(callbackStore,"test")
Or, you can use the shorthand notation for the same thing:
callbackStore:test("test")

Is this a good practice to use the "default" Java access to hide classes and methods from client

In the case of classes:
If we use the factory method we'll have to return created implementation as the type of an implemented interface.
public class Factory {
public Product getProduct() {
return new ProductA();
}
}
public interface Product {
}
class ProductA implements Product {
}
To avoid client's ability to cast returned Product to concrete implementation of the Product{A, B, C... etc.} we have to:
package client's and factory's code separately (let's say com.example.client and com.example.factory)
declare concrete implemantations with the default ("package") access (visible to Factory, not visible to Client)
package com.example.client;
...
public class Client {
public static void main(String[] args) {
Product i = new Factory().getProduct();
ProductA a = (ProductA) i; // the type of ProductA isn't visible.
}
}
In the case of methods:
For example we need to use the same factory with the hidden method
public class Factory {
public Product getProduct() {
return new ProductA();
}
Product[] getCreatedProducts() {
...
}
}
I see two problems here:
bad package structure: hidden classes and methods must be in one package with the calling code.
bad code: less intuitive and understandable. It's easy to break with the replacement of java files to another package.
The "default" access does not guarantee much of anything, since any rogue programmer can declare their class in your package. Also, regardless of your package structure, in java, you almost always can do an "instance of" check, and then downcast to the "instance of" type. So, if your goal is to prevent any downcasting whatsoever, you must use the private keyword. For example, you can declare the concrete implementations of your Product interface as private static or as anonymous inner classes within your Factory. Indeed, in Bloch's "How to design a good API" article, he makes a point that you should "Minimize Accessibility of Everything."
That said, I think you're being a little paranoid here. Does it really matter that much to you if somebody downcasts? Any code that you write can be misused, and certainly if you include a well-documented factory then you have provided clear information about how to use your API properly. Also, if you build a real factory method that takes arguments and has clear method names, as opposed to this toy Factory example that takes no arguments, then I think you'll find that you're broadcasting the publicly relevant part of what's being created anyway.
I do not really understand why do you want to put factory and classes to separate packages.
I usually create public interface, public factory class and package protected implementations in the same package. So client can create instances using factory only and cannot down cast because the concrete classes are not visible from other package.
In your case here, you have the client knows the factory which knows the implementation class. If they are all in the same process, then both the client and the implementation class are loaded into the same process, which means that the client can have access to the underlying methods of the implementation class via reflection. This assumes that you do not have complete control over the client runtime, i.e. taking measures to prevent reflection. However, if you did, then you probably wouldn't need to worry about the inability of the client to cast to the implementation class.
So, if you view this as a potential security mechanism against an untrusted client process, then I wouldn't put any faith in it. If you have control over the client, then this is probably good enough to keep errant programmers from making an unintentional mess.
I do not see the advantage of two packages. I suggest this alternative:
package com.example.client ;
public interface Product
{
/* stuff */
}
package com.example.client ;
public interface ProductFactory
{
Product make ( X1 x1 , X2 x2 , /* parameters */ , Xn xn ) ;
}
package com.example.manager;
interface ManagedProduct extends com.example.client.Product
{
/* management methods */
}
package com.example.manager ;
public final class DefaultProductFactory implements com.example.client.ProductFactory
{
public static final DefaultProductFactory instance = new DefaultProductFactory ( ) ;
private DefaultProductFactory ( )
{
super ( ) ;
}
public ManagedProduct make ( final X1 x1 , final X2 x2 , /* parameters */ , final Xn xn )
{
return new ManagedProduct ( )
{
/* implementation logic here */
} ;
}
/*
possibly other methods
The Product implementation class is invisible.
*/
}
Using two packages unnecessarily exposes the implementation Product class to the com.example.manager.DefaultProductFactory class. I would argue that my approach is superior to Bringer128's private inner class Factory. With my approach, the implementation Product class is even invisible to other methods that may exist in the implementation Factory class.
If you make the parameters final, then you can use them in the implementation Product class directly from the method arguments (no need to (1) create X1 x1, X2 x2, ..., Xn xn members; (2) this.x1=x1, this.x2=x2, ..., and this.xn=xn in the constructor; and (3) invoke the constructor with ProductImpl (x1,x2,...,xn). This is admittedly small but it saves you keystrokes.
I strongly agree with philwb. This should not be regarded as security.
This allows classes in com.example.manager to have more methods on the same object than classes in other packages - as requested in Is this a good practice to use the "default" Java access to hide classes and methods from client.

final static String defined in an interface not evaluated at compile time - Android

I have two classes and an interface (for example DatabaseModel, LocalStore, and InternalModelInterface). They're defined as follows;
public class DatabaseModel {
// ...
public static final String KEY_PARAM1 = "param1";
}
public class LocalStore implements InternalModelInterface {
// ...
public void function () {
String temp = InternalModelInterface.COLUMN_PARAM1;
}
}
public interface InternalModelInterface {
public static final String COLUMN_PARAM1 = DatabaseModel.KEY_PARAM1;
// ...
}
The issue I'm experiencing is that at runtime, when I call localStore.function(), temp is being assigned null, as InternalModelInterface.COLUMN_PARAM1 is null. Does this make sense? Shouldn't InternalModelInterface.COLUMN_PARAM1 be evaluated at compile time and inlined?
This is for an Android application. Thanks in advance.
I'll further explain to clarify any confusion.
Objects of the DatabaseModel class are instantiated as a JSON response is parsed. The constants defined in the DatabaseModel class represent the keys to look for in the JSON response.
The InternalModelInterface defines the column names used in the local (cache) database on the device. For several reasons (including they keys being illegal column names in SQLite), I'm not reusing the keys as column names.
The reason I'm using an interface and not just a plain class is that the interface also specifies required methods that need to be implemented by the third class, LocalStore.
JLS3 §8.3.2.1, §9.3.1 http://java.sun.com/docs/books/jls/third_edition/html/classes.html#38010
at run time, static variables that are
final and that are initialized with
compile-time constant values are
initialized first. This also applies
to such fields in interfaces (§9.3.1).
These variables are "constants" that
will never be observed to have their
default initial values (§4.12.5), even
by devious programs.
So null should never be observed in your example. It's an Android bug then.
I'm not and android expert but I think that if you don't create an instance of the class, it's optimised out at compile time. If you create a constructor for DatabaseModel and instantiate it somewhere it seems to solve this for me.

Categories

Resources